MySQL基礎操作


 

第1章 數據庫

2.3 數據庫安裝

MySQL家譜:

1、正宗后代

3.26 MySQL-5.0.xx到MySQL-5.1.xx的產品線 5.2 yum自帶

正式中很少用了。

yum info mysql

yum grouplist

 

2*****、MySQL-5.4.xx-到MySQL-5.7.xx產品線 主流。

主流5.5 5.6 5.7

講此產品線,5.6.34

 

3、MySQL-Cluster-6.0.xx-到MySQL-Cluster-7.5.xx產品線

類似 ORACLE RAC

2.4 數據庫常見安裝方法:

mysql安裝方法:

1、yum/rpm 安裝  適合並發不大,企業內部的一些應用場景 不能定制

 

2、二進制安裝比較簡單方便 適合5.0-5.1和5.5-5.6系列,

解壓即可

 

3、編譯安裝 5.5-5.6系列采用cmake編譯方式*******常用

./cmake ,make, makeinstall

 

4、5.0產品線 configure ,make make install

 

5、利用源碼編譯安裝,做成rpm包,然后在yum倉庫 yum安裝

 

建議:MySQL5.5及以上版本,安裝方式機器數量少的話,推薦cmake編譯安裝 數量多就用二進制免安裝,如果數量特別大,可以選擇定制rpm包的安裝方式

 

講5.6.34,cmake安裝。

 

第3章 單實例安裝:

3.1 安裝過程

