第四部分數據庫服務
第三十章 MySQL基礎
一、MySQL單實例源碼cmake方式編譯安裝
1、安裝cmake軟件
(1)解壓cmake
tar zxf cmake-2.8.8.tar.gz
cd cmake-2.8.8
(2)configure
./configure
(3)gmake
gmake
(4)gmake install
gmake install
cd ..
2、確認依賴包是否安裝
rpm -qa | grep ncurses
ncurses-5.7-4.20090207.el6.x86_64
ncurses-base-5.7-4.20090207.el6.x86_64
ncurses-term-5.7-4.20090207.el6.x86_64
ncurses-libs-5.7-4.20090207.el6.x86_64
ncurses-devel-5.7-4.20090207.el6.x86_64
如沒有安裝,則安裝之
yum install ncurses-devel -y
3、安裝MySQL
(1)解壓MySQL
tar xf mysql-5.5.32.tar.gz
cd mysql-5.5.32
(2)創建mysql用戶和組
useradd mysql -s /sbin/nologin -M
id mysql
(3)configure
a、不指定字符集,使用默認拉丁字符集
cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.5.32 \
-DMYSQL_DATADIR=/application/mysql-5.5.32/data \
-DMYSQL_UNIX_ADDR=/application/mysql-5.5.32/tmp/mysql.sock \
-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \
-DENABLED_LOCAL_INFILE=ON \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \
-DWITHOUT_PARTITION_STORAGE_ENGINE=1 \
-DWITH_FAST_MUTEXES=1 \
-DWITH_ZLIB=bundled \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_READLINE=1 \
-DWITH_EMBEDDED_SERVER=1 \
-DWITH_DEBUG=0
b、指定字符集爲utf8
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
(4)make && make install
make && make install
(5)創建MySQL軟連接
ln -s /application/mysql-5.5.32/ /application/mysql
(6)配置環境變量
echo 'export PATH=/application/mysql/bin/:$PATH' >>/etc/profile
(7)檢查環境變量
a、查看profile
tail -1 /etc/profile
export PATH=/application/mysql/bin/:$PATH
b、讓 配置生效
source /etc/profile
c、查看PATH
echo $PATH
/application/mysql/bin/:/application/nginx/sbin:/application/nginx/sbin:/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
(8)檢查數據目錄是否創建
ll -d /application/mysql/data/
drwxr-xr-x 3 root root 4096 Mar 26 22:10 /application/mysql/data/
(9)授權mysql用戶訪問數據目錄
chown -R mysql.mysql /application/mysql/data/
(10)調整/tmp目錄權限(否則初始化會報錯)
chmod 1777 /tmp/
(11)創建MySQL配置文件:my.conf
cp mysql-5.5.32/support-files/my-small.cnf /etc/my.cnf
(12)初始化MySQL
cd /application/mysql/scripts/
./mysql_install_db --user=mysql --basedir=/application/mysql/--datadir=/application/mysql/data/
(13)創建MySQL啓動腳本
cp/application/mysql/support-files/mysql.server /etc/init.d/mysqld
(14)增加MySQL啓動腳本的可執行權限
chmod +x /etc/init.d/mysqld
(15)啓動MySQL
/etc/init.d/mysqld start
(16)爲root用戶指定密碼
/application/mysql/bin/mysqladmin -u rootpassword '123456'
(17)登陸MySQL
mysql -uroot -p
(18)刪除無用的數據庫和用戶
delete from mysql.user where host='::1'or user='';
drop database test;
(19)額外添加管理員
grant all privileges on *.* tosystem@'localhost' identified by '123456' with grant option
(20)配置MySQL啓動級別
chkconfig mysqld on
chkconfig --list mysqld
mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off
二、MySQL多實例概念
1、什麼是多實例
就是一臺服務器上開啓多個不同的服務端口,來運行多個MySQL服務里程,通過不用同socket 監聽不同的服務端口提供各自的服務。
這些MySQL多實例,共用一套MySQL安裝程序,使用不同(也可相同)的my.conf配置文件、啓動程序、數據文件。在提供服務時,多實例的MySQL在邏輯上看起來是各自獨立的,多個實例根據配置文件對應的設定值,獲取相應的服務器資源。
2、多實例的作用、問題和應用場景
(1)作用
a、有效利用服務器資源
b、節約服務器資源
c、節省IDC機櫃
(2)問題
a、資源互相搶佔
b、當某個服務實例併發很高或有慢查詢時導致其它實例性能下降
(3)應用場景
a、資金緊張的公司
b、併發訪問不是特別大的業務
c、門戶網站應用較多
百度搜索引擎的數據庫是多實例,一般是從庫(48核,96G,3-4個實例)
sina網也是多實例(內存48G)
3、MySQL多實常見配置方案
(1)多配置文件及多個啓動程序(推薦方法)
tree data
/data
├── 3306
│ ├── data #3306實例的數據文件
│ ├── my.cnf #3306實例的配置文件
│ └── mysql #3306實例的啓動文件
└── 3307
├── data
├── my.cnf
└── mysql
(2)單一配置文件部署方案
a、my.cnf配置文件樣例(mysql手冊中提到的方法)
[mysqld_multi]
mysqld = /usr/bin/mysqld_safe
mysqladmin = /usr/bin/mysqladmin
user = mysql
[mysqld1]
socket =/var/lib/mysql/mysql.sock
port =3306
pid-file = /var/lib/mysql/mysql.pid
datadir =/var/lib/mysql/
user =mysql
[mysqld2]
socket =/mnt/data/db2/mysql.sock
port =3303
pid-file = /mnt/data/db2/mysql.pid
datadir =/mnt/data/db2/
user =mysql
skip-name-resolve
server-id = 11
master-connect-retry = 60
default-storage-engine = innodb
innodb_buffer_pool_size = 512M
innodb_additional_mem_pool = 10M
default_character_set = utf8
character_set_server = utf8
#read-only
relay-log-space-limit =3G
expire_logs_day =20
[mysqld3]
socket =/mnt/data/db1/mysql.sock
port =3302
pid-file = /mnt/data/db1/mysql.pid
datadir =/mnt/data/db1/
user =mysql
skip-name-resolve
server-id = 10
default-storage-engine = innodb
innodb_buffer_pool_size = 512M
innodb_additional_mem_pool = 10M
default_character_set = utf8
character_set_server = utf8
#read-only
relay-log-space-limit =3G
expire_logs_day =20
b、啓動方法
mysqld_multi--config-file=/data/mysql/my_multi.cnf start 1,2,3
c、停止方法
mysqld_multi stop 1,3
d、存在的問題
耦合性太強
三、MySQL多實例安裝:多配置文件、啓動程序方法
1、安裝依賴包
yum install ncurses-devel -y
yum install libaio-devel -y
2、cmake方式編譯安裝MySQL單實例源碼
整個安裝過程只到make install和建立軟鏈接就停止,後面的步驟不用操作,多實例方式需重新配置。
3、創建MySQL多實例的數據文件目錄
(1)關閉單實例MySQL的所有進程
pkill mysqld
ps -ef | grep mysql
(2)刪除MySQL啓動命令
rm -f /etc/init.d/mysqld
(3)創建多實例目錄
mkdir -p /data/{3306,3307}/data
4、創建多實例配置文件
(1)配置3306的配置文件
vi /data/3306/my.cnf
[client]
port = 3306
socket =/data/3306/mysql.sock
[mysql]
no-auto-rehash
[mysqld]
user = mysql
port = 3306
socket =/data/3306/mysql.sock
basedir = /application/mysql
datadir = /data/3306/data
open_files_limit = 1024
back_log = 600
max_connections = 800
max_connect_errors = 3000
table_cache = 614
external-locking = FALSE
max_allowed_packet =8M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 100
thread_concurrency = 2
query_cache_size = 2M
query_cache_limit = 1M
query_cache_min_res_unit = 2k
#default_table_type = InnoDB
thread_stack = 192K
#transaction_isolation = READ-COMMITTED
tmp_table_size = 2M
max_heap_table_size = 2M
long_query_time = 1
#log_long_format
#log-error = /data/3306/error.log
#log-slow-queries = /data/3306/slow.log
pid-file = /data/3306/mysql.pid
log-bin = /data/3306/mysql-bin
relay-log = /data/3306/relay-bin
relay-log-info-file = /data/3306/relay-log.info
binlog_cache_size = 1M
max_binlog_cache_size = 1M
max_binlog_size = 2M
expire_logs_days = 7
key_buffer_size = 16M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
bulk_insert_buffer_size = 1M
#myisam_sort_buffer_size = 1M
#myisam_max_sort_file_size = 10G
#myisam_max_extra_sort_file_size = 10G
#myisam_repair_threads = 1
#myisam_recover
lower_case_table_names = 1
skip-name-resolve
slave-skip-errors = 1032,1062
replicate-ignore-db=mysql
server-id = 1
innodb_additional_mem_pool_size = 4M
innodb_buffer_pool_size = 32M
innodb_data_file_path = ibdata1:128M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 4M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
max_allowed_packet = 2M
[mysqld_safe]
log-error=/data/3306/mysql_oldboy3306.err
pid-file=/data/3306/mysqld.pid
(2)配置3307的配置文件
vi /data/3307/my.cnf
[client]
port = 3307
socket =/data/3307/mysql.sock
[mysql]
no-auto-rehash
[mysqld]
user = mysql
port = 3307
socket =/data/3307/mysql.sock
basedir = /application/mysql
datadir = /data/3307/data
open_files_limit = 1024
back_log = 600
max_connections = 800
max_connect_errors = 3000
table_cache = 614
external-locking = FALSE
max_allowed_packet =8M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 100
thread_concurrency = 2
query_cache_size = 2M
query_cache_limit = 1M
query_cache_min_res_unit = 2k
#default_table_type = InnoDB
thread_stack = 192K
#transaction_isolation = READ-COMMITTED
tmp_table_size = 2M
max_heap_table_size = 2M
#long_query_time = 1
#log_long_format
#log-error = /data/3307/error.log
#log-slow-queries = /data/3307/slow.log
pid-file = /data/3307/mysql.pid
#log-bin = /data/3307/mysql-bin
relay-log = /data/3307/relay-bin
relay-log-info-file = /data/3307/relay-log.info
binlog_cache_size = 1M
max_binlog_cache_size = 1M
max_binlog_size = 2M
expire_logs_days = 7
key_buffer_size = 16M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
bulk_insert_buffer_size = 1M
#myisam_sort_buffer_size = 1M
#myisam_max_sort_file_size = 10G
#myisam_max_extra_sort_file_size = 10G
#myisam_repair_threads = 1
#myisam_recover
lower_case_table_names = 1
skip-name-resolve
slave-skip-errors = 1032,1062
replicate-ignore-db=mysql
server-id = 3
innodb_additional_mem_pool_size = 4M
innodb_buffer_pool_size = 32M
innodb_data_file_path = ibdata1:128M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 4M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
max_allowed_packet = 2M
[mysqld_safe]
log-error=/data/3307/mysql_oldboy3307.err
pid-file=/data/3307/mysqld.pid
5、創建多實例啓動文件
(1)多實例啓動/停止MySQL服務的實質
當啓動MySQL時,如果配置文件不在/etc下的話,在啓動時,必須通過--defaults-file參數來指定MySQL的配置文件my.cnf的路徑
啓動:
mysqld_safe--default-file=/data/3306/my.cnf 2>&1 >/dev/null &
mysqld_safe--default-file=/data/3307/my.cnf 2>&1 >/dev/null &
停止(平滑停止MySQL):
mysqladmin -uroot -p 123456 -S /data/3306/mysql.sock shutdown
mysqladmin -uroot -p 123456 -S /data/3307/mysql.sock shutdown
(2)配置3306的啓動文件
vi /data/3306/mysql
#!/bin/sh
#init
port=3306
mysql_user="root"
mysql_pwd="oldboy"
CmdPath="/application/mysql/bin"
mysql_sock="/data/${port}/mysql.sock"
#startup function
function_start_mysql()
{
if [ ! -e"$mysql_sock" ];then
printf "StartingMySQL...\n"
/bin/sh${CmdPath}/mysqld_safe --defaults-file=/data/${port}/my.cnf 2>&1 >/dev/null &
else
printf "MySQL isrunning...\n"
exit
fi
}
#stop function
function_stop_mysql()
{
if [ ! -e"$mysql_sock" ];then
printf "MySQL isstopped...\n"
exit
else
printf "StopingMySQL...\n"
${CmdPath}/mysqladmin-u ${mysql_user} -p${mysql_pwd} -S /data/${port}/mysql.sock shutdown
fi
}
#restart function
function_restart_mysql()
{
printf "RestartingMySQL...\n"
function_stop_mysql
sleep 2
function_start_mysql
}
case $1 in
start)
function_start_mysql
;;
stop)
function_stop_mysql
;;
restart)
function_restart_mysql
;;
*)
printf "Usage:/data/${port}/mysql {start|stop|restart}\n"
esac
(3)配置3307的啓動文件
vi /data/3307/mysql
#!/bin/sh
#init
port=3307
mysql_user="root"
mysql_pwd="oldboy"
CmdPath="/application/mysql/bin"
mysql_sock="/data/${port}/mysql.sock"
#startup function
function_start_mysql()
{
if [ ! -e"$mysql_sock" ];then
printf "StartingMySQL...\n"
/bin/sh${CmdPath}/mysqld_safe --defaults-file=/data/${port}/my.cnf 2>&1 >/dev/null &
else
printf "MySQL isrunning...\n"
exit
fi
}
#stop function
function_stop_mysql()
{
if [ ! -e "$mysql_sock"];then
printf "MySQL isstopped...\n"
exit
else
printf "StopingMySQL...\n"
${CmdPath}/mysqladmin-u ${mysql_user} -p${mysql_pwd} -S /data/${port}/mysql.sock shutdown
fi
}
#restart function
function_restart_mysql()
{
printf "RestartingMySQL...\n"
function_stop_mysql
sleep 2
function_start_mysql
}
case $1 in
start)
function_start_mysql
;;
stop)
function_stop_mysql
;;
restart)
function_restart_mysql
;;
*)
printf "Usage:/data/${port}/mysql {start|stop|restart}\n"
esac
6、授權mysql用戶管理/data目錄
chown -R mysql.mysql /data
7、給予mysql腳本執行權限
find /data -type f -name mysql | xargs chmod +x
8、配置環境變量
echo 'export PATH=/application/mysql/bin/:$PATH' >>/etc/profile
9、初始化多實例MySQL
(1)MySQL5.1.X
#命令在mysql/bin目錄下
mysql_install_db --basedir=/application/mysql--datadir=/data/3306/data --user=mysql
mysql_install_db --basedir=/application/mysql--datadir=/data/3307/data --user=mysql
(2)MySQL5.5.X
#命令在mysql/scripts目錄下
cd /application/mysql/scripts
./mysql_install_db--basedir=/application/mysql --datadir=/data/3306/data --user=mysql
./mysql_install_db--basedir=/application/mysql --datadir=/data/3307/data --user=mysql
(3)比較一下:單實例MySQL5.5.X
mysql_install_db --user=mysql
10、啓動多實例MySQL
/data/3306/mysql start
/data/3307/mysql start
11、查看是否啓動成功:檢查端口和進程
(1)檢查端口
netstat -lntup| grep 330[6-7]
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 14756/mysqld
tcp 0 00.0.0.0:3307 0.0.0.0:* LISTEN 24286/mysqld
(2)檢查進程
ps -ef | grep mysql
12、修改MySQL用戶密碼:必須指定sock
mysqladmin -u root -S /data/3306/mysql.sock password '123456'
mysqladmin -u root -S /data/3307/mysql.sock password '123456'
13、MySQL多實例數據庫安裝排錯方法
(1)如果沒有顯示MySQL的端口,要等幾秒再看,MySQL服務啓動相對於Web有些慢
(2)如果還不行,則要查看MySQL的錯誤日誌
grep log-error /data/3306/my.cnf
#log-error = /data/3306/error.log
log-error=/data/3306/mysql_oldboy3306.err
(3)細看所有執行命令返回的屏幕輸出,不要忽略關鍵的輸出內容
(4)查看系統的/var/message
(5)如果是關聯服務,要同時查看相關服務的LOG
14、登陸MySQL多實例數據庫
(1)MySQL多實例登陸必須通過-S參數指定sock(遠程是IP)才能登陸
mysql -S /data/3306/mysql.sock
create database d3306;
mysql -S /data/3307/mysql.sock
create database d3307;
(2)也可能在一個MySQL客戶端中利用system函數調用系統命令來進入另個實例
mysql -S /data/3306/mysql.sock
system mysql -S /data/3307/mysql.sock
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| d3307 |
| mysql |
| performance_schema |
| test |
15、關閉MySQL多實例數據庫
在關閉MySQL多實例數據庫時,是需要密碼的,所以在/data/{port}/mysql中是要寫入MySQL用戶密碼的。一定要與真實密碼相匹配,否則無法關閉數據庫。同時,由於密碼放在啓動腳本中,存在安全問題,所以要把啓動腳本文件的權限改爲700.
(1)指定啓動腳本中的密碼
grep mysql_pwd /data/3306/mysql
mysql_pwd="123456"
(2)停止數據庫
/data/3306/mysql stop
/data/3307/mysql stop
(3)修改啓動腳本的權限
find /data -type f -name mysql | xargs chmod 700
find /data -type f -name mysql | xargs chown root.root
或
find /data -type f -name mysql -exec chmod 700 {} \;
find /data -type f -name mysql -exec chown root.root {} \;
(4)查看改變後的啓動腳本權限
find /data -type f -name mysql -exec ls -l {} \;
-rwx------ 1 root root 1307 Mar 28 13:36 /data/3306/mysql
-rwx------ 1 root root 1307 Mar 28 13:36 /data/3307/mysql
16、重啓MySQL多實例數據庫
(1)先關閉數據庫
/data/3306/mysql stop
/data/3307/mysql stop
(2)再啓動數據庫
/data/3306/mysql start
/data/3307/mysql start
17、遠程登陸MySQL多實例數據庫
本地連接MySQL數據庫,需要指定sock文件,遠程連接時,只需指定IP和端口
mysql -uroot -p123456 -h 192.168.1.3 -P 3307
四、新增一個MySQL實例:端口3308
1、新建3308目錄和data目錄
mkdir -p /data/3308/data
2、拷貝/data/3306目錄下的my.cnf和mysql文件到3308
cp /data/3306/my.cnf /data/3308/
cp /data/3306/mysql /data/3308/
3、將3308目錄下的my.cnf和mysql中的3306改爲3308
sed -n s#3306#3308#gp my.cnf
sed -i s#3306#3308#g my.cnf
sed -n s#3306#3308#gp mysql
sed -i s#3306#3308#g mysql
4、修改my.cnf中的server-id
server-id = 5
5、授權mysql用戶訪問3308目錄
chown -R mysql.mysql 3308/
6、初始化數據庫3308
cd /application/mysql/scripts/
./mysql_install_db --basedir=/application/mysql --datadir=/data/3308/data--user=mysql
7、啓動3308數據庫
/data/3308/mysql start
8、修改MySQL用戶密碼:必須指定sock
mysqladmin -u root -S /data/3308/mysql.sock password '123456'
9、登陸MySQL-3308
mysql -S /data/3308/mysql.sock -uroot -p
create database d3308;
五、MySQL管理基礎
1、MySQL啓動基本原理
/etc/init.d/mysqld是一個shell啓動腳本,啓動後最終會調用mysqld_safe腳本,最後調用mysqld服務啓動MySQL。/etc/init.d/mysqld腳本中調用mysqld_safe的內容如下:
$bindir/mysqld_safe--datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args>/dev/null 2>&1 &
2、MySQL單實例啓動命令
/etc/init.d/mysqld start
3、查看MySQL端口:CentOS7取消了netstart命令,改爲ss,兩者一樣
ss -lnt | grep 3306
4、查看MySQL進程
ps -ef | grep mysql | grep -v grep
5、利用初始化數據庫時MySQL提示的方法啓動
(1)啓動命令
mysqld_safe --user=mysql
(2)提示說明
a、當需找回root密碼時,經常用mysql_safe --user=mysql &帶參數啓動。
b、自己載髮腳本啓動MySQL數據庫時,可能會使用到這個啓動方法
c、/etc/init.d/mysqld和mysql_safe --user=mysql &的啓動實質是一樣的。
6、關閉數據庫方法
(1)常見正常(優雅)方法
a、mysqladmin方法
mysqladmin -uroot -p123456 shutdown
b、自帶腳本
/etc/init.d/mysqld stop
c、kill信號的方法(最好不用)
kill -USR2 `cat path/pid`
(2)強制關閉數據庫
killall mysqld
pkill mysqld
killall -9 mysqld
(3)強制關閉數據庫的注意事項
a、用killall關閉,要直到出現mysqld: no process killed才表示完成關閉操作
b、一般在生產環境儘量不要用強制關閉數據庫的方法,在生產環境中,高併發業務時,可能會引起數據丟失。甚至導致數據庫無法啓動的故障。
野蠻粗魯殺死數據庫導致故障企業案例見備註參考博文19
7、登陸MySQL
(1)單實例登陸
mysql -uroot -p
(2)多實例登陸
a、本地登陸
mysql -S /data/3308/mysql.sock -uroot -p
b、遠程登陸
mysql -uroot -p -h 192.168.1.3 -P3306
(3)MySQL操作命令的歷史記錄
cat /root/.mysql_history
8、修改MySQL登陸提示符
(1)一般顯示的提示符
mysql>
(2)命令行臨時修改提示符
mysql> prompt \u@mysql \r:\m:\s>
PROMPT set to '\u@mysql \r:\m:\s>'
root@mysql 02:18:11>
(3)my.cnf配置文件永久修改提示符
[mysql] #不是[mysqld]
prompt=\\u@mysql \\r:\\m:\\s>
9、善用MySQL的幫助命令help
所有操作在登陸MySQL後進行。
(1)顯示客戶端相關命令幫助:help
mysql> help
(2)顯示MySQL命令幫助:help command
mysql> help show
mysql> help grant
10、退出MySQL
Bye
quit
exit
ctrl + c
ctrl + d
11、設置及修改MySQL root用戶密碼
(1)新增root權限的用戶system
grant all privileges on *.* to system@'localhost' identified by '123456'with grant option;
(2)刪除除system外的所有用戶
delete from mysql.user where user<>'system'
(3)爲root用戶設置密碼(命令行操作,剛安裝時root沒密碼)
a、單實例
mysqladmin -u root password '123456';
b、多實例
mysqladmin -u root -S /data/3307/mysql.sock password '123456'
(4)修改root用戶密碼(命令行操作)
a、方法一:mysqladmin命令行操作
(i)單實例
mysqladmin -u root -p123456 password '123456789';
(ii)多實例
mysqladmin -u root -p123456 -S /data/3307/mysql.sock password '123456'
b、方法二:普通SQL操作
(i)用法
select user,host,password from mysql.user;
update mysql.user set password=password('456') where user='root' andhost='localhost';
flush privileges;
(ii)應用場景
適合於MySQL root用戶密碼丟失後通過--skip-grant-tables參數啓動數據庫後修改密碼。
c、方法三:MySQL的set命令-修改當前登陸用戶的密碼
mysql> set password=password('123456789');
mysql> flush privileges;
12、找回丟失的MySQL的root用戶密碼-單實例
(1)停止MySQL數據庫
/etc/init.d/mysqld stop
(2)使用--skip-grant-tables參數忽略密碼驗證模式啓動數據庫
mysqld_safe -–skip-grant-tables -–user=mysql &
(3)直接登陸MySQL
mysql
或
mysql –uroot –p #直接回車,無密碼
(4)修改root用戶密碼
a、不能用mysqladmin方式修改密碼,因爲mysqladmin在用戶存在密碼時修改密碼,是要求提供原密碼的。
b、只能使用SQL語句來修改
update mysql.user set password=password("456") whereuser='root' and host='localhost';
flush privileges;
quit;
(5)重啓MySQL數據庫
a、不能用/etc/init.d/mysqldstop來停止數據庫,因爲不是腳本啓動的,沒有PID文件
b、只能使用mysqladmin命令加修改後的密碼來停止數據庫
mysqladmin –uroot –p456 shutdown
ps –ef | grep mysql
c、使用/etc/init.d/mysqld腳本來啓動數據庫
/etc/init.d/mysqld start
(6)客戶端登陸MySQL數據庫
mysql –uroot –p456
13、找回丟失的MySQL的root用戶密碼-多實例
(1)停止數據庫
killall mysqld #只能用killall了,儘量不要用kill -9
(2)使用skip-grant-tables和defaults-file參數忽略密碼驗證模式和指定my.cnf文件啓動數據庫
mysqld_safe –-defaults-file=/data/3306/my.cnf -–skip-grant-tables -–user=mysql&
說明:-–defaults-file必須在-–skip-grant-tables
(3)直接登陸MySQL
mysql –S /data/3306/mysql.sock
(4)修改root用戶密碼
update mysql.user set password=password("456") whereuser='root' and host='localhost';
flush privileges;
quit;
(5)重啓MySQL數據庫
killall mysqld
ps –ef | grep mysql
/data/3306/mysql start
(6)客戶端登陸MySQL數據庫
mysql –uroot –p456 –S /data/3306/mysql.sock
六、MySQL常見管理
1、創建數據庫
(1)語法
create database <dbname>
(2)要求
不能以數字開頭
(3)示例:使用在編譯安裝時沒有指定數據庫字符集的MySQL數據庫
a、創建一個默認字符集的數據庫
(i)創建
create database test1;
(ii)查看數據庫
show databases like 'test%';
(iii)查看建庫語句
show create database test1;
+----------+------------------------------------------------------------------+
| Database | Create Database |
+----------+------------------------------------------------------------------+
| test1 | CREATE DATABASE`test1` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+------------------------------------------------------------------+
show create database test1\G
*************************** 1. row ***************************
Database: test1
Create Database: CREATE DATABASE `test1` /*!40100 DEFAULT CHARACTERSET latin1 */
(iv)說明
拉丁(latin1)字符集實際上也可以支持中文
加\G的作用是來格式化輸出信息,便於查看
在編譯時沒有指定數據庫字符集,則默認是拉丁(latin1)字符集。
b、創建一個GBK字符集的數據庫
(i)創建
create database test2 default character set gbk collategbk_chinese_ci;
(ii)查看數據庫
show databases like 'test%';
(iii)查看建庫語句
show create database test2\G
*************************** 1. row ***************************
Database: test2
Create Database: CREATE DATABASE `test2` /*!40100 DEFAULT CHARACTERSET gbk */
(iv)說明
collate gbk_chinese_ci是校對規則
c、創建一個UTF8字符集的數據庫
(i)創建
create database test3 default character set utf8 collate utf8_general_ci;
(ii)查看數據庫
show databases like 'test%';
(iii)查看建庫語句
show create database test3\G
*************************** 1. row ***************************
Database: test3
Create Database: CREATE DATABASE `test3` /*!40100 DEFAULT CHARACTERSET utf8 */
d、生產企業是如何創建MySQL數據庫
(i)根據開發的程序確定字符集,一般建議用UTF8
(ii)編譯的時間指定字符集
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
(iii)建庫的時候默認即可
create database <dbname>
(iv)如果編譯時沒指定或指定了與程序不同的字符集,則在建庫時指定字符集即可
create database test3 default character set utf8 collateutf8_general_ci;
(v)數據庫必須支持指定字符集
示例:
-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii
2、連接數據庫
(1)語法
use <dbname>
(2)示例
use test1;
3、查看數據庫
(1)語法
select database();
(2)示例
a、如果沒有使用use dbname,則顯示爲NULL
select database();
+------------+
| database() |
+------------+
| NULL |
+------------+
b、使用use dbname,則顯示相應的dbname
use test1
Database changed
select database();
+------------+
| database() |
+------------+
| test1 |
+------------+
4、刪除數據庫
(1)語法
drop database <dbname>
(2)示例
drop database test1;
5、查看數據庫版本
select version();
+-----------+
| version() |
+-----------+
| 5.1.72 |
+------------+
6、查看當前用戶
select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
7、查看當前時間
select user();
+---------------------+
| now() |
+---------------------+
| 2017-03-27 21:15:46 |
+---------------------+
8、查看當前數據庫下的表
show tables;
Empty set (0.00 sec) #新建的庫,沒有表
9、查看指定數據庫下的表
show tables from test2;
show tables in test2;
10、刪除數據庫中指定用戶
(1)語法
drop user "user"@"主機域"
(2)要求
可以是單引號,也可以是雙引號。但是不能不加。如果主機名中有大寫字母的則drop刪除不了,可以用delete語句來刪除mysql.user表中的用戶。
(3)示例
drop user 'root'@'localhost';
drop user 'system'@"localhost";
drop user ''@"localhost";
11、創建用戶及授權
(1)查看GRANT命令幫助獲取創建用戶並授權的例子
mysql> help grant;
CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';
GRANT USAGE ON *.* TO 'jeffrey'@'localhost' WITHMAX_QUERIES_PER_HOUR 90;
(2)普通創建用戶方法:先Create後grant
a、語法
CREATE USER 'username'@'主機域' IDENTIFIED BY 'mypass';
GRANT ALL ON dbname.* to 'username'@'localhost'
b、示例
create user 'u1'@'localhost' identified by '123456';
grant all on test1.* to 'u1'@'localhost';
(3)運維人員常用創建用戶方法:使用grant命令在創建用戶的同時進行授權
a、語法
GRANT ALL PRIVILEGES ON dbname.* to 'username'@'主機域' identified by 'password';
b、說明
GRANT | ALL PRIVILEGES | ON dbname.* | to 'username'@'主機域' | identified by 'password' |
授權命令 | 對應權限 | 目標:庫和表 | 用戶名和客戶端主機 | 用戶密碼 |
(4)遠程主機授權連接數據庫
grant命令的語法中主機域部分爲授權訪問數據庫的客戶端主機,可以用域名、IP或IP段來表示。遠程主機的授權方法有2種,具體如下:
a、方法一:百分號匹配法
grant all on *.* to test@'192.168.0.%' identified by '123456';
flush privileges;
b、方法二:子網掩碼匹配法
grant all on *.* to test@'192.168.1.0/24'identified by '123456';
grant all on *.* to test@'192.168.1.0/255.255.255.0' identified by'123456';
flush privileges;
flush privileges;
(5)示例
a、創建u1用戶,具備test1庫所有權限,並允許從localhost主機登陸數據庫,密碼是123456
(i)grant命令創建並授權
grant all on test1.* to 'u1'@'localhost' identified by '123456';
(ii)刷新權限
flush privileges;
(iii)查看權限
show grants for u1@'localhost';
+----------------------------------------------------------------------------------+
| Grants for u1@localhost |
+---------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO'u1'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB743..' |
| GRANT ALL PRIVILEGES ON `test1`.* TO'u1'@'localhost' |
+----------------------------------------------------------------------------------+
(iv)說明
查看權限可以看出授權是分爲2步:
第一步是授權可登陸GRANT USAGE ON*.*。USAGE表示只有登陸權限。
第二步是授權可訪問ON`test1`.* TO 'u1'@'localhost'
b、創建u2用戶,具備test1庫所有權限,並允許從192.168.0.3主機登陸數據庫,密碼是123456
(i)grant命令創建並授權
grant all on test1.* to 'u2'@'192.168.0.3' identified by'123456';
(ii)刷新權限
flush privileges;
(iii)說明
如果授權時主機域不是客戶端主機,則會報錯,提示沒有權限訪問MySQL
Host'192.168.0.3 is not allowed to connect to this MySQL server
c、創建u3用戶,測試USAGE權限
(i)創建u3用戶,允許從localhost主機登陸數據庫,密碼是123456
create user u3@'localhost' identified by '123456';
(ii)查看權限
show grants for u3@'localhost';
+-----------------------------------------------------------------------------+
| Grants for u3@localhost |
+-----------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'u3'@'localhost' IDENTIFIED BYPASSWORD '*6310..。。。。' |
+-----------------------------------------------------------------------------+
(iii)登陸數據庫
mysql -uu3 –p123456
(iv)查看數據庫:沒有權限,只能看到information_schema
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
(v)創建一個新數據庫:報錯是,提示沒有權限(Access denied)
create database test4;
ERROR 1044 (42000): Access denied for user 'u3'@'localhost' todatabase 'test4'
(vi)在mysql的root用戶下對u3進行授權,具備test1庫所有權限
mysql> mysql –uroot –p123456
grant all on test1.* to u3@'localhost';
flush privileges;
(vii)在mysql的u3用戶查看數據庫
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| test1 |
+--------------------+
d、創建u4用戶,測試遠程連接
(i)創建u4用戶,授權具備所有權限,允許從192.168.0.0網段的所有主機登陸數據庫,密碼是123456
grant all on *.* to 'u4'@'192.168.0.%' identified by '123456';
(ii)刷新權限
flush privileges;
(iii)客戶端登陸
mysql -uu4 -p123456 -h192.168.0.2
(iv)戶查看數據庫
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbs |
| mysql |
| test1 |
| test2 |
| test3 |
+--------------------+
12、查看AllPRIVILEGES權限內容
(1)方法一:通過show grants查看
a、查看u1用戶在test1數據庫的權限:ALL PRIVILEGES
show grants for u1@'localhost';
+----------------------------------------------------------------------------+
| Grants for u1@localhost |
+---------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO'u1'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837E..|
| GRANT ALL PRIVILEGES ON `test1`.* TO'u1'@'localhost' |
+---------------------------------------------------------------------------+
b、移除u1用戶在test1數據庫的INSERT權限:必段匹配相關數據庫
revoke insert on test1 to 'u1'@'localhost'
c、再次查看u1用戶在test1數據庫的權限
show grants for u1@'localhost';
+---------------------------------------------------------------------------+
| Grants for u1@localhost |
+---------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO'u1'@'localhost' IDENTIFIED BY PASSWORD '*6B8....' |
| GRANT SELECT, UPDATE, DELETE, CREATE,DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY, TABLES, LOCK TABLES, EXECUTE,CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON`test1`.* TO 'u1'@'localhost' |
+---------------------------------------------------------------------------+
d、myslq命令使用-e參數,通過Linux Shell命令行查看u1用戶在test1數據庫的權限
mysql -uroot -p123456 -e "show grants for u1@'localhost';"
e、MySQL權限列表如下
SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX,ALTER, CREATE TEMPORARY, TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW,CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER
(2)方法二:通過MySQL相關表查看
a、與用戶權限相關的表
(i)表名
mysql.db、mysql.user、mysql.host
(ii)字段含義
Select_priv:確定用戶是否可以通過SELECT命令選擇數據。
Insert_priv:確定用戶是否可以通過INSERT命令插入數據。
Update_priv:確定用戶是否可以通過UPDATE命令修改現有數據。
Delete_priv:確定用戶是否可以通過DELETE命令刪除現有數據。
Create_priv:確定用戶是否可以創建新的數據庫和表。
Drop_priv:確定用戶是否可以刪除現有數據庫和表。
Reload_priv:確定用戶是否可執行刷新和重新加載各種內部緩存的特定命令,包括日誌、權限、主機、查詢和表。
Shutdown_priv:確定用戶是否可以關閉MySQL服務器。在將此權限提供給root賬戶之外的任何用戶時應當謹慎。
Process_priv:確定用戶是否可以通過SHOW PROCESSLIST命令查看其他用戶的進程。
File_priv:確定用戶是否可以執行SELECT INTO OUTFILE和LOADDATA INFILE命令。
Grant_priv:確定用戶是否可以將已經授予給該用戶自己的權限再授予其他用戶。
References_priv:目前只是某些未來功能的佔位符;現在沒有作用。
Index_priv:確定用戶是否可以創建和刪除表索引。
Alter_priv:確定用戶是否可以重命名和修改表結構。
Show_db_priv:確定用戶是否可以查看服務器上所有數據庫的名字,包括用戶擁有足夠訪問權限的數據庫。可以考慮對所有用戶禁用這個權限,除非有特別不可抗拒的原因。
Super_priv:確定用戶是否可以執行某些強大的管理功能,例如通過KILL命令刪除用戶進程,使用SETGLOBAL修改全局MySQL變量,執行關於複製和日誌的各種命令。
Create_tmp_table_priv:確定用戶是否可以創建臨時表。
Lock_tables_priv:確定用戶是否可以使用LOCK TABLES命令阻止對錶的訪問/修改。
Execute_priv:確定用戶是否可以執行存儲過程。此權限只在MySQL 5.0及更高版本中有意義。
Repl_slave_priv:確定用戶是否可以讀取用於維護複製數據庫環境的二進制日誌文件。
Repl_client_priv:確定用戶是否可以確定複製從服務器和主服務器的位置。
Create_view_priv:確定用戶是否可以創建視圖。此權限只在MySQL 5.0及更高版本中有意義。
Show_view_priv:確定用戶是否可以查看視圖或瞭解視圖如何執行。只在MySQL 5.0及更高版本中有意義。
Create_routine_priv:確定用戶是否可以更改或放棄存儲過程和函數。此權限是在MySQL 5.0中引入的。
Alter_routine_priv:確定用戶是否可以修改或刪除存儲函數及函數。此權限是在MySQL 5.0中引入的。
Create_user_priv:確定用戶是否可以執行CREATE USER命令,這個命令用於創建新的MySQL賬戶。
Event_priv:確定用戶能否創建、修改和刪除事件。這個權限是MySQL 5.1.6新增的。
Trigger_priv:確定用戶能否創建和刪除觸發器,這個權限是MySQL 5.1.6新增的。
b、通過mysql.db表查看用戶u1在數據庫test上的權限:
select * from mysql.db where user='u1'\G;
*************************** 1. row ***************************
Host:localhost
Db: test
User: u1
Select_priv: Y
Insert_priv: Y
Update_priv: Y
Delete_priv: Y
Create_priv: Y
Drop_priv: Y
Grant_priv: N
References_priv: Y
Index_priv: Y
Alter_priv: Y
Create_tmp_table_priv: Y
Lock_tables_priv: Y
Create_view_priv: Y
Show_view_priv: Y
Create_routine_priv: Y
Alter_routine_priv: Y
Execute_priv: Y
Event_priv: Y
Trigger_priv: Y
c、通過mysql.user表查看用戶u1權限
select * from mysql.user where user='u1'\G;
*************************** 1. row ***************************
Host:localhost
User: u1
Password:*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9
Select_priv: N
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
Process_priv: N
File_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Show_db_priv: N
Super_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Execute_priv: N
Repl_slave_priv: N
Repl_client_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Create_user_priv: N
Event_priv: N
Trigger_priv: N
Create_tablespace_priv: N
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin:
authentication_string: NULL
13、企業生產環境如何給用戶授權
(1)博客、BBS等產品的數據庫授權
對於web連接用戶授權儘量採用最小化原則,很多開源軟件都是web界面安裝,因此在安裝期間除了select、insert、update、delete這4個權限外,還需create、drop等比較危險的權限。安裝完成後,還應將create、drop等權限收回。
a、授權
grant select, insert, update, delete, create, drop on blog.* to'blog'@'%' identified by '123456';
b、安裝
c、收加權限
revoke create, drop on blog.* from 'blog'@'%'
14、查看MySQL變量和狀態
(1)查看已生效的變量
show variables;
(2)查看MySQL當前的狀態
show global status;
(3)不重啓MySQL,讓新增變量生效
a、設置變量臨時生效
set global 變量=值
b、查看是否生效
show variables like '變量名%'
c、在配置文件my.cnf中設置相關變量,以便重啓後生效
d、示例
set global key_buffer_size=8096
show variables like 'key_buffer%'
vi /etc/my.cnf
global key_buffer_size=8096M
(4)查看當前MySQL的連接情況
show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host |db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+-------+------------------+
| 1 | root | localhost | NULL| Query | 0 | NULL | show processlist |
+----+------+-----------+------+---------+------+-------+------------------+
(5)生產環境常用狀態命令
a、查看當前會話的數據庫狀態信息
show status;
b、查看整個數據庫運行狀態信息(很重要,要分析並做好監控,DBA重點關注)
show global status;
c、查看正在執行的SQL語句(看不全)
show processlist;
d、查看正在執行的SQL語句(全)
show full processlist;
e、查看數據庫的生效參數信息
show variables;
f、臨時調整數據庫參數(重啓後失效,一般情況下關閉參數不能改,大小參數可以改)
set global key_buffer_size = 31*1024*1024
七、SQL操作
1、創建測試環境
(1)創建測試數據庫mytest
create database mytest;
(2)查看數據庫建庫語句
show create database mytest\G;
*************************** 1. row ***************************
Database: mytest
Create Database: CREATE DATABASE `mytest` /*!40100 DEFAULT CHARACTERSET latin1 */
(3)使用測試庫
use mytest;
2、創建表
(1)語法(Syntax)
a、通過幫助獲取
mysql> help create table
b、常用格式
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] <表名>(
<字段1> <類型1>,
<字段2> <類型2>,
...
<字段n> <類型n>
);
(2)建表示例
a、手工建表語句
create table student (
id int(4) not null,
name char(20) not null,
age tinyint(2) not nulldefault '0', #很小的數字類型,比int小
dept varchar(16) defaultNULL
);
b、MySQL生成的建表語句
CREATE TABLE `student` (
`id` int(4) NOT NULL,
`name` char(20) NOT NULL,
`age` tinyint(2) NOT NULLDEFAULT '0',
`dept` varchar(16) DEFAULTNULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
c、查看建表語句
show create table student\G;
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int(4) NOT NULL,
`name` char(20) NOT NULL,
`age` tinyint(2) NOT NULLDEFAULT '0',
`dept` varchar(16) DEFAULTNULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
d、生產環境建表語句示例
某sns產品生產正式建表語句
use sns;
set names gbk;
CREATE TABLE `subject_comment_manager` (
`subject_comment_manager_id` bigint(12) NOT NULL auto_incrementCOMMENT '主鍵',
`subject_type` tinyint(2) NOT NULL COMMENT '素材類型',
`subject_primary_key` varchar(255) NOT NULL COMMENT '素材的主鍵',
`subject_title` varchar(255) NOT NULL COMMENT '素材的名稱',
`edit_user_nick` varchar(64) default NULL COMMENT '修改人',
`edit_user_time` timestamp NULL default NULL COMMENT '修改時間',
`edit_comment` varchar(255) default NULL COMMENT '修改的理由',
`state` tinyint(1) NOT NULL default '1' COMMENT '0代表關閉,1代表正常',
PRIMARY KEY(`subject_comment_manager_id`),
KEY `IDX_PRIMARYKEY`(`subject_primary_key`(32)),#括號內的32表示對前32個字符做前綴索引。
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8;
(3)查看錶結構
a、方法一:desc
desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null |Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(4) | NO | | NULL | |
| name | char(20) | NO | | NULL | |
| age | tinyint(2) | NO | | 0 | |
| dept | varchar(16) |YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
b、方法二:show columns
mysql> show columns from student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null |Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(4) | NO | | NULL | |
| name | char(20) | NO | | NULL | |
| age | tinyint(2) | NO | | 0 | |
| dept | varchar(16) |YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3、創建索引
(1)創建主鍵索引
a、方法一:在建表時,增加主鍵索引
(i)示例
create table student(
id int(4) not null AUTO_INCREMENT,
name char(20) not null,
age tinyint(2) NOT NULL default '0',
dept varchar(16) default NULL,
primary key(id), #在ID列增加主鍵索引
);
(ii)查看錶結構
desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null |Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | char(20) | NO | MUL | NULL | |
| age | tinyint(2) | NO | | 0 | |
| dept | varchar(16) |YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
b、方法二:在建表後,通過alter命令增加主鍵索引
(i)示例-未建主鍵的Student2表
create table student2(
id int(4) not null,
name char(20) not null,
age tinyint(2) NOT NULLdefault '0',
dept varchar(16) defaultNULL,
KEY index_name (name)
);
(ii)增加主鍵
alter table student2 change id id int primary key;
desc student2;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null |Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(20) | NO | MUL | NULL | |
| age | tinyint(2) | NO | | 0 | |
| dept | varchar(16) |YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
(2)創建普通索引
a、方法一:在建表時,增加主鍵索引
create table student3(
id int(4) not null AUTO_INCREMENT,
name char(20) not null,
age tinyint(2) NOT NULL default '0',
dept varchar(16) default NULL,
primary key(id), #在ID列增加主鍵索引
KEY index_name (name) #在name列增加普通索引
);
b、方法二:在建表後,通過alter命令增加普通索引
(i)語法(Syntax)
alter table <tablename> add index <indexname>(columnname);
(ii)示例
alter table student3 add index myIndex_student3_name(name);
alter table student3 add index myIndex_student3_dept(dept);
(3)刪除索引
a、刪除主鍵索引
alter table student2 drop primary key;
b、刪除普通索引
alter table student3 drop index myIndex_student3_name;
or
drop index myIndex_student3_name on student;
(4)對列中前n個字符建立索引
a、語法(Syntax)
create index index_name on table_name(column_name(length));
b、示例
create index myStudentIndexName on student(dept(8));
(5)創建聯合索引
a、語法(Syntax)
create index index_name on table_name(column_name1,column_name2);
b、示例
create index myStudentUnionIndexName on student(name,dept);
create index myStudentUnionIndexName on student(name(4),dept(8));
c、聯合索引生效條件
按條件列查詢數據時,聯合索引是有前綴生效特性的。如
index(a, b, c)只有公a,ab, abc三個查詢條件列纔可能走索引。b,bc, ac, c等是無法走索引的。
(6)創建非主鍵的唯一索引
a、語法(Syntax)
create unique index index_name on table_name(column_name);
b、示例
create unique index myStudentUnionIndexName on student(age);
(7)查看索引
show index from student\G
(8)索引列的創建和生效條件
a、問一:既然索引可以加快查詢速度,那麼就給所有的列建索引吧?
解答:
索引會加快查詢速度,但會影響更新速度。索引不僅佔用系統空間,更新數據庫時還需維護索引數據。因此,索引是一把雙刃劍,並不是越多越好,例如:數十到幾百行的小表上無需建索引,寫頻繁、讀少的業務要少建索引。
b、到底在哪些列上創建索引?
解答:
(i)索引一定要創建在條件列上
(ii)儘量要選擇在唯一值多的大表上建立索引
4、Insert
(1)創建測試表
CREATE TABLE `test` (
`id` int(4) NOT NULL,
`name` char(20) NOT NULL,
primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
(2)指定所有列名插入數據
insert into test(id,name) values(1,'oldboy');
(3)不指定自增列插入數據
insert into test(name) values('oldboy2');
(4)不指定列插入數據:必須對所有列進行插入
a、正確寫法
insert into test values(3,'oldboy3');
b、錯誤寫法:沒有指定插入自增列
insert into test values('oldboy3');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
(5)批量插入
insert into test values(4,'oldboy4'),(5,'oldboy5'),(6,'oldboy6');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
5、Delete
(1)備份mysest數據庫
mysqldump -uroot -p123456 -B mytest > /data/mysql_bak_$(date+%F).sql
(2)刪除指定記錄
delete from test where id=2;
(3)刪除所有記錄
delete from test;
6、Select單表查詢
(1)查詢表中所有信息
select * from test;
(2)查詢表中指定列
select name from test;
(3)指定條件查詢
select name from test where id=2;
select id,name from test where name='oldboy4';
select id,name from test where name='oldboy4' or id=3;
select id,name from test where id>2 and id<7;
(4)指定返回前3條記錄
select name from test limit 3;
select name from test limit 0,3;
(5)指定返回第3到第6條記錄
select * from test limit 3,6;
(6)排序
select id,name from test order by id asc;
select id,name from test order by id desc;
7、Select多表查詢
(1)創建測試表
a、使用數據庫mytest
use mytest
b、創建學生表student(Sno學號,Sname姓名,Ssex性別,Sage年齡,Sdept所在系)
drop tables student;
create table student(
Sno int(10) NOT NULL COMMENT '學號',
Sname varchar(16) NOT NULL COMMENT '姓名',
Ssex char(2) NOT NULL COMMENT '性別',
Sage tinyint(2) NOT NULL default '0' COMMENT '年齡',
Sdept varchar(16) default NULL COMMENT '所在系',
PRIMARY KEY (Sno) ,
key index_Sname (Sname)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
c、創建課程表Course(Cno課程號,Cname課程名,Ccredit學分)
create table course(
Cno int(10) NOT NULL COMMENT '課程號',
Cname varchar(64) NOT NULL COMMENT '課程名',
Ccredit tinyint(2) NOT NULL COMMENT '學分',
PRIMARY KEY (Cno)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
d、創建成績表SC(Sno學號,Cno課程號,Grade成績)
CREATE TABLE sc (
SCid int(12) NOT NULL auto_increment COMMENT '主鍵',
Cno int(10) NOT NULL COMMENT '學號',
Sno int(10) NOT NULL COMMENT '課程號',
Grade tinyint(2) NOT NULL COMMENT '成績',
PRIMARY KEY (SCid)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
e、插入模擬數據
INSERT INTO student values(0001,'宏志','男',30,'計算機網絡');
INSERT INTO student values(0002,'王碩','男',30,'computerapplication');
INSERT INTO student values(0003,'oldboy','男',28,'物流管理');
INSERT INTO student values(0004,'脈動','男',29,'computerapplication');
INSERT INTO student values(0005,'oldgirl','女',26,'計算機科學與技術');
INSERT INTO student values(0006,'瑩瑩','女',22,'護士');
INSERT INTO course values(1001,'Linux中高級運維',3);
INSERT INTO course values(1002,'Linux高級架構師',5);
INSERT INTO course values(1003,'MySQL高級Dba',4);
INSERT INTO course values(1004,'Python運維開發',4);
INSERT INTO course values(1005,'Javaweb開發',3);
INSERT INTO sc(Sno,Cno,Grade) values(0001,1001,4);
INSERT INTO sc(Sno,Cno,Grade) values(0001,1002,3);
INSERT INTO sc(Sno,Cno,Grade) values(0001,1003,1);
INSERT INTO sc(Sno,Cno,Grade) values(0001,1004,6);
INSERT INTO sc(Sno,Cno,Grade) values(0002,1001,3);
INSERT INTO sc(Sno,Cno,Grade) values(0002,1002,2);
INSERT INTO sc(Sno,Cno,Grade) values(0002,1003,2);
INSERT INTO sc(Sno,Cno,Grade) values(0002,1004,8);
INSERT INTO sc(Sno,Cno,Grade) values(0003,1001,4);
INSERT INTO sc(Sno,Cno,Grade) values(0003,1002,4);
INSERT INTO sc(Sno,Cno,Grade) values(0003,1003,2);
INSERT INTO sc(Sno,Cno,Grade) values(0003,1004,8);
INSERT INTO sc(Sno,Cno,Grade) values(0004,1001,1);
INSERT INTO sc(Sno,Cno,Grade) values(0004,1002,1);
INSERT INTO sc(Sno,Cno,Grade) values(0004,1003,2);
INSERT INTO sc(Sno,Cno,Grade) values(0004,1004,3);
INSERT INTO sc(Sno,Cno,Grade) values(0005,1001,5);
INSERT INTO sc(Sno,Cno,Grade) values(0005,1002,3);
INSERT INTO sc(Sno,Cno,Grade) values(0005,1003,2);
INSERT INTO sc(Sno,Cno,Grade) values(0005,1004,9);
f、查看模擬數據
select * from student;
select * from course;
select * from sc;
(2)查詢學生每門課的學分
select student.sno,student.sname,course.cname,sc.grade from student,course,sc where student.sno=sc.sno and course.cno=sc.cno;
(3)查詢學生每門課的學分,按學號升序排列
select student.sno,student.sname,course.cname,sc.grade from student,course,sc where student.sno=sc.sno and course.cno=sc.cno order by sno;
8、Update
(1)修改指定的記錄
update test set name='zhangsan' where id=4;
(2)不加條件將修改所有記錄(非常危險)
update test set name='zhangsan';
(3)小試牛刀初步增量恢復MySQL數據庫
a、打開MySQL活動日誌
vi /etc/my.cnf
修改前:
#log-bin=mysql-bin
修改後:
log-bin=mysql-bin
b、重啓MySQL,讓配置生效
/etc/init.d/mysqld restart
c、不加條件修改test表中所有記錄
update test set name='lisi';
d、手動對MySQL活動日誌分表
mysqladmin -uroot -p'123456' flush-log
e、查看mysql/data目錄下產生mysql-bin文件
ll /application/mysql/data/
drwx------ 2 mysql mysql 40960 Mar 25 21:06 bbs
-rw-rw---- 1 mysql mysql 5242880 Apr 9 12:44 ib_logfile0
-rw-rw---- 1 mysql mysql 5242880 Mar 4 21:13 ib_logfile1
-rw-rw---- 1 mysql mysql 10485760 Apr 9 12:44 ibdata1
-rw-r----- 1 mysql root 9276 Apr 9 12:44 lamp.err
-rw-rw---- 1 mysql mysql 5 Apr 9 12:44 lamp.pid
drwx------ 2 mysql root 4096 Mar 4 20:48 mysql
-rw-rw----1 mysql mysql 866 Apr 9 13:01 mysql-bin.000001
-rw-rw----1 mysql mysql 106 Apr 9 13:01 mysql-bin.000002
-rw-rw---- 1 mysql mysql 38 Apr 9 13:01 mysql-bin.index
drwx------ 2 mysql mysql 4096 Apr 8 16:34 mytest
-rw-r----- 1 mysql root 23411 Mar 27 16:44 rhel.err
-rw-rw---- 1 mysql mysql 5 Mar 27 15:38 rhel.pid
drwx------ 2 mysql mysql 4096 Mar 27 16:16 test1
drwx------ 2 mysql mysql 4096 Mar 27 16:27 test2
drwx------ 2 mysql mysql 4096 Mar 27 16:33 test3
f、查看mysql-bin文件類型
file /application/mysql/data/mysql-bin.000001
/application/mysql/data/mysql-bin.000001: MySQL replication log
g、使用mysqlbinlog查看mysql-bin.000001文件內容
mysqlbinlog /application/mysql/data/mysql-bin.000001
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET@OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#170409 12:44:26 server id 1 end_log_pos 106 Start: binlog v4, server v 5.1.72-log created 170409 12:44:26 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
KrzpWA8BAAAAZgAAAGoAAAABAAQANS4xLjcyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAqvOlYEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 106
#170409 12:45:49 server id 1 end_log_pos 198 Query thread_id=1 exec_time=0 error_code=0
use `mytest`/*!*/;
SET TIMESTAMP=1491713149/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,@@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET@@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
update test set name='lisi'
/*!*/;
# at 198
#170409 12:59:03 server id 1 end_log_pos 304 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1491713943/*!*/;
update test set name='oldboy1' where id=5
/*!*/;
# at 304
#170409 12:59:12 server id 1 end_log_pos 410 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1491713952/*!*/;
update test set name='oldboy2' where id=6
/*!*/;
# at 410
#170409 12:59:19 server id 1 end_log_pos 516 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1491713959/*!*/;
update test set name='oldboy3' where id=7
/*!*/;
# at 516
#170409 12:59:26 server id 1 end_log_pos 622 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1491713966/*!*/;
update test set name='oldboy4' where id=8
/*!*/;
# at 622
#170409 12:59:33 server id 1 end_log_pos 728 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1491713973/*!*/;
update test set name='oldboy5' where id=9
/*!*/;
# at 728
#17040913:00:48 server id 1 end_log_pos823 Query thread_id=1 exec_time=0 error_code=0
SETTIMESTAMP=1491714048/*!*/;
updatetest set name='oldboy5'
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
h、將mysql-bin.000001文件內容導出到bin.sql文件中,並刪除錯誤操作的語句(上面紅色部分)
mysqlbinlog -d mytest /application/mysql/data/mysql-bin.000001 >mybin.sql
i、恢復數據庫
(i)首先,選擇最近的備份文件進行恢復
mysqldump -uroot -p123456 mytest < /data/mysql_bak_20170709.sql
(ii)最後,通過導出的bin.sql文件恢復(也可以將mybin.sql文件內容加在備份文件後面,一次性恢復)
mysqldump -uroot -p123456 mytest < /data/mybin.sql
j、查看數據恢復情況
select * from test;
+----+---------+
| id | name |
+----+---------+
| 4 | lisi |
| 5 | oldboy1 |
| 6 | oldboy2 |
| 7 | oldboy3 |
| 8 | oldboy4 |
| 9 | oldboy5 |
+----+---------+
9、利用explain查看SQL的執行計劃
(1)查看執行計劃:發現test表上沒有索引,所以也不會走索引。掃描全表6行
explain select * from test where name='oldboy6'\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 6
Extra: Using where
(2)在test表上的name列增加索引
alter table test add index IDX_test_name(name);
(3)再次查看執行計劃,已走索引。只掃描1行
explain select * from test where name='oldboy6'\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: ref
possible_keys: IDX_test_name
key: IDX_test_name
key_len: 20
ref: const
rows: 1
Extra: Using where
(4)查看explain幫助
help explain
10、使用-U參數,防止誤修改或刪除
(1)-U參數
當在mysql登陸時加上-U參數後,發出的update或delete命令後面如果沒有where或limit關鍵字,MySQL程序就會拒絕執行。
(2)指定-U登陸
mysql -uroot -p'123456' -U
(3)執行不帶條件的update操作
use mytest;
update test set name='aaa';
ERROR 1175 (HY000): You are using safe update mode and you tried toupdate a table without a WHERE that uses a KEY column
(4)通過別名給mysql加上-U參數,讓mysql自動帶上-U參數
vi /etc/profile
alias mysql='mysql -U'
11、truncate截斷表
(1)語法(Syntax)
truncate table <table_name>
(2)示例
truncate table test
(3)truncate與delete的區別
truncate更快。因爲truncate是物理刪除,直接清空物理文件,而delete是邏輯刪除,一行一行的刪除。
12、修改表
(1)查看測試表結構
desc test;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null |Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | char(20) | NO | MUL | NULL | |
+-------+----------+------+-----+---------+----------------+
(2)增加表字段
alter table test add sex char(4);
alter table test add column(age int(4),qq varchar(15));
desc test;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null |Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | char(20) | NO | MUL | NULL | |
| sex | char(4) | YES | | NULL | |
| age | int(4) | YES | | NULL | |
| qq | varchar(15) |YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
(3)在指定位置增加表字段:只有first和after兩種
alter table test add tel char(11) after qq;
alter table test add xh char(2) first;
(4)修改表字段
alter table test change age age int(2) comment 'nianlin';
alter table test modify age int(3);
(5)修改表字段的同時,調整位置(只調整位置報錯)
alter table test modify age int(2) after name;
alter table test modify age after name;
ERROR 1064 (42000): You have an error in your SQL syntax; check themanual that corresponds to your MySQL server version for the right syntax touse near 'after name' at line 1
(6)修改表名
rename table test to newtest;
or
alter table newtest rename to test;
12、刪除表
drop table test;
八、MySQL字符集亂碼解決
1、查看演示環境
(1)查看數據庫
show create database mytest;
+----------+-------------------------------------------------------------------+
| Database | Create Database |
+----------+-------------------------------------------------------------------+
| mytest | CREATE DATABASE`mytest` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-------------------------------------------------------------------+
(2)查看錶
use mytest;
show create table student\G;
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int(4) NOT NULLAUTO_INCREMENT,
`name` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
(3)查看數據
insert into student values
(1,'oldboy'),(2,'oldgril'),(3,'inca'),(4,'zuma'),(5,'kaka');
select * from student;
+----+---------+
| id | name |
+----+---------+
| 1 | oldboy |
| 2 | oldgril |
| 3 | inca |
| 4 | zuma |
| 5 | kaka |
+----+---------+
2、測試
insert into student values (6,'張三');
insert into student values (7,'李四');
select * from student;
+----+---------+
| id | name |
+----+---------+
| 1 | oldboy |
| 2 | oldgril |
| 3 | inca |
| 4 | zuma |
| 5 | kaka |
| 6 | ?? |
| 7 | ?? |
+----+---------+
3、解決方法
(1)方法一:set names latin1;
a、操作
vi test.sql
set names latin1;
insert into student values (6,'張三');
insert into student values (7,'李四');
mysql> source test.sql;
select * from student;
+----+---------+
| id | name |
+----+---------+
| 1 | oldboy |
| 2 | oldgril |
| 3 | inca |
| 4 | zuma |
| 5 | kaka |
| 6 | 張三 |
| 7 | 李四 |
+----+---------+
b、原理
實際上set names latin1這個步驟就是先執行set字符集操作,然後再執行更新操作,只不過是通過source加載文件來執行的。
(2)方法二:--default-character-set=latin1參數
a、操作
mysql -uroot -p'123456' --default-character-set=latin1 mytest <test.sql
b、庫外查看
mysql -uroot -p'123456' -e "set names latin1;select * from mytest.student;"
4、字符集亂碼5種解決方法小結
(1)根據數據庫和表的字符集,登陸MySQL後,先執行set names<database_set|table_set>,再執行更新語句或執行語句文件。
set names latin1;
insert into student values (6,'張三');
(2)根據數據庫和表的字符集,在sql文件中更新語句前指定setnames <database_set|table_set>,再通過source命令執行語句文件。
head 1 test.sql
set names latin1;
mysql> source test.sql
(3)根據數據庫和表的字符集,在sql文件中更新語句前指定setnames <database_set|table_set>,再通過mysql命令執行語句文件。
mysql -uroot -p'123456' mytest < test.sql
mysql -uroot -p'123456' -e "set names latin1;select * from mytest.student;"
(4)通過指定MySQL命令的字符集參數--default-character-set=latin1。
mysql -uroot -p'123456' --default-character-set=latin1 mytest <test.sql
(5)在配置文件時設置客戶端及服務端相關參數,永久生效。
更改my.cnf配置文件中客戶端和服務端模塊參數,實現set names <database_set>效果,並永久生效。修改客戶端參數無需重啓服務,退出重新登錄就生效,相當於set names <database_set>
[client]
default-character-set=latin1
[mysqld]
default-character-set=latin1 #適用於5.1及以前版本
character-set-server=latin1 #適用於5.5版本
5、不亂碼的思想:建議中文混合的環境用utf8
一定要保證linux系統、客戶端和服務端,庫、表和程序的字符集統一,就不會出現亂碼了。
(1)Linux:
cat /etc/sysconfig/i18n
LANG="zh_CN.utf8"
(2)MySQL客戶端:
set names latin1 #臨時生效
vi /etc/my.cnf #永久生效
[client]
default-character-set=latin1
(3)MySQL服務端:
vi /etc/my.cnf #永久生效
[mysqld]
default-character-set=latin1 #適用於5.1及以前版本
character-set-server=latin1 #適用於5.5版本
(4)庫、表:可以通過show character set;命令來查找相關字符集對應的校驗規則
create database test_utf8 default character set utf8 collate utf8_general_ci;
(5)程序:下載程序時選擇對應字符集的安裝程序
6、選擇合適的字符集
(1)如果是中英文混用,就用UTF8。(每個漢字3個字節)
(2)如果需支持中文,且數據量很大,性能要求也很高(大量運算、排序等),則選GBK(定長,每個漢字2個字節,每個英文也是2個字節),定長字符集更快、性能更高
(3)處理移動互聯網業務,可能需要使用utf8mb4字符集
7、查看當前MySQL系統支持的字符集
(1)查看支持的所有字符集
show character set;
+----------+-----------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+-----------------------------+---------------------+--------+
| big5 | Big5 TraditionalChinese | big5_chinese_ci | 2 |
| dec8 | DEC WestEuropean | dec8_swedish_ci | 1 |
| cp850 | DOS WestEuropean | cp850_general_ci | 1 |
| hp8 | HP WestEuropean | hp8_english_ci | 1 |
| koi8r | KOI8-R RelcomRussian | koi8r_general_ci | 1 |
| latin1 | cp1252 WestEuropean | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2Central European | latin2_general_ci | 1 |
| swe7 | 7bit Swedish | swe7_swedish_ci | 1 |
| ascii | US ASCII | ascii_general_ci | 1 |
| ujis | EUC-JP Japanese | ujis_japanese_ci | 3 |
| sjis | Shift-JISJapanese | sjis_japanese_ci | 2 |
| hebrew | ISO 8859-8Hebrew | hebrew_general_ci | 1 |
| tis620 | TIS620 Thai | tis620_thai_ci | 1|
| euckr | EUC-KRKorean |euckr_korean_ci | 2 |
| koi8u | KOI8-UUkrainian |koi8u_general_ci | 1 |
| gb2312 | GB2312 SimplifiedChinese | gb2312_chinese_ci | 2 |
| greek | ISO 8859-7Greek | greek_general_ci | 1 |
| cp1250 | Windows CentralEuropean | cp1250_general_ci | 1 |
| gbk | GBK SimplifiedChinese | gbk_chinese_ci | 2 |
| latin5 | ISO 8859-9Turkish | latin5_turkish_ci | 1 |
| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 |
| utf8 | UTF-8Unicode |utf8_general_ci | 3 |
| ucs2 | UCS-2Unicode |ucs2_general_ci | 2 |
| cp866 | DOS Russian | cp866_general_ci | 1 |
| keybcs2 | DOS KamenickyCzech-Slovak | keybcs2_general_ci | 1 |
| macce | Mac CentralEuropean | macce_general_ci | 1 |
| macroman | Mac West European | macroman_general_ci | 1 |
| cp852 | DOS CentralEuropean | cp852_general_ci | 1 |
| latin7 | ISO 8859-13Baltic | latin7_general_ci | 1 |
| utf8mb4 | UTF-8Unicode |utf8mb4_general_ci | 4 |
| cp1251 | WindowsCyrillic |cp1251_general_ci | 1 |
| utf16 | UTF-16Unicode |utf16_general_ci | 4 |
| cp1256 | WindowsArabic |cp1256_general_ci | 1 |
| cp1257 | WindowsBaltic | cp1257_general_ci | 1 |
| utf32 | UTF-32Unicode |utf32_general_ci | 4 |
| binary | Binary pseudocharset | binary | 1 |
| geostd8 | GEOSTD8Georgian |geostd8_general_ci | 1 |
| cp932 | SJIS for WindowsJapanese | cp932_japanese_ci | 2 |
| eucjpms | UJIS for WindowsJapanese | eucjpms_japanese_ci | 3 |
+----------+-----------------------------+---------------------+--------+
(2)查看常用的字符集
mysql -uroot -p'123456' -e "show character set;" | egrep"gbk|utf8|latin1"
latin1 cp1252 WestEuropean latin1_swedish_ci 1
gbk GBK SimplifiedChinese gbk_chinese_ci 2
utf8 UTF-8 Unicode utf8_general_ci 3
utf8mb4 UTF-8 Unicode utf8mb4_general_ci 4
8、查看當前MySQL字符集設置
(1)查看當前MySQL使用的字符集
show variables like 'character_set%';
+--------------------------+-------------------------------------------+
| Variable_name |Value |
+--------------------------+-------------------------------------------+
| character_set_client |utf8 |
| character_set_connection | utf8 |
| character_set_database |latin1 |
| character_set_filesystem | binary |
| character_set_results |utf8 |
| character_set_server |latin1 |
| character_set_system |utf8 |
| character_sets_dir |/application/mysql-5.5.32/share/charsets/ |
+--------------------------+-------------------------------------------+
(2)客戶端字符集
character_set_client、character_set_connection、character_set_results三個參數是客戶端的字符集,如果MySQL不指定,默認情況下與系統的字符集是一致的。也就是與/etc/sysconfig/i18n中的設置是一樣的。
cat /etc/sysconfig/i18n
LANG="en_US.UTF-8"
SYSFONT="latarcyrheb-sun16"
(3)不同字符集參數含義
character_set_client |utf8 #客戶端字符集
character_set_connection |utf8 #連接字符集
character_set_database |latin1 #數據庫字符集,配置文件指定或建庫、表時指定
character_set_results |utf8 #返回結果字符集
character_set_server |latin1 #服務器字符集,配置文件指定或建庫、表時指定
9、MySQL插入中文數據不亂碼深度剖析
(1)查看當前MySQL默認設置的字符集
show variables like 'character_set%';
+--------------------------+-------------------------------------------+
| Variable_name |Value |
+--------------------------+-------------------------------------------+
| character_set_client |utf8 |
| character_set_connection | utf8 |
| character_set_database |latin1 |
| character_set_filesystem | binary |
| character_set_results |utf8 |
| character_set_server |latin1 |
| character_set_system |utf8 |
| character_sets_dir |/application/mysql-5.5.32/share/charsets/ |
+--------------------------+-------------------------------------------+
(2)設置客戶端字符集(如果不是utf8)
vi /etc/sysconfig/i18n
#LANG="en_US.UTF-8"
LANG="zh_CN.UTF-8"
SYSFONT="latarcyrheb-sun16"
(3)查看客戶端字符集
show variables like 'character_set%';
必須保證character_set_client、character_set_connection、character_set_results三個參數的字符集一致,最好是utf8。
(4)執行set names latin1到底做了什麼
由於開始建庫和建表時,沒有指定字符集,系統設置爲默認的latin1字符集,但由於character_set_client、character_set_connection、character_set_results三個客戶端參數的字符集爲utf8,所以在插入或查詢時中文顯示爲亂碼。而set names latin1這條語句執行完後,就是將character_set_client、character_set_connection、character_set_results三個客戶端參數的字符集爲latin1。使客戶端和服務端的字符集統一爲latin1,所以在插入和查詢就不會出現亂碼了。
set names latin1
show variables like 'character_set%';
+--------------------------+-------------------------------------------+
| Variable_name |Value |
+--------------------------+-------------------------------------------+
| character_set_client |latin1 |
| character_set_connection | latin1 |
| character_set_database |latin1 |
| character_set_filesystem | binary |
| character_set_results |latin1 |
| character_set_server |latin1 |
| character_set_system |utf8 |
| character_sets_dir | /application/mysql-5.5.32/share/charsets/|
+--------------------------+-------------------------------------------+
(5)mysql命令參數--default-character-set=latin1做了什麼
a、帶參數--default-character-set=latin1登陸MySQL
mysql -uroot -p --default-character-set=latin1
b、查看字符集
show variables like 'character_set%';
+--------------------------+-------------------------------------------+
| Variable_name |Value |
+--------------------------+-------------------------------------------+
| character_set_client |latin1 |
| character_set_connection | latin1 |
| character_set_database |latin1 |
| character_set_filesystem | binary |
| character_set_results |latin1 |
| character_set_server |latin1 |
| character_set_system |utf8 |
| character_sets_dir |/application/mysql-5.5.32/share/charsets/ |
+--------------------------+-------------------------------------------+
c、作用
與set names latin1的作用一樣,也是臨時修改character_set_client、character_set_connection、character_set_results三個客戶端參數的字符集爲latin1。
(6)調整客戶端字符集永久生效(無需重啓mysql,重新登陸即可,也不會根據i18n中的設置改變了)
vi /etc/my.cnf
[client]
default-character-set=utf8
(7)調整服務端字符集永久生效(需重啓mysql)
a、修改配置文件
vi /etc/my.cnf
[mysqld]
character-set-server=utf8
b、重啓mysqld
/etc/init.d/mysqld restart
c、查看字符集
show variables like 'character_set%';
+--------------------------+-------------------------------------------+
| Variable_name |Value |
+--------------------------+-------------------------------------------+
| character_set_client |utf8 |
| character_set_connection | utf8 |
| character_set_database |utf8 |
| character_set_filesystem | binary |
| character_set_results |utf8 |
| character_set_server |utf8 |
| character_set_system |utf8 |
| character_sets_dir |/application/mysql-5.5.32/share/charsets/ |
+--------------------------+-------------------------------------------+
d、作用
是修改character_set_database、character_set_server兩個服務端參數的字符集爲utf8。
九、更改生產MySQL數據庫字符集
1、數據庫字符集修改步驟
(1)如果是沒有記錄的數據庫,可以通過alter database character set <新字符集> 或者alter table <表名> character set <新字符集>這兩個命令來修改。但如果數據庫中有記錄,則不能使用這兩個命令來修改,因爲這兩個命令只是對新創建的表或記錄生效,對已有的記錄是無效的。
(2)已有記錄的數據庫字符集調整:
a、導出表結構
b、導出數據
c、修改數據庫或表的字符集
d、導入數據
2、示例:將latin1字符集的數據庫mytest修改爲GBK字符集的數據庫
(1)導出表結構(-d:表示只導表結構)
mysqldump -uroot -p123456 --default-character-set=latin1 -d mytest> /mnt/dbbak.sql
(2)編輯/mnt/dbbak.sql文件,將latin1修改爲GBK
(3)確保數據庫不再更新,導出所有數據
mysqldump -uroot -p123456 --quick --no-create-info --extended-insert--default-charcter-set=latin1 mytest > /mnt/dbdatabak.sql
(4)參數說明:
--quick:用於轉儲大的表,強制mysqldump從服務器一次一行的檢索數據,而不是檢索所有行,並輸出CACHE到內容中。
--no-Create-info:不創建Createtable語句
--extended-insert:使用包括多個values列表的多行insert語法,這樣文件更小,IO更小,導入數據快
--default-charcter-set=latin1:按原有字符集導出數據,保證導出的數據所有中文都是可見的,不會保存爲亂碼。
(5)打開/mnt/dbdatabak.sql文件,將setnames latin1修改爲set names gbk
(6)確保MySQL服務端和客戶端編碼統一,本例均爲gbk
(7)刪除數據庫
drop database mytest;
(8)建庫
create database mytest default character set gbk;
(9)導入表結構
mysql -uroot -p mytest < /mnt/dbbak.sql
(10)導入數據
mysql -uroot -p mytest < /mnt/ dbdatabak.sql