1、  安裝MySQL所需要的依賴包和編譯軟件(cmake

[root@db02 ~]# yum install -y ncurses-devel libaio-devel

[root@db02 ~]# yum install -y cmake

[root@db02 ~]# rpm -qa ncurses-devel libaio-devel cmake

ncurses-devel-5.7-4.20090207.el6.x86_64

cmake-2.8.12.2-4.el6.x86_64

libaio-devel-0.3.107-10.el6.x86_64

2、  創建用戶

[root@db02 ~]# useradd mysql -s /sbin/nologin -M

[root@db02 ~]# id mysql

uid=501(mysql) gid=501(mysql) groups=501(mysql)

3、上傳源碼安裝包並解壓

[root@db02 ~]# cd /home/oldboy/tools/

rz傳入

[root@db02 tools]# tar xf mysql-5.6.34.tar.gz

4、編譯、

[root@db02 tools]# cd mysql-5.5.32

cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.34 \

-DMYSQL_DATADIR=/application/mysql-5.6.34/data \

-DMYSQL_UNIX_ADDR=/application/mysql-5.6.34/tmp/mysql.sock \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DWITH_EXTRA_CHARSETS=all \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_FEDERATED_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \

-DWITH_ZLIB=bundled \

-DWITH_SSL=bundled \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_EMBEDDED_SERVER=1 \

-DENABLE_DOWNLOADS=1 \

-DWITH_DEBUG=0

3.2 cmake編譯參數

 

 

5、編譯安裝

make &&make install

提示:

#錯誤情況:磁盤滿了,內存擴大會提高速度

#1)請提前加大VM虛擬機硬件的內存,這樣編譯時候會更快,最好設置2GB以上的內存。

#3)重視每個操作過程的輸出,有錯誤要解決掉再繼續,不能忽略掉操作中的錯誤(error)。

6、做軟鏈接

ln -s /application/mysql-5.6.34/ /application/mysql

7、配置MySQL配置文件

cp support-files/my*.cnf /etc/my.cnf

8、初始化

/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/application/mysql/data --user=mysql

9、授權mysql用戶

chown -R mysql.mysql /application/mysql/

10、復制mysql啟動文件

cp support-files/mysql.server /etc/init.d/mysqld

11、授權mysql啟動文件

chmod 700 /etc/init.d/mysqld

12、加入開機自啟動

chkconfig mysqld on

chkconfig --list mysqld

13、啟動mysql

/etc/init.d/mysqld start

netstat -lntup|grep 330

14、設置mysql全局環境變量

echo 'PATH=/application/mysql/bin/:$PATH' >>/etc/profile

tail -1 /etc/profile

source /etc/profile

echo $PATH

mysql

重新初始化

##############################################################

#重新初始化

#rm -fr /application/mysql/data/*

#授權mysql用戶

chmod 700 /etc/init.d/mysqld

chown -R mysql.mysql /application/mysql/

/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/application/mysql/data --user=mysql

[root@db02 mysql-5.6.34]# pwd

/home/oldboy/tools/mysql-5.6.34

cp support-files/my-default.cnf /etc/my.cnf

/etc/init.d/mysqld start

##############################################################

 

15、設置密碼:

mysqladmin -u root password 'oldboy123'

 

 

 

3.2.1 清理用戶及無用數據庫(基本優化)

select user,host from mysql.user;

drop user ''@'db02';

drop user ''@'localhost';

drop user 'root'@'db02';

drop user 'root'@'::1';

select user,host from mysql.user;

drop database test;

show databases;

##################

3.3 排錯

tail -100 /application/mysql/data/db02.err

常見錯誤

3.3.1 啟動問題四:

常見問題1

[root@mysql02 ~]# /etc/init.d/mysqld start

Starting MySQL.Logging to '/application/mysql-5.6.36/data/mysql02.err'.

170618 18:59:33 mysqld_safe Directory '/application/mysql-5.6.36/tmp' for UNIX socket file don't exists.

 ERROR! The server quit without updating PID file (/application/mysql-5.6.36/data/mysql02.pid).

解決方法:

[root@mysql02 ~]# mkdir /application/mysql/tmp

[root@mysql02 ~]# chown -R mysql.mysql /application/mysql/

[root@mysql02 ~]# /etc/init.d/mysqld start

Starting MySQL.Logging to '/application/mysql-5.6.36/data/mysql02.err'.

. SUCCESS!

常見問題2

故障:ERROR! The server quit without updating PID file

1.權限.chown -R mysql.mysql

2.killall mysqld

3.重新初始化.

4.運行1年了,出問題(非法關機或者關數據庫).

 

第4章 多實例介紹

4.1 什么是MySQL多實例?

在一台服務器上安裝一套MySQL程序,起多個不同的端口,通過不同的端口提供服務 ,多實例配置用多個配置文件配置  server_id的區別 端口的區別 數據文件路徑的區別

 

 

 

4.2 MySQL多實例的作用,

·有效利用服務器資源

當單個服務器資源有剩余時,可以充分利用剩余的資源提供更多的服務,且可以實現資源的邏輯隔離。

節約服務器資源

當公司資金緊張,但是數據庫又需要各自盡量獨立地提供服務,而且,需要主從復制等技術時,多實例就再好不過了。

MySQL多實例有它的好處,但也有其弊端,比如,會存在資源互相搶占的問題

當某個數據庫實例並發很高或有SQL慢查詢時,整個實例會消耗大量的系統CPU、磁盤I/O等資源,導致服務器上的其他數據庫實例提供服務的質量一起下降。這就相當於大家住在一個房子的不同卧室一樣,早晨起來上班,都要刷牙、洗臉等,這樣衛生間就會長期占用,其他人要等待一樣。不同實例獲取的資源是相對獨立的,無法像虛擬化一樣完全隔離。

4.3 MySQL多實例的生產應用場景

4.3.1 資金緊張型公司的選擇

若公司資金緊張,公司業務訪問量不太大,但又希望不同業務的數據庫服務各自盡量獨立地提供服務而互相不受影響,同時,還需要主從復制等技術提供備份或讀寫分離服務,那么,多實例就再好不過了。例如:可以通過3台服務器部署9~15個實例,交叉做主從復制、數據備份及讀寫分離,這樣就可達到9~15台服務器每個只裝一個數據庫才有的效果。這里要強調的是,所謂的盡量獨立是相對的。

4.3.2 並發訪問不是特別大的業務

當公司業務訪問量不太大的時候,服務器的資源基本上都浪費了,這時就很適合多實例的應用,如果對SQL語句的優化做得比較好,MySQL多實例會是一個很值得使用的技術,即使並發很大,合理分配好系統資源,搭配好服務,也不會有太大問題。

4.3.3 門戶網站應用MySQL多實例場景

門戶網站通常都會使用多實例,因為配置硬件好的服務器,可節省IDC機櫃空間,同時,跑多實例也會減少硬件資源跑不滿的浪費。比如,百度公司的很多數據庫都是多實例,不過,一般是從庫多實例,例如某部門中使用的IBM服務器為48核CPU,內存96GB,一台服務器跑3~4個實例;此外,新浪網使用的也是多實例,內存48GB左右。

 

 

 

 

4.4 多實例安裝:

#####################################

多實例安裝 多實例與單實例只能用一個

 

1、安裝MySQL所需要的依賴包和編譯軟件(cmake

[root@db02 ~]# yum install -y ncurses-devel libaio-devel

[root@db02 ~]# yum install -y cmake

[root@db02 ~]# rpm -qa ncurses-devel libaio-devel cmake

ncurses-devel-5.7-4.20090207.el6.x86_64

cmake-2.8.12.2-4.el6.x86_64

libaio-devel-0.3.107-10.el6.x86_64

2、創建用戶

[root@db02 ~]# useradd mysql -s /sbin/nologin -M

[root@db02 ~]# id mysql

uid=501(mysql) gid=501(mysql) groups=501(mysql)

3、上傳源碼安裝包並解壓

[root@db02 ~]# cd /home/oldboy/tools/

rz傳入

wget -q http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.34.tar.gz

[root@db02 tools]# tar xf mysql-5.6.34.tar.gz

4、編譯、

[root@db02 tools]# cd mysql-5.5.32

cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.34 \

-DMYSQL_DATADIR=/application/mysql-5.6.34/data \

-DMYSQL_UNIX_ADDR=/application/mysql-5.6.34/tmp/mysql.sock \

-DDEFAULT_CHARSET=utf8 \

-DDEFAULT_COLLATION=utf8_general_ci \

-DWITH_EXTRA_CHARSETS=all \

-DWITH_INNOBASE_STORAGE_ENGINE=1 \

-DWITH_FEDERATED_STORAGE_ENGINE=1 \

-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \

-DWITH_ZLIB=bundled \

-DWITH_SSL=bundled \

-DENABLED_LOCAL_INFILE=1 \

-DWITH_EMBEDDED_SERVER=1 \

-DENABLE_DOWNLOADS=1 \

-DWITH_DEBUG=0

5、編譯安裝

make &&make install

提示:

#錯誤情況:磁盤滿了,內存擴大會提高速度

#1)請提前加大VM虛擬機硬件的內存,這樣編譯時候會更快,最好設置2GB以上的內存。

#3)重視每個操作過程的輸出,有錯誤要解決掉再繼續,不能忽略掉操作中的錯誤(error)。

6、做軟鏈接

ln -s /application/mysql-5.6.34/ /application/mysql

 

 

若安裝了mysql單實例關閉單實例

[root@db02 mysql-5.6.34]# /etc/init.d/mysqld stop  關閉單實例

Shutting down MySQL.. SUCCESS!

[root@db02 mysql-5.6.34]# chkconfig mysqld off   關閉單實例

 

7、把data.zip放入/

unzip data.zip 解壓配置文件包

[root@db02 /]# tree /data/

/data/

├── 3306

│?? ├── my.cnf

│?? └── mysql

└── 3307

    ├── my.cnf

└── mysql

8、創建多實例目錄

mkdir /data//{3306,,3307}/data -p

9、授權多實例目錄

chown -R mysql.mysql /data/

10、授權啟動文件執行權限

find /data/ -name mysql|xargs chmod 700

find /data/ -name mysql|xargs ls -l

11、初始化

cd /application/mysql/scripts

./mysql_install_db  --defaults-file=/data/3306/my.cnf --basedir=/application/mysql/ --datadir=/data/3306/data --user=mysql

./mysql_install_db  --defaults-file=/data/3307/my.cnf --basedir=/application/mysql/ --datadir=/data/3307/data --user=mysql

12、設置全局環境變量

echo 'PATH=/application/mysql/bin/:$PATH' >>/etc/profile

tail -1 /etc/profile

source /etc/profile

13、啟動多實例MySQL

[root@db02 tools]# /data/3306/mysql start

Starting MySQL...

[root@db02 tools]# /data/3307/mysql start

Starting MySQL...

14、登錄多實例數據庫

[root@db02 tools]# mysql -S /data/3306/mysql.sock

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 1

Server version: 5.6.34 Source distribution

 

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

 

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

mysql>

15、給mysql設置密碼

[root@db02 scripts]# mysqladmin password oldboy123 -S /data/3306/mysql.sock

[root@db02 scripts]# mysqladmin password oldboy123 -S /data/3307/mysql.sock

[root@db02 scripts]# mysqladmin password oldboy123 -S /data/3308/mysql.sock

16、登錄有密碼的實例

[root@db02 scripts]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock

17、#有密碼改密碼

[root@db02 scripts]# mysqladmin -poldboy456 password oldboy123 -S /data/3307/mysql.sock

 

4.5 現場作業:請你增加一個3308實例。

mkdir -p /data/3308/data

\cp /data/3306/my.cnf  /data/3308/

\cp /data/3306/mysql  /data/3308/

sed -i 's/3306/3308/g' /data/3308/my.cnf

sed -i 's/server-id = 6/server-id = 8/g' /data/3308/my.cnf

sed -i 's/3306/3308/g' /data/3308/mysql

chown -R mysql:mysql /data/3308

chmod 700 /data/3308/mysql

cd /application/mysql/scripts

./mysql_install_db --defaults-file=/data/3308/my.cnf --datadir=/data/3308/data --basedir=/application/mysql --user=mysql

chown -R mysql:mysql /data/3308

egrep "server-id|log-bin" /data/3308/my.cnf

/data/3308/mysql start

sleep 5

netstat -lnt|grep 3308

 

 

 

 

 

 

 

 

第5章 MySQL安全優化

 

 

不要給數據庫外網IP

 

第6章 mysql啟動基本原理

6.1 MySQL單實例啟動基本原理說明

/etc/init.d/mysqld是一個shell啟動腳本,啟動后最終會調用mysqld_safe腳本,最后調用mysqld主程序啟動mysql,如下,/etc/init.d/mysqld腳本中調用mysqld_safe的程序。

/etc/init.d/mysqld啟動:

$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &

/etc/init.d/mysqld 停止:

if (kill -0 $mysqld_pid 2>/dev/null)

      then

        echo $echo_n "Shutting down MySQL"

        kill $mysqld_pid

6.2 MySQL單實例服務啟動小結

1)使用/etc/init.d/mysqld start 命令啟動數據庫的本質就相當於執行mysqld_safe --user=mysql &命令

2)后文老男孩自己開發shell腳本啟動多實例數據庫時就是調用的mysqld_safe程序。

3)在找回MySQL root密碼時,也會使用musqld_safe程序並帶忽略授權表的參數啟動來找回root密碼

請描述MySQL啟動與關閉的原理?
mysql 使用start啟動,調用mysqld_safe指向配置文件來管理mysqld的進程。
mysql 使用stop關閉原理,是利用KIll的方式殺掉mysqld_pid進程號。

6.3 關閉MySQL數據庫的方法選擇順序如下:

第一種、最先使用MySQL自帶的管理腳本,實例如下:

/etc/init.d/mysqld stop

第二種:為mysqladmin管理方法:

mysqladmin -uroot -poldboy123 shutdown #===這個命令最大的障礙就是必須事先知道密碼。

第三種:為利用系統進程管理命令關閉MySQL

kill pid ##==這里的pid為數據庫服務對應的進程號、

killall mysqld ##==這里的mysqld是數據庫服務對應的進程名字。

pkill mysqld    ##==這里的mysqld是數據庫服務對應的進程名字

可通過如下地址查看生產高並發環境野蠻粗魯殺死數據庫導致故障企業案例:

http://oldboy.blog.51cto.com/2561410/1431161

http://oldboy.blog.51cto.com/2561410/1431172

 

6.4 作業:自己寫一個單實例mysql啟動腳本,並且能夠加入chkconfig管理.

 

 

6.5 多實例MySQL 啟動與關閉方法示例

下面來看一下多實例MySQL啟動與關閉方法的原理

啟動3306實例命令服務的命令為/data/3306/mysql start 實際上就是mysql_safe加上不同的實例配置文件參數啟動實例如下:

mysqld_safe --defaults-file=/data/3306/my.cnf >/dev/null 2>&1 &

停止3306實例命令為/data/3306/mysql stop 實際上就是使用的mysqladmin命令的方法

mysqladmin -u root -podlboy123 -S /data/3306/mysql.sock shutdown

也可以用kill的方式

 

第7章 MySQL登錄、密碼設置、查詢幫助

7.1 MySQL登錄優化

登錄安全優化:/etc/my.cnf

[client]

user=root

password=oldboy123

設置:600

chmod 600 /etc/my.cnf

 

登錄

[root@db02 ~]# mysql    單實例

[root@db02 ~]# mysql  -S /data/3306/mysql.sock  多實例

 

 

 

[root@db02 ~]# HISTCONTROL=ignorespace  忽略開頭空格的記錄 可以加入環境變量

[root@db02 ~]#  mysql -uroot -poldboy -S /data/3306/mysql.sock 安全登錄加空格開頭

7.2 查看MYSQL命令幫助

man linux命令及配置文件\函數等.

help linux內置命令

 

mysql幫助:

help或?

到底.

#設置MySQL的提示符

mysql> prompt \u@oldboy \r:\m:\s-->

PROMPT set to '\u@oldboy \r:\m:\s-->'

root@oldboy 11:41:12-->

 

 

7.3 設置及修改MySQL root用戶密碼

方法1:

單實例修改:mysqladmin -uroot -poldboy123 password oldboy

多實例修改:mysqladmin -uroot -poldboy -S /data/3306/mysql.sock password oldboy123

方法二:

mysql登錄后修改

mysql> update mysql.user set password=password('1234') where user='root' and host='localhost';

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

7.4 單實例找回MySQL root用戶密碼(面試題)

單實例:

忽略授權表啟動:

單實例:mysqld_safe --skip-grant-table --user=mysql &

多實例:mysqld_safe --defaults-file=/data/3306/my.cnf --skip-grant-table &

直接mysql 命令登錄

修改密碼:update mysql.user set password=PASSWORD("oldboy1234") where user='root' and host='localhost';

#刷新flush privileges;

#成功登錄mysql -uroot -poldboy1234

#重啟MySQL

pkill mysql    殺掉MySQL

/etc/init.d/mysqld start    正常啟動

mysql -uroot -poldboy1234   登錄成功

###############################################

7.5 多實例找回MySQL-root密碼丟失############

###############################################

#跳過授權表不驗證啟動

[root@db02 ~]# mysqld_safe --defaults-file=/data/3306/my.cnf --skip-grant-table &

[root@db02 ~]# mysql -uroot -S /data/3306/mysql.sock  登錄

 

#修改密碼

mysql> update mysql.user set password=PASSWORD("oldboy1234") where user='root' and host='localhost';

Query OK, 1 row affected (0.12 sec)

Rows matched: 1  Changed: 1  Warnings: 0

#刷新

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

#成功登錄

[root@db02 ~]# mysql -uroot -poldboy1234 -S /data/3306/mysql.sock

 

#重啟MySQL

[root@db02 ~]# mysqladmin -uroot -poldboy123 -S /data/3306/mysql.sock shutdown

[root@db02 ~]# mysqld_safe --defaults-file=/data/3306/my.cnf &

[root@db02 ~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock 登錄

7.6 小結

 

第8章 SQL語句DDL DCL DML

DDL(Data Definition Language)——數據定義語言(create,alter,drop),管理基礎數據,例如:庫,表   #←運維要熟練、開發也要熟練

DCL(Data Control Language)——數據控制語言(grant,revoke,commit,rollback),用戶授權,權限回收,數據提交回滾等 #←運維要熟練

DML(Data Manipulation Language)——數據操作語言(select,insert,delete,update),針對數據庫里的表的數據進行操作,記錄  #←開發要熟練,運維要了解

 

SQL分類:

DDL 數據定義語言  管理庫和表     create,drop,alter等.            *****熟練

DCL 數據控制語言  用戶管理授權   grant,revoke,commit;rollback.   *****熟練

DMC 數據操作語言  針對表里的數據 insert,delete,update,select     *****熟悉\開發熟練.

 

8.1 SQL語句基本操作

8.1.1 查看數據庫:

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| oldboy             |

| performance_schema |

+--------------------+

4 rows in set (0.00 sec)

8.1.2 創建數據庫

mysql> create database linjie;

Query OK, 1 row affected (0.01 sec)

8.1.3 指定字符集建庫

CREATE DATABASE db_name CHARACTER SET  charset_name COLLATE collation_name

CREATE DATABASE oldgirl CHARACTER SET gbk COLLATE gbk_chinese_ci;

show character set;找字符集.

mysql> create database linjie character set gbk COLLATE gbk_chinese_ci;

Query OK, 1 row affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

8.1.4 改庫的字符集

mysql> alter database linjie character set utf8 collate utf8_general_ci;

Query OK, 1 row affected (0.00 sec)

mysql> show create database linjie\G

*************************** 1. row ***************************

       Database: linjie

Create Database: CREATE DATABASE `linjie` /*!40100 DEFAULT CHARACTER SET utf8 */

1 row in set (0.00 sec)

8.1.5 查看建庫語句

mysql> show create database mysql\G

*************************** 1. row ***************************

       Database: mysql

Create Database: CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */

1 row in set (0.00 sec)

8.1.6 刪庫

mysql> drop database linjie;

Query OK, 0 rows affected (0.00 sec)

8.1.7 切庫

mysql> use oldboy;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

8.1.8 查看當前所在庫

mysql> select database();

+------------+

| database() |

+------------+

| oldboy     |

+------------+

1 row in set (0.00 sec)

8.1.9 查看庫里的表

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

| test             |

+------------------+

2 rows in set (0.00 sec)

8.2 DDL&&DCL語句之管理用戶

8.2.1 查看當前數據庫的用戶列表

mysql> select user,host from mysql.user;

+--------+--------------------------+

| user   | host                     |

+--------+--------------------------+

| oldboy | %                        |

| root   | 127.0.0.1                |###數據核心保留管理員用戶

| oldboy | 172.16.1.%               |

| oldboy | 172.16.1.0/255.255.255.0 |

| oldboy | localhost                |

| root   | localhost                | ###數據庫核心保留管理員用戶

+--------+--------------------------+

6 rows in set (0.00 sec)

 

8.2.2 創建用戶

CREATE

USER

'用戶'@'主機'

IDENTIFIED BY '密碼'

動作(創建)

對象(用戶)

用戶和從哪個主機登錄

設定密碼

現在創建一個oldboy用戶,只允許本地主機登錄,密碼是oldboy123.

CREATE USER '用戶'@'主機' IDENTIFIED BY '密碼';

create user 'oldboy'@'locahost' identified by 'oldboy123';  #只能連接

 

mysql> create user linjie@'localhost' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

企業里創建用戶一般是授權一個內網網段登錄,最常見的網段寫法有兩種。

方法1:172.16.1.%(%為通配符,匹配所有內容)。

方法2:172.16.1.0/255.255.255.0,但是不能使用172.16.1.0/24,是個小遺憾。

8.2.3 查看用戶對應的權限

mysql> show grants for linjie@'localhost';

+---------------------------------------------------------------------------------------------------------------+

| Grants for linjie@localhost                                                                                   |

+---------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'linjie'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |

+---------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

mysql> show grants for linjie@'localhost'\G

*************************** 1. row ***************************

Grants for linjie@localhost: GRANT USAGE ON *.* TO 'linjie'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9'

1 row in set (0.00 sec)

8.2.4 刪除用戶

drop user 'user'@'主機域'

注意引號,可以是單或雙引號,規范是最好加單引號。

drop

user

'user'@'主機域'

動作(刪除)

對象(用戶)

具體用戶

刪除上述中的oldboy用戶:

mysql> select user,host from mysql.user where user=oldboy'; ###刪除前檢查

+------+-----------+

| user | host      |

+------+-----------+

| oldboy | localhost |

+------+-----------+

1 row in set (0.01 sec)

mysql> drop user oldboy@localhost;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select user,host from mysql.user where user='oldboy';

Empty set (0.00 sec)

8.2.5 特殊的刪除方法:

mysql> delete from mysql.user where user='bbs' and host='172.16.1.%';

Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

8.2.6 給用戶授權

8.2.6.1  grant命令語法

1、通過在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' WITH MAX_QUERIES_PER_HOUR 90;

……

通過查看grant的命令幫助,可以很容易的找到創建用戶並授權的例子。

 

2、運維人員比較常用的創建用戶的方法是,使用grant命令在創建用戶的同時進行權限授權。具體授權例子為:

grant all privileges on dbname.* to username@localhost identified by '密碼';

##前面的引號可以沒有,但是密碼一定要引起來

grant

all

on dbname.*

to username@localhost

identified by 'passwd'

授權命令

對應權限

目標:庫和表

用戶名和客戶端主機

用戶密碼

 

mysql> grant all on kkk.* to www@localhost identified by '123456';

Query OK, 0 rows affected (0.00 sec)

mysql> select user,host from mysql.user where user='www';

+------+-----------+

| user | host      |

+------+-----------+

| www  | localhost |

+------+-----------+

1 row in set (0.01 sec)

3、操作案例1:創建test用戶,對oldboy庫具備所有權限,允許從localhost主機登錄管理數據庫,密碼為123456.

實現上述操作的具體命令為:

grant all privileges on oldboy.* to 'test'@'localhost' identified by '123456';

操作過程如下:

查看當前數據庫用戶情況,然后執行對應命令授權如下:

mysql> grant all privileges on oldboy.* to 'test'@'localhost' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

 

mysql> select user,host from mysql.user where user='test';

+------+-----------+

| user | host      |

+------+-----------+

| test | localhost |

+------+-----------+

1 row in set (0.00 sec)

操作案例2:創建一個權限和root一樣大的system用戶(with grant option是下面命令的重點)。

mysql> show grants for root@localhost;   ###先查看root用戶的權限

+----------------------------------------------------------------------------------------------------------------------------------------+

| Grants for root@localhost                                                                                                              |

+----------------------------------------------------------------------------------------------------------------------------------------+

| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*FE28814B4A8B3309DAC6ED7D3237ADED6DA1E515' WITH GRANT OPTION |

| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION                                                                           |

+----------------------------------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

mysql> grant all on *.* to 'system'@'localhost' identified by '123456' with grant option;  ##創建

Query OK, 0 rows affected (0.00 sec)

 

mysql> show grants for system@localhost;

+------------------------------------------------------------------------------------------------------------------------------------------+

| Grants for system@localhost                                                                                                              |

+------------------------------------------------------------------------------------------------------------------------------------------+

| GRANT ALL PRIVILEGES ON *.* TO 'system'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' WITH GRANT OPTION |

+------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

8.2.7 創建用戶同時授權

grant all on *.* to oldgirl@'172.16.1.%' identified by 'oldgirl123';

grant all on *.* to oldgirl@'172.16.1.0/255.255.255.0' identified by 'oldgirl123';

flush privileges;

mysql> show grants for oldgirl@'172.16.1.0/255.255.255.0'\G

*************************** 1. row ***************************

Grants for oldgirl@172.16.1.0/255.255.255.0: GRANT ALL PRIVILEGES ON *.* TO 'oldgirl'@'172.16.1.0/255.255.255.0' IDENTIFIED BY PASSWORD '*2CADADD54086D5EB4C9F10E0430084D7F179885C'

1 row in set (0.00 sec)

8.2.8 回收權限

mysql> revoke insert on *.* from oldboy@'localhost';

Query OK, 0 rows affected (0.00 sec)

mysql> show grants for oldboy@'localhost'\G

*************************** 1. row ***************************

Grants for oldboy@localhost: GRANT SELECT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'oldboy'@'localhost' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9'

*************************** 2. row ***************************

Grants for oldboy@localhost: GRANT ALL PRIVILEGES ON `oldboy`.* TO 'oldboy'@'localhost'

2 rows in set (0.00 sec)

 

8.2.9 博客、CMS、bbs等產品的數據庫授權:

對於Web連接數據庫的用戶授權盡量采用最小化原則,但是很多開源軟件都是Web界面安裝,因此,在安裝期間除了select,insert,update,delete4個權限外,有可能還需要create,drop等比較危險的權限,因此需要建庫、建表,因此授權例子如下。

mysql> grant select,insert,update,delete,create,drop on blog.* to blog@'172.16.1.%' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

生成數據庫、表后,可以使用revoke命令收回create、drop授權:

mysql> revoke create,drop on blog.* from blog@'172.16.1.%';

Query OK, 0 rows affected (0.00 sec)

 

mysql> show grants for blog@'172.16.1.%';

+--------------------------------------------------------------------------------------------------------------+

| Grants for blog@172.16.1.%                                                                                   |

+--------------------------------------------------------------------------------------------------------------+

| GRANT USAGE ON *.* TO 'blog'@'172.16.1.%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |

| GRANT SELECT, INSERT, UPDATE, DELETE ON `blog`.* TO 'blog'@'172.16.1.%'                                      |

+--------------------------------------------------------------------------------------------------------------+

2 rows in set (0.00 sec)

8.2.10 生產場景具體授權命令為:

a.主庫授權的命令:

grant select,insert,update,delete on blog.* to 'blog'@'172.16.1.%' identified by '123456';

b.從庫授權用戶的命令:

grant select on blog.* to 'blog'@'172.16.1.%' identified by '123456';

當然從庫除了做select的授權外,還可以加read-only等只讀參數,嚴格控制web用戶寫從庫。

 

8.2.11 授權不規范導致的生產血案

運維人員授權用戶all權限了,導致開發通過該用戶自行改了表結構(字段),最后造成服務處問題,最后黑鍋甩在了運維人員身上。

運維人員排查了半天沒結果,最后對比表結構(把生產數據和備份的數據比對),發現了問題,最后告訴開發,把字段改回去,服務就好了。

啟發:生產場景盡量不要給開發select以為的權限,用於網站的連接賬號不要授權select,insert,delete,update以外的權限,對別人的“仁慈”,就是對自己的崗位和公司最大的背叛。

8.3 DML語句之管理表中的數據

8.3.1 往表中插入數據語法

drop table test;

CREATE TABLE test (

   id int(4) NOT NULL AUTO_INCREMENT,

  name char(20) NOT NULL,

  PRIMARY KEY (id)

) ;

(1)命令語法:

insert into <表名> [(字段名1[,..<字段名n>])] values(值1)[,(值n)]

(2)新建一個簡單的測試表test,語句如下:

mysql> use oldboy

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> CREATE TABLE test (

    ->    id int(4) NOT NULL AUTO_INCREMENT,

    ->   name char(20) NOT NULL,

    ->   PRIMARY KEY (id)

    -> ) ;

Query OK, 0 rows affected (0.32 sec)

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

2 rows in set (0.00 sec)

 

8.3.2 往表中插入數據的不同的語法例子:

8.3.2.1  按規矩指定所有列名,並且每列都插入值

mysql> insert into test(id,name) values(1,'oldboy');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

+----+--------+

| id | name   |

+----+--------+

|  1 | oldboy |

+----+--------+

1 row in set (0.00 sec)

8.3.2.2  由於id列為自增的,所以,可以只在name列插入值

mysql> insert into test(name) values('oldgirl');

Query OK, 1 row affected (0.00 sec)

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

+----+---------+

2 rows in set (0.00 sec)

 

在建表的時候就確認了

#查看表結構

mysql> 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    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

8.3.2.3  如果不指定列,就要按規矩為每列都插入恰當的值。

mysql> insert into test values(3,'oldboy');

Query OK, 1 row affected (0.05 sec)

 

mysql> select * from test;

+----+--------+

| id | name   |

+----+--------+

|  1 | linjie |

|  2 | oldboy |

|  3 | oldboy |

+----+--------+

3 rows in set (0.00 sec)

8.3.2.4  批量插入數據的方法:

mysql> insert into test values(4,'linjie'),(5,'lanyezi');

Query OK, 2 rows affected (0.00 sec)

Records: 2  Duplicates: 0  Warnings: 0

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | linjie  |

|  2 | oldboy  |

|  3 | oldboy  |

|  4 | linjie  |

|  5 | lanyezi |

+----+---------+

5 rows in set (0.00 sec)

8.3.2.5  插入全部數據

mysql> delete from test;

Query OK, 5 rows affected (0.07 sec)

 

mysql> select * from test;

Empty set (0.00 sec)

 

mysql> insert into test values(1,'oldboy'),(2,'oldgirl'),(3,'inca'),(4,'zuma'),(5,'kaka');

Query OK, 5 rows affected (0.01 sec)

Records: 5  Duplicates: 0  Warnings: 0

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

5 rows in set (0.00 sec)

8.3.2.6  測試完畢,退出數據庫,然后備份上述數據,留着備用。

[root@db02 ~]# mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock -B oldboy >/opt/oldboy.sql

Warning: Using a password on the command line interface can be insecure.

[root@db02 ~]# ll /opt/oldboy.sql

-rw-r--r--. 1 root root 2051 2017-06-21 14:58 /opt/oldboy.sql

[root@db02 ~]# egrep -v '#|\/|^$|--' /opt/oldboy.sql

USE `oldboy`;

DROP TABLE IF EXISTS `test`;

CREATE TABLE `test` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

LOCK TABLES `test` WRITE;

INSERT INTO `test` VALUES (1,'oldboy'),(2,'oldgirl'),(3,'inca'),(4,'zuma'),(5,'kaka');

UNLOCK TABLES;

 

 

 

 

 

 

 

 

 

 

 

 

 

mysql> alter table student change id id int primary key auto_increment;  添加主鍵

 

 

 

 

 

 

 

 

 

 

 

unique 唯一的 獨一無二的。

8.3.3 修改表中的數據

8.3.3.1  修改表中的數據

update test set id=6 where name='kaka';

mysql> update test set name='bingbing' where id=3;

Query OK, 1 row affected (0.12 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

mysql> select * from test;

+----+----------+

| id | name     |

+----+----------+

|  1 | linjie   |

|  2 | oldboy   |

|  3 | bingbing |

|  4 | linjie   |

|  5 | lanyezi  |

+----+----------+

5 rows in set (0.00 sec)

8.3.3.2  不指定條件誤操作

mysql> update test set name='linjie';

Query OK, 5 rows affected (0.15 sec)

Rows matched: 5  Changed: 5  Warnings: 0

 

mysql> select * from test;

+----+--------+

| id | name   |

+----+--------+

|  1 | linjie |

|  2 | linjie |

|  3 | linjie |

|  4 | linjie |

|  6 | linjie |

+----+--------+

5 rows in set (0.01 sec)

-U禁止update操作

防止不加條件誤刪

[root@db02 ~]# mysql -U

mysql> update test set name='xiaoting';

ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

mysql>

至於防止誤操作導致上述數據庫故障案例的方法之一,請讀者到老男孩的博客http://oldboy.blog.51cto.com/2561410/1321061索引列的創建及生效條件

8.3.4 查詢表中的數據

8.3.4.1  命令語法:

select<字段1,字段2,...> from <表名> where <表達式>

其中,select、from、where是不能隨便改的,是關鍵字,支持大小寫。

 

mysql> select user,host from mysql.user;

+------+-----------+

| user | host      |

+------+-----------+

| root | 127.0.0.1 |

| root | ::1       |

|      | db02      |

| root | db02      |

|      | localhost |

| root | localhost |

+------+-----------+

6 rows in set (0.00 sec)

8.3.4.2  查看表test中所有數據

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  1 | oldboy  |

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

5 rows in set (0.00 sec)

8.3.4.3  倒敘查詢

mysql> select * from test where id>1 order by id desc;

+----+---------+

| id | name    |

+----+---------+

|  5 | kaka    |

|  4 | zuma    |

|  3 | inca    |

|  2 | oldgirl |

+----+---------+

4 rows in set (0.12 sec)

8.3.4.4  升序查詢

mysql> select * from test where id>1 order by id asc;

+----+---------+

| id | name    |

+----+---------+

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

4 rows in set (0.00 sec)

8.3.5 刪除表中的數據

8.3.5.1  命令語法:

delete from 表名 where 表達式

8.3.5.2  刪除表test中編號為1 的記錄。

mysql> delete from test where id=1;

Query OK, 1 row affected (0.00 sec)

 

mysql> delete from test where name='oldboy';

Query OK, 0 rows affected (0.00 sec)

 

mysql> select * from test;

+----+---------+

| id | name    |

+----+---------+

|  2 | oldgirl |

|  3 | inca    |

|  4 | zuma    |

|  5 | kaka    |

+----+---------+

4 rows in set (0.00 sec)

8.3.5.3  通過update偽刪除數據(企業案例)

mysql> alter table test add state tinyint(2) not null default 1;

Query OK, 0 rows affected (0.46 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+------------+------+-----+---------+----------------+

| Field | Type       | Null | Key | Default | Extra          |

+-------+------------+------+-----+---------+----------------+

| id    | int(4)     | NO   | PRI | NULL    | auto_increment |

| name  | char(20)   | NO   |     | NULL    |                |

| state | tinyint(2) | NO   |     | 1       |                |

+-------+------------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

程序顯示內容時,使用下面的語句。

mysql> select * from test where state=1;

+----+---------+-------+

| id | name    | state |

+----+---------+-------+

|  2 | oldgirl |     1 |

|  3 | inca    |     1 |

|  4 | zuma    |     1 |

|  5 | kaka    |     1 |

|  6 | linjie  |     1 |

+----+---------+-------+

5 rows in set (0.29 sec)

此時,如果要刪除數據,就可以用update替代delete實現邏輯刪除,現在闡述oldgirl所在的行。

mysql> update test set state=0 where name='oldgirl';

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

 

mysql> select * from test where state=1;

+----+------+-------+

| id | name | state |

+----+------+-------+

|  3 | inca |     1 |

|  4 | zuma |     1 |

|  5 | kaka |     1 |

+----+------+-------+

3 rows in set (0.00 sec)

提示:

網頁正常顯示的數據SQL語句為:select * from test where state=1;

刪除上述oldgirl的記錄的語句為:update test set state=0 where name='oldgirl';

因此實際上數據並未真的刪除,而是顯示狀態變為0了。

8.3.6 清空表中的數據

1、  命令語法:truncate table 表名;

2、  刪除實踐、

mysql> select * from test where state=1;

+----+--------+-------+

| id | name   | state |

+----+--------+-------+

|  3 | inca   |     1 |

|  4 | zuma   |     1 |

|  5 | kaka   |     1 |

|  6 | linjie |     1 |

+----+--------+-------+

4 rows in set (0.00 sec)

 

mysql> truncate table test;

Query OK, 0 rows affected (0.33 sec)

 

mysql> select * from test where state=1;

Empty set (0.00 sec)

3、truncate和delete區別

truncate table test;速度更快。直接清空對應數據的物理文件。

delete from test;速度慢,邏輯清除,按行刪。

8.3.7 相關名詞注釋

權限

說明

SELECT

查詢(數據)

INSERT

插入(數據)

UPDATE

修改(數據)

DELETE

刪除(數據)

CREATE

創建(數據庫、表等對象)

DROP

刪除(數據庫、表等對象)

RELOAD

重載

SHUTDOWN

關閉

PROCESS

進程

FILE

文件

REFERENCES

參考資料

INDEX

索引

ALTER

修改(數據庫、表等對象)

SHOW DATABASES

查看數據庫

SUPER

超級權限

CREATE TEMPORARY TABLES

創建臨時表

LOCK TABLES

鎖表

EXECUTE

執行

REPLICATION SLAVE

從復制權限

REPLICATION CLIENT

從客戶端復制

CREATE VIEW

創建視圖

SHOW VIEW

查看視圖

CREATE ROUTINE

創建存儲過程

ALTER ROUTINE

修改存儲過程

CREATE USER

創建用戶

EVENT

事件

TRIGGER

觸發器

CREATE TABLESPACE

創建表空間

 

 

 

 

 

 

 

 

第9章 表操作

    MySQL數據庫中的表和Word,Excel里的表格是一模一樣的。

 

 

9.1 建表的基本語法

(1)語法

create table <表名>(

<字段名1><類型1>,

...

create table<表名>(

<字段名n><類型n>;

提示:其中create table是關鍵字,不能更改,但是大小寫可以變化。

(2)建表語句:

create table student(

id int(4) not null,

name char(20) not null,

age tinyint(2)  NOT NULL default '0',

dept varchar(16)  default NULL

);

上述語句表示創建一個student表,有4個字段:

create table student(                 #CREATE TABLE是創建表的固定關鍵字,student為表名

id int(4) not null,                   #學號列,數字類型,長度為4,不為空值

name char(20) not null,               #名字列,定長字符類型,長度20,不為空值

age tinyint(2)  NOT NULL default '0', #年齡列,很小的數字類型,長度為2,不為空,默認為0值

dept varchar(16)  default NULL        #系別列,變長字符類型,長度16,默認為空

) ENGINE=InnoDB DEFAULT CHARSET=UTF8; #引擎和字符集,引擎默認為innodb,字符集,繼承庫的utf8

(3)student表的直觀顯示,可以用下表表示:字段下面的5行為表的5條記錄。

 

9.1.1 字段類型表的對應列的內容的類型

列類型

說明

TINYINT

微小整數類型,可存儲的容量為1字節

INT

整數類型,可以存儲容量為4字節(4294967296)

CHAR(M)

定長字符串類型,當存儲時,總是用空格填滿右邊到指定的長度。最大可存儲1<=M字節<=255

VARCHAR(M)

變長字符串類型,最大可存儲1<=M字節<=255

DATE

日期類型,支持的范圍是1000-01-01到9999-12-31,MySQL以YYYY-MM-DD格式來顯示DATE值,但是允許你使用字符串或數字把值賦給DATE列。

DOUBLE[(M,D)] [ZEROFILL]

正常大小(雙精密)浮點數字類型

BLOB TEXT

最大長度為65535(2^16-1)個字符。

 

9.1.2 CHAR和VARCHAR之間的差別:

CHAR(4)

存儲需求

VARCHAR(4)

存儲需求

''

'       '

4個字節

''

1個字節

'ab'

'ab    '

4個字節

'ab'

3個字節

'abcd'

'abcd'

4個字節

'abcd'

5個字節

'avcdefgh'

'abcd'

4個字節

'abcd'

5個字節

例如,VARCHAR(10)列可以容納最大長度為10的字符串。實際存儲需求是字符串(L)的長度,加上一個記錄字符串長度的字節。對應字符串'abcd',L是4,存儲需要5個字節。

 

CHAR和VARCHAR差別小結:

1、char類型是定長,不夠的在右邊用空格補全,浪費存儲空間,以此列為查詢條件時,速度更快,多數系統表的字段都是定長。

2、varchar類型是變長,省存儲空間,以此列為查詢條件時速度會慢。

 

9.2 創建一個表

use oldboy

create table student(               

id int(4) not null,                 

name char(20) not null,             

age tinyint(2)  NOT NULL default '0',

dept varchar(16)  default NULL      

) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

mysql> 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    |       |

+-------+-------------+------+-----+---------+-------+

4 rows in set (0.00 sec)

 

9.3 更改表名

9.3.1 采用rename命令更改表名

命令語法:rename table 原表名 to 新表名;

把student表名改為test

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

+------------------+

1 row in set (0.00 sec)

 

mysql> rename table student to test;

Query OK, 0 rows affected (0.32 sec)

 

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| test             |

+------------------+

1 row in set (0.00 sec)

9.3.2 通過alter命令改表名

把test表名改回student

mysql> alter table test rename to student;

Query OK, 0 rows affected (0.02 sec)

 

mysql> show tables;

+------------------+

| Tables_in_oldboy |

+------------------+

| student          |

+------------------+

1 row in set (0.00 sec)

9.4 增刪改表的字段

9.4.1 添加字段

命令語法:alter table 表名 add 字段 類型 其他;

a.測試表數據

#測試環境

CREATE TABLE `test` (

  `id` int(4) NOT NULL AUTO_INCREMENT,

  `name` char(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

 

mysql> use kkk

mysql> CREATE TABLE `test` (

    ->   `id` int(4) NOT NULL AUTO_INCREMENT,

    ->   `name` char(20) NOT NULL,

    ->   PRIMARY KEY (`id`)

    -> ) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

Query OK, 0 rows affected (0.30 sec)

 

mysql> show tables;

+---------------+

| Tables_in_kkk |

+---------------+

| test          |

+---------------+

1 row in set (0.00 sec)

###查看表結構

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

2 rows in set (0.00 sec)

 

b.實踐案例

在表test中添加字段sex,age,qq類型分別為char(4),int(4),varchar(15)。

 

mysql> alter table test add sex char(4);

Query OK, 0 rows affected (0.35 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

 

mysql> alter table test add age int(4) after name;

Query OK, 0 rows affected (0.03 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| age   | int(4)   | YES  |     | NULL    |                |

 

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> alter table test add qq varchar(15) first;

Query OK, 0 rows affected (0.03 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| qq    | varchar(15) | YES  |     | NULL    |                |

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   |     | NULL    |                |

| age   | int(4)      | YES  |     | NULL    |                |

| sex   | char(4)     | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

5 rows in set (0.00 sec)

 

9.4.2 刪除字段

mysql> alter table test drop qq;

Query OK, 0 rows affected (0.72 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| age   | int(4)   | YES  |     | NULL    |                |

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> alter table test drop age;

Query OK, 0 rows affected (0.07 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(4)   | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | NO   |     | NULL    |                |

| sex   | char(4)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

9.4.3 修改字段名稱

mysql> alter table test add age int(4) after name;

Query OK, 0 rows affected (0.10 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> alter table test change age oldboyage char(4) after name;

Query OK, 0 rows affected (0.10 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc test;

+-----------+----------+------+-----+---------+----------------+

| Field     | Type     | Null | Key | Default | Extra          |

+-----------+----------+------+-----+---------+----------------+

| id        | int(4)   | NO   | PRI | NULL    | auto_increment |

| name      | char(20) | NO   |     | NULL    |                |

| oldboyage | char(4)  | YES  |     | NULL    |                |

| sex       | char(4)  | YES  |     | NULL    |                |

+-----------+----------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

9.4.4 企業里更改表的流程:開發人員寫出SQL語句,發給運維或DBA檢驗並執行!

提示:工作中添加字段需求來自開發,運維或DBA拿着開發給的語句執行。

對數據庫表的修改,盡量在代碼上線的時候或者業務的低谷,不要再流量高峰期處理大表的更改。

     下班的時候盡量不要單人獨自生產線上改東西。

9.5 面試題授權:##MySQL數據庫授權oldboy用戶管理bbs庫的所有表,172.16.1.0整個網段訪問,密碼是123456,請給出詳細#命令(不低於2種方法:)

mysql> create database bbs;

Query OK, 1 row affected (0.00 sec)

 

mysql> grant all on bbs.* to oldboy@'172.16.1.0/255.255.255.0' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

9.6 mysql表的字段類型

 

以索引列為查詢條件時可以加快查詢數據的速度

9.7 為表的字段創建索引

數據庫的索引就像書的目錄一樣,如果在字段上建立了索引,那么以索引列為查詢條件時可以加快查詢數據的速度,這是MySQL優化的重要內容之一。

9.7.1 創建主鍵索引

查詢數據庫,按主鍵查詢是最快的,每個表只能有一個主鍵列,但是可以有很多個普通索引列。主鍵列要求列的所有內容必須唯一,而普通索引列不要求內容必須唯一。

主鍵就類似我們在學校學習時的學號一樣,班級內是唯一的,整個表的每一條記錄的主鍵值在表內都是唯一的,用來唯一標識一條記錄。那么,我們該如何建立主鍵索引和普通索引呢?

首先,無論建立主鍵索引還是普通索引,都要在表的對應列上創建,可以對單列創建索引,也可以對多列創建索引!

建立主鍵索引的方法:

1、在建表時,可以增加建立主鍵索引的語句如下

drop table student;

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),

KEY index_name(name)

);

提示:

1、primary key(id)   ←主鍵

2、KEY index_name(name) ←name字段普通索引

優化:在唯一值多的列上建索引查詢效率高。

mysql> show create table student\G   #查看建表語句

*************************** 1. row ***************************

       Table: student

Create Table: 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`),

  KEY `index_name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

 

2、建表后通過alter命令增加主鍵索引(不要這樣干)

mysql> alter table student drop primary key;

ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

##如果建表時沒有增加AUTO_INCREMENT,就可以刪掉(id自增的不能刪除)。

 

去掉AUTO_INCREMENT,再創建一張表

mysql> drop table student;

Query OK, 0 rows affected (0.01 sec)

 

mysql> create table student(

    -> id int(4) not null,

    -> name char(20) not null,

    -> age tinyint(2)  NOT NULL default '0',

    -> dept varchar(16)  default NULL,

    -> primary key(id),

    -> KEY index_name(name)

    -> );

Query OK, 0 rows affected (0.09 sec)

 

mysql> alter table student drop primary key;

Query OK, 0 rows affected (0.07 sec)

Records: 0  Duplicates: 0  Warnings: 0

#利用alter命令修改id列主鍵自增

mysql> alter table student change id id int primary key auto_increment;

Query OK, 0 rows affected (0.09 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(11)     | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | MUL | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

提示:只有int類型且為primary key 才可以使用auto_increment。

 

9.7.2 創建普通索引

1、在建表時,可以增加建立普通索引的語句如下

drop table student;

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),

KEY index_name(name)

);

###查看有沒有索引

mysql> 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    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

####查看索引

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

2 rows in set (0.00 sec)

 

2、建表后利用alter增加普通索引

刪除建表時創建的index_name索引

mysql> alter table student drop index index_name;

Query OK, 0 rows affected (0.30 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   |     | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

1 row in set (0.00 sec)

 

在name列上添加索引,索引名為index_name,

mysql> alter table student add index index_name(name);

Query OK, 0 rows affected (0.06 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> 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    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

2 rows in set (0.00 sec)

提示:PRI為主鍵的標識,MUL為普通索引的標識。

 

生產場景:數據量很大的時候,不適合建立索引,會影響用戶訪問。曾經400-500萬條記錄的表,建立索引,花了90-180秒。

盡量選擇在業務低谷時建立索引。

 

9.7.3 對字段的前n個字符創建普通索引

當遇到表中比較大的列時,列內容的前n個字符在所有內容中已經接近唯一時,這時可以對列的前n個字符建立索引,而無需對整個列建立索引,這樣可以節省創建索引占用的系統空間,以及降低讀取和更新維護索引消耗的系統資源。

對字段的前n個字符創建普通索引的語法:

create index index_name on test(name(8));←條件列前n個字符創建索引

操作實際:

在dept系別列上,前8個字符創建索引

mysql> create index index_dept on student(dept(8));

Query OK, 0 rows affected (0.04 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 3. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_dept

 Seq_in_index: 1

  Column_name: dept

    Collation: A

  Cardinality: 0

     Sub_part: 8

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

3 rows in set (0.00 sec)

###alter table student add index index_dept((dept(8)));與上面語句等價

 

9.7.4 為表的多個字段創建聯合索引

如果查詢數據的條件是多列時,我們可以為多個查詢的列創建聯合索引,什么,可以為多列的前n個字符列創建聯合索引,實踐演示如下:

##刪除之前創建的索引

mysql> alter table student drop index index_name;

Query OK, 0 rows affected (0.06 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> alter table student drop index index_dept;

Query OK, 0 rows affected (0.04 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   |     | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

mysql> create index index_name_dept on student(name,dept);

Query OK, 0 rows affected (0.37 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> 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    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 3. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 2

  Column_name: dept

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

3 rows in set (0.00 sec)

 

###對多列前n個字符創建聯合索引

mysql> alter table student drop index index_name_dept;

Query OK, 0 rows affected (0.08 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> create index index_name_dept on student(name(8),dept(10));

Query OK, 0 rows affected (0.32 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> 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    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

mysql> show index from student\G

*************************** 1. row ***************************

        Table: student

   Non_unique: 0

     Key_name: PRIMARY

 Seq_in_index: 1

  Column_name: id

    Collation: A

  Cardinality: 0

     Sub_part: NULL

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 2. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 1

  Column_name: name

    Collation: A

  Cardinality: 0

     Sub_part: 8

       Packed: NULL

         Null:

   Index_type: BTREE

      Comment:

Index_comment:

*************************** 3. row ***************************

        Table: student

   Non_unique: 1

     Key_name: index_name_dept

 Seq_in_index: 2

  Column_name: dept

    Collation: A

  Cardinality: 0

     Sub_part: 10

       Packed: NULL

         Null: YES

   Index_type: BTREE

      Comment:

Index_comment:

3 rows in set (0.00 sec)

生產案例:

建表語句加入聯合索引:某sns產品生產正式建表語句

use sns;

set names gbk;

CREATE TABLE `subject_comment_manager` (

  `subject_comment_manager_id` bigint(12) NOT NULL auto_increment COMMENT '主鍵',

  `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)),

  KEY `IDX_SUBJECT_TITLE` (`subject_title`(32))

  KEY `index_nick_type` (`edit_user_nick`(32),`subject_type`)#<==聯合索引,此行為新加的,用於給大家講解的。實際表語句內沒有此行。

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

提示:盡量在唯一值多的大表建立索引。

按條件查詢數據時,聯合索引是有前綴生效特性的。

index(a,b,c)僅a,ab,abc三個查詢條件可以走索引。b,ba,ac,c等無法使用索引了,盡量把最常用作為查詢條件的列,放在第一的位置。

也可以創建多列聯合主鍵

PRIMARY KEY (`Host`,`User`)

 

9.7.5 創建唯一索引(非主鍵)

mysql> create unique index uni_ind_name on student(name);

Query OK, 0 rows affected (0.34 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> desc student;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(4)      | NO   | PRI | NULL    | auto_increment |

| name  | char(20)    | NO   | UNI | NULL    |                |

| age   | tinyint(2)  | NO   |     | 0       |                |

| dept  | varchar(16) | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.00 sec)

 

9.7.6 索引列的創建及生效條件

問題1:既然索引可以加快查詢速度,那么就給所有的列建索引吧?

解答:因為索引不但占用系統空間,而且更新數據時還需要維護索引數據的,因此,索引是一把雙刃劍,並不是越多越好,例如:數十到幾百行的小表上無需建立索引,插入更新頻繁,讀取比較少的表要少建立索引。

問題2、要在哪些列上創建索引才能加快查詢速度呢?

解答:select user,host from mysql.user where password=...,索引一定要創建在where 后的條件列上,而不是select后的選擇數據的列上。另外,我們要盡量選擇在唯一值的大表上的列建立索引,例如,男女性別列唯一值少,不適合建立索引。

查看表的唯一值數量:

select count(distinct user) from mysql.user;

select count(distinct user,host) from mysql.user;

 

9.7.7 創建索引命令集合小結

1、創建索引相關命令集合

創建主鍵索引

mysql> alter table student change id id int primary key auto_increment;

刪除主鍵索引(主鍵列不能自增,否則刪不掉):

mysql> alter table student drop primary key;

創建普通索引

mysql> alter table student add index index_dept(dept);

根據列的前n個字符創建索引

mysql> create index index_dept on student(dept(8));

根據多個列創建聯合索引

mysql> create index index_name_dept on student(name,dept);

根據多個列的前n個字符創建聯合索引

mysql> create index index_name_dept on student(name(8),dept(10));

創建唯一索引

mysql> create unique index uni_ind_name on student(name);

刪除普通索引與唯一索引

mysql> alter table student drop index index_dept;

mysql> drop index index_dept on student;

查看唯一值的數量

mysql> select count(distinct user) from mysql.user;

9.7.8 創建索引的基本知識小結:

1、索引類似書籍的目錄,會加快查詢數據的速度。

2、要在表的列(字段)上創建索引。

3、索引會加快查詢速度,但是也會會影響更新的速度,因為更新要維護索引數據。

4、索引列並不是越多越好,要在頻繁查詢的表語句where后的條件列上創建索引。

5、小表或重復值很多的列上可以不建索引,要在大表以及重復值少的條件列上創建索引。

6、多個列聯合索引有前綴生效特性。

7、當字段內容前N個字符己經接近唯一時,可以對字段的前N個字符創建索引。

8、索引從工作方式區分,有主鍵,唯一,普通索引。

9、索引類型會有BTREE (默認)和hash適合做緩存(內存數據庫)等。

http://blog.csdn.net/dyllove98/article/details/9631303

10、索引一般創建用於where關鍵字后面的列上,group by,order by,join in.

select user,host from mysql.user where id=110;

 

9.8 SQL語句優化

 

 

 

CPU,I/O是不是高,高的話基本就是SQL語句的問題

 

 

 

 

等號容易走索引。

范圍查詢不愛走索引。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM