1. 程式人生 > >mysql資料庫深入學習

mysql資料庫深入學習

mysql 資料庫

一、資料庫介紹

1、關係型資料庫的特點

​ 二維表
典型產品Oracle傳統企業,MySQL是網際網路企業
資料存取是通過SQL
最大特點,資料安全性方面強(ACID)

2、NoSQL:非關係型資料庫(Not only SQL)

​ 不是否定關係型資料庫,做關係型資料庫的的補充。

3、web1.0時代

​ 企業提供內容,使用者瀏覽,所以關係型資料庫夠用,併發並不高,所以不需要NoSQL。

4、web2.0時代

​ 核心是企業提供平臺,使用者參與提供內容。這時關係型資料庫無法滿足需求了。

5、2003 NoSQL出現

​ memcached誕生,關注的點是效能,而安全性關注比較低。隨著安全性需求不斷提升,所以有了redis。

6、redis特點

​ 依然高效能該併發,

​ 資料持久化的功能

​ 支援多資料型別,主從複製和叢集

​ 管理不再使用SQL了

7、NoSQL特性總覽:

​ 不是否定關係型資料庫,而是作為補充,現在也有部分替代的趨勢。

​ 關注高效能,高併發,靈活性,忽略和上述無關的功能。

​ 現在也在提升安全性和使用功能。

​ 典型產品:Redis(持久化快取,兩個半天)、MongoDB(最接近關係型資料的NoSQL)、Memcached。

​ 管理不適用SQL管理,而是用一些特殊的API或資料介面。

8、NoSQL的分類、特點、典型產品

​ 鍵值(KV)儲存:Memcached、Redis;

​ 列儲存(column-oriented):HBASE(新浪,360)、Cassandra(200臺伺服器叢集)

​ 文件資料庫(document-oriented):MongoDB(最接近關係型資料庫的NoSQL)

​ 圖形儲存(Graph):Neo4j。

9、mysql發展史

1979年,報表工具Unireg出現。
1985 年,以瑞典David Axmark為首,成立了一家公司(AB前身),IASM引擎出現。
1990年,提供SQL支援。
1999-2000年,MySQLAB公司成立,並公佈原始碼,開源化。
2000年4月BDB引擎出現,支援事務。
2008年1月16號MySQL被Sun公司收購。
2009年04月20日Oracle收購Sun公司,MySQL轉入Oracle 門下。

10、mysql特點

開源
社群版免費
簡單,使用方便,可靠
穩定、安全
社群活躍

二、mysql安裝及啟動

1、mysql安裝方式介紹

1.RPM、Yum:安裝方便、安裝速度快,無法定製
2.二進位制:不需要安裝,解壓即可使用,不能定製功能
3.編譯安裝:可定製,安裝慢。
5.5之前:./configure make make install
5.5之後:cmakegmake
4.先編譯,然後製作rpm,製作yum庫,然後yum安裝。
簡單、速度快、可定製,比較複雜製作時間長
企業選擇安裝方式
中小企業:以上方式都可以,運維偏向編譯,dba偏向選擇二進位制。
大型企業:可以選擇4

2、mysql安裝

一、MySQL5.6.36安裝前準備
(1)克隆一個模板機器(使用centos6),克隆完做快照
(2)IP 10.0.0.52 主機名db02
(3)iptables   selinux (關閉)
(4)下載好5.6.36
(5)安裝依賴包
     yum  install  -y  ncurses-devel libaio-devel
(6)安裝cmake
	yum install cmake –y
(7)建立使用者
    useradd -s /sbin/nologin -M mysql
	id mysql
二、MySQL下載安裝
(0)建立軟體下載目錄:
mkdir -p /server/tools
cd /server/tools/
(1)下載並上傳到/server/tools
https://www.mysql.com/downloads/
社群版MySQL Community Server
(2)解壓:
cd /server/tools
tar xf mysql-5.6.36.tar.gz
(3)安裝:
cd mysql-5.6.36
cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.36 \
-DMYSQL_DATADIR=/application/mysql-5.6.36/data \
-DMYSQL_UNIX_ADDR=/application/mysql-5.6.36/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

make && make install

三、配置並啟動
(1)製作軟連線:
[root@centos6-kvm3 mysql-5.6.36]# ln -s /application/mysql-5.6.36/ /application/mysql
(2)拷貝配置檔案到/etc:
[root@centos6-kvm3 support-files]# cp my-default.cnf /etc/my.cnf 
(3)初始化資料庫:
[root@centos6-kvm3 support-files]# /application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/application/mysql/data --user=mysql
(4)建立關鍵目錄並設定許可權:
[root@centos6-kvm3 support-files]# mkdir -p /application/mysql/tmp
[root@centos6-kvm3 support-files]# chown -R mysql.mysql /application/mysql/
(5)複製啟動指令碼到/etc/init.d/mysqld
[root@centos6-kvm3 support-files]# cp mysql.server /etc/init.d/mysqld 
(6)啟動資料庫
[root@centos6-kvm3 support-files]# /etc/init.d/mysqld start
[root@centos6-kvm3 support-files]# ps -ef | grep mysql
[root@centos6-kvm3 support-files]# netstat -lntp | grep 3306
(7)配置環境變數
[root@centos6-kvm3 support-files]# echo 'PATH=/application/mysql/bin/:$PATH'>>/etc/profile
[root@centos6-kvm3 support-files]# tail /etc/profile
[root@centos6-kvm3 support-files]# source /etc/profile
[root@centos6-kvm3 support-files]# echo $PATH
/application/mysql/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos6-kvm3 support-files]# mysql
mysql> select user,host,password from mysql.user;

3、客戶端程式連線到MySQL方式

通過網路連線串
mysql -uroot -poldboy123 -h 10.0.0.200
通過套接字檔案
mysql -uroot -poldboy123 -S /tmp/mysql.sock

4、mysql 的SQL層處理:

SQL:
	1、接收到連線層送過過來的“SQL”
	2、由專門的模組,會判斷SQL語法、語義(SQL語句的型別:DDL、DCL、DML)
	3、將不同型別的語句,送到專門的處理介面(解析器)
	4、解析器,將SQL解析成執行計劃
	5、優化器,會選擇“它”最優的執行計劃交給執行器
	6、執行器,執行 執行計劃,得出如何去“磁碟”獲取資料的方法
	7、專門執行緒將獲取資料的方法,送給下層(儲存引擎層)繼續處理。
	8、驗證授權,當前使用者對 庫或表物件有沒有操作的許可權。
	9、查詢快取記憶體query_cache。
	10、記錄修改操作日誌binlog。
	
mysql 表儲存
1、資料檔案
   頁(預設是16k):是mysql資料庫儲存的最小單元
   區:連續的多個頁組成
   段:一個表(分割槽表)就是一個段,包含了多個區

5、mysql常用命令

mysql 登入命令
-u   使用者名稱
-p   密碼
例子: 
mysql -uroot -poldboy123
-h ip
例子:
[root@centos6-kvm3 support-files]# mysql -uroot -poldboy123 -h 127.0.0.1
[root@centos6-kvm3 support-files]# mysql -uroot -poldboy123 -h localhost
mysql -uroot -poldboy123 -h 10.0.0.52
-P 3308
例子:

mysql -uroot -poldboy123 -h 10.0.0.52 -P 3308
[root@centos6-kvm3 support-files]# mysql -uroot -poldboy123 -P 3306
-S /tmp/mysql.sock
例子:
[root@centos6-kvm3 support-files]# mysql -uroot -poldboy123 -S /application/mysql/tmp/mysql.sock 
mysql -uroot -poldboy123 -S /application/mysql/tmp/mysql.sock
-e "show variables like 'server_id';"
例子:
mysql -uroot -poldboy123  -e "show variables like 'server_id';"
修改密碼:
[root@centos6-kvm3 support-files]# mysqladmin -uroot -p password oldboy123
Enter password: 

6、清理不常用的資料庫

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;

三、mysql的基本管理

1、資料庫關閉啟動

資料庫啟動流程:

關閉:
[root@centos6-kvm3 support-files]# service mysql stop
[root@centos6-kvm3 support-files]# mysqladmin -uroot -poldboy123 shutdown
啟動:
[root@centos6-kvm3 support-files]# service mysqld start
[root@centos6-kvm3 support-files]# /application/mysql/bin/mysqld_safe &
野蠻關閉資料庫方式:
kill -9 ?
第三種為利用系統程序管理命令關閉MySQL。
kill pid#<==這裡的pid為資料庫服務對應的程序號。
killall mysqld#<==這裡的mysqld是資料庫服務對應的程序名字。
pkill mysqld #<==這裡的mysqld是資料庫服務對應的程序名字。

啟動報錯案例:
[root@centos6-kvm3 data]# service mysqld start
Starting MySQL. ERROR! The server quit without updating PID file (/application/mysql-5.6.36/data/centos6-kvm3.pid).

檢視錯誤日誌:
[root@centos6-kvm3 data]# pwd
/application/mysql/data
[root@centos6-kvm3 data]# cat centos6-kvm3.err 
檢視報錯部分:
2020-03-19 00:07:20 23029 [ERROR] /application/mysql-5.6.36/bin/mysqld: Can't find file: './mysql/user.frm' (errno: 13 - Permission denied)

[root@centos6-kvm3 data]#  ll
drwx------ 2 root  root      4096 Mar 18 21:32 mysql
[root@centos6-kvm3 data]# chown -R mysql.mysql mysql

編譯啟動:
[root@centos6-kvm3 data]# mysqld_safe --socket=/tmp/mysql.sock --port=3307 &
[root@centos6-kvm3 data]# mysql -uroot -poldboy123 -S /tmp/mysql.sock 
[root@centos6-kvm3 data]# ps -ef | grep mysql
mysql啟動引數設定:
1、預編譯時候設定引數,引數會硬編碼到程式中。
2、命令列方式設定啟動引數。
3、初始化的配置檔案,/etc/my.cnf
啟動優先順序:2>3>1
影響到什麼?
①影響資料庫的啟動
[mysqld]
[mysqld_safe]
[server]

②影響到資料庫的連結
[mysql]
[mysqladmin]
[mysqldump]
[client]


2、mysql配置檔案

配置檔案案例:
[root@centos6-kvm3 data]# vim /etc/my.cnf 
[mysqld]
basedir=/application/mysql
datadir/application/mysql/data
socket=/application/mysql/tmp/mysql.sock
port=3306
server_id=10
log-error=/var/log/mysql.log #錯誤日誌
log-bin=/application/mysql/data/mysql-bin
binlog_format=row
skip_name_resolve #跳過域名解析
[mysql]
#客戶端
socket=/application/mysql/tmp/mysql.sock
 
[root@centos6-kvm3 data]# service mysqld start
Starting MySQL. SUCCESS! 
[root@centos6-kvm3 data]# ps -ef | grep mysql

自定義配置檔案啟動:
[root@centos6-kvm3 ~]# cat /tmp/aa.txt 
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/application/mysql/tmp/mysql.sock
port=3309
server_id=11
log-error=/var/log/mysql.log
log-bin=/application/mysql/data/mysql-bin
binlog_format=row
skip_name_resolve
[root@centos6-kvm3 data]# mysqld_safe --defaults-file=/tmp/aa.txt
[root@centos6-kvm3 ~]# ps -ef | grep mysql

3、配置mysql多例項

思路:
1、啟動多個mysqld程序
2、規劃多套資料
3、規劃多個埠
4、規劃多套日誌路徑

多例項配置
1、建立多套目錄
mkdir -p /data/330{7,8,9}
2、準備多套配置檔案
vi /data/3307/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/3307
server-id=3307
port=3307
log-bin=/data/3307/mysql-bin
socket=/data/3307/mysql.sock
log-error=/data/3307/mysql.log

vi /data/3308/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/3308
server-id=3308
port=3308
log-bin=/data/3308/mysql-bin
socket=/data/3308/mysql.sock
log-error=/data/3308/mysql.log

vi /data/3309/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/data/3309
server-id=3309
port=3309
log-bin=/data/3309/mysql-bin
socket=/data/3309/mysql.sock
log-error=/data/3309/mysql.log
3、初始化多套資料
/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/data/3307 --user=mysql
/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/data/3308 --user=mysql
/application/mysql/scripts/mysql_install_db --basedir=/application/mysql/ --datadir=/data/3309 --user=mysql
4、啟動多個例項
mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &
5、檢視啟動埠
netstat -lnp |grep 330
6、分別連線測試
mysql -S /data/3307/mysql.sock -e "show variables like 'server_id';"
mysql -S /data/3308/mysql.sock -e "show variables like 'server_id';"
mysql -S /data/3309/mysql.sock -e "show variables like 'server_id';"

如果出現閃退,檢查是否埠已經被使用:需要關閉在用的埠
mysqladmin -uroot -poldboy123 -S /tmp/mysql.sock shutdown

四、資料庫使用者管理

1、使用者定義

使用者定義:
mysql> select user,host,password from mysql.user;
+------+--------------+-------------------------------------------+
| user | host         | password   

==================================

user                     主機範圍
使用某個使用者              從哪些主機地址可以訪問我的資料庫

使用者的功能:
1、用來登入mysql資料庫
2、用來管理資料庫物件(庫,表)

許可權:
	功能:針對不同的使用者,設定不同的物件管理能力。
    select updata delete insert creat ...
許可權的範圍:
*.*  :全域性範圍
oldboy.* :單庫級別
oldboy.t1 :單表級別
建立使用者並授權:
grant 	all  on  wordpress.* to workpress@'10.0.0.%' identified by 'oldboy123';
授權命令 許可權     許可權範圍		用於		主機範圍 				密碼

修改超級管理員使用者:root
修改密碼:mysqladmin -uroot -p password oldboy123
root@localhost
普通使用者:select,updata,delete,insert,create,drop (增刪改查)

只針對使用者的操作命令:
mysql> create user zabbix@'10.0.0.%' identified by 'oldboy123';
Query OK, 0 rows affected (0.01 sec)
mysql> drop user root@'127.0.0.1';
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host,password from mysql.user;
特殊的刪除方法:
mysql> delete from mysql.user where user='oldboy' and host='localhost'; 
Query OK, 1 row affected (0.00 sec)
mysql> flush privileges;

2、使用者授權

grant 	all  on  wordpress.* to workpress@'10.0.0.%' identified by 'oldboy123';
授權命令 許可權     許可權範圍		用於		主機範圍 

all許可權:
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

開發使用者許可權:(root使用者進行授權)
	grant SELECT,INSERT, UPDATE, DELETE, CREATE, DROP on testdb.* to zabbix@'10.0.0.%';
使用zabbix檢查:
mysql> create database testdb;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
建立使用者並授權:
mysql> grant all on *.* to root@'10.0.0.%' identified by 'oldboy123';
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host,password from mysql.user;
查詢使用者的許可權:
mysql> show grants for zabbix@'10.0.0.%';
建立類似管理員:
mysql> show grants for root@'10.0.0.%';
本地超級管理員:有grants許可權
mysql> show grants for root@'localhost';
收回許可權:
mysql> revoke create,drop  on testdb.* from zabbix@'10.0.0.%';
mysql> show grants for zabbix@'10.0.0.%';

思考:
grant select on *.* to zabbix@'10.0.0.%';
grant INSERT, UPDATE, DELETE, CREATE, DROP on testdb.* to zabbix@'10.0.0.%';
grant update on testdb.t1 to zabbix@'10.0.0.%';

###
mysql> use testdb;
mysql> create table t1(id int);
mysql> show tables;
mysql> insert into t1 values(1);

問:zabbix@'10.0.0.%' 對t1 表到底有什麼許可權?
如果對某個使用者在不同的資料庫級別設定了許可權,最終許可權許可權疊加,加起來的最大許可權為準。
建議,不要多範圍授權。

五、SELECT高階應用

1、課程大綱

• 開發環境準備
• select語句的基本語法格式
• WHERE子句
• ORDER BY子句
• LIMIT子句
• 多表連線查詢(join、using) • 集合操作(union) • group by與having字句
• 子查詢

2、開發環境

• 匯入world.sql
• 建立使用者,使用sqlyog登入資料庫

3、select語法環境

help select;
SELECT
[ALL | DISTINCT | DISTINCTROW ]
select_expr [, select_expr ...]
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[Asc | DEsc], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[Asc | DEsc], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[FOR UPDATE | LOCK IN SHARE MODE]]

4、WHERE子句

• 基本語法

SELECT *|{[DISTINCT] column|select_expr [alias], ...]}  

[FROM [database.]table] 

[WHERE conditions];  

• WHERE條件又叫做過濾條件,它從FROM子句的中間結果中去掉所有

條件conditions不為TRUE(而為FALSE或者NULL)的行

• WHERE子句跟在FROM子句後面

• 不能在WHERE子句中使用列別名

例1:where字句的基本使用

SELECT * FROM world.`city` WHERE CountryCode='CHN'; 

or 

SELECT * FROM world.`city` WHERE CountryCode='chn'; 

注意:

WHERE中出現的字串和日期字面量必須使用引號括起來

這裡,字串字面量寫成大寫或小寫結果都一樣,即不區分大小寫進行查詢。

這和ORACLE不同,ORACLE中WHERE條件中的字面量是區分大小寫的

例2:where字句中的邏輯操作符:

SELECT * FROM world.`city`  

WHERE CountryCode='chn' AND district = 'anhui'; 

• 邏輯操作符介紹:

– and

邏輯與。只有當所有的子條件都為true時,and才返回true。否則返回false或null

– or

邏輯或。只要有一個子條件為true,or就返回true。否則返回false或null

– not

邏輯非。如果子條件為true,則返回false;如果子條件為false,則返回true

– xor

邏輯異或。當一個子條件為true而另一個子條件為false時,其結果為true;

當兩個條件都為true或都為false時,結果為false。否則,結果為null

例3 :where字句中的範圍比較:

SELECT * FROM world.`city`  

WHERE  

population BETWEEN 100000 AND 200000 ; 

• 例4:where字句中的IN

SELECT * FROM city 

WHERE countrycode IN ('CHN','JPN');

例5:where字句中的like

– 語法:

like ‘匹配模式字串’

– 實現模式匹配查詢或者模糊查詢:

測試一個列值是否匹配給出的模式

– 在‘匹配模式字串’中,可以有兩個具有特殊含義的通配字元:

%:表示0個或者任意多個字元

_:只表示一個任意字元

SELECT * FROM city 

WHERE countrycode LIKE 'ch%'; 

5、ORDER BY子句

• ORDER BY子句用來排序行

• 如果SELECT語句中沒有ORDER BY子句,那麼結果集中行的順序是

不可預料的

• 語法:

SELECT expr 

FROM table 

[WHERE condition(s)] 

[ORDER BY {column, expr, numeric_position} [Asc|DEsc]]; 

• 其中:

– Asc:執行升序排序。預設值

– DEsc:執行降序排序

– ORDER BY子句一般在SELECT語句的最後面

例1: 基本使用

SELECT * FROM city 

ORDER BY population; 

• 例2:多個排序條件

SELECT * FROM city 

ORDER BY population,countrycode; 

• 例3:以select字句列編號排序

SELECT * FROM city 

ORDER BY 5; 按照第5列進行排序。

• 例4:desc asc

SELECT * FROM city 

ORDER BY 5 desc; 

• 例5:NULL值的排序

在MySQL中,把NULL值當做一列值中的最小值對待。因此,升序排序時,它出現在最前面

6、LIMIT子句

MySQL特有的子句。

• 它是SELECT語句中的最後一個子句(在order by後面)。

• 它用來表示從結果集中選取最前面或最後面的幾行。

• 偏移量offset的最小值為0。

• 語法:

limit <獲取的行數> [OFFSET <跳過的行數>]

或者 limit [<跳過的行數>,] <獲取的行數>

SELECT * FROM city 

ORDER BY 5 DEsc 

LIMIT 4; 

注:先按照人口數量進行降序排序,然後使用limit從中挑出最前面的4行。

如果沒有order by子句,返回的4行就是不可預料的。

7、多表連線查詢

傳統的連線寫法(使用where)

SELECT NAME,ci.countrycode ,cl.language ,ci.population 

FROM city ci , countrylanguage cl 

WHERE ci.`CountryCode`=cl.countrycode; 

注意:一旦給表定義了別名,那麼原始的表名就不能在出現在該語句

的其它子句中了

• NATURAL JOIN子句

• 自動到兩張表中查詢所有同名同類型的列拿來做連線列,進行相等 連線

SELECT NAME,countrycode ,LANGUAGE ,population 

FROM city NATURAL JOIN countrylanguage 

WHERE population > 1000000 

ORDER BY population; 

注意:在select子句只能出現一個連線列

使用using子句

SELECT NAME,countrycode ,LANGUAGE ,population 

FROM city JOIN countrylanguage 

USING(countrycode);

8、集合操作

UNION [DISTINCT]
• UNION ALL
• 語法:
SELECT ... 
UNION [ALL | DISTINCT] 
SELECT ... 
[UNION [ALL | DISTINCT] 
SELECT ...]

• UNION用於把兩個或者多個select查詢的結果集合併成一個
• 進行合併的兩個查詢,其SELECT列表必須在數量和對應列的資料型別上保持一致
• 預設會去掉兩個查詢結果集中的重複行
• 預設結果集不排序
• 最終結果集的列名來自於第一個查詢的SELECT列表

9、分組操作及分組處理

“Group By”從字面意義上理解就是根據“By”指定的規則對資料進行分組, 所謂的分組就是將一個“資料集”劃分成若干個“小區域”,然後針對若干個 “小區域”進行資料處理。

• Having與Where的區別

  • where 子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分

組之前過濾資料,where條件中不能包含聚組函式,使用where條件過濾出特定的行。

  • having 子句的作用是篩選滿足條件的組,即在分組之後過濾資料,條件中經常包含聚

組函式,使用having 條件過濾出特定的組,也可以使用多個分組標準進行分組。

11、子查詢

子查詢定義

  • 在一個表表達中可以呼叫另一個表表達式,這個被呼叫的表表達式叫做子查詢( subquery),我麼也稱作子選擇(subselect)或內嵌選擇(inner select)。子查詢 的結果傳遞給呼叫它的表表達式繼續處理。

  • 子查詢(inner query)先執行,然後執行主查詢(outer query)

  • 子查詢按對返回結果集的呼叫方法,可分為:where型子查詢,from型子查詢及exists 型子查詢。

• 使用子查詢原則

  • 一個子查詢必須放在圓括號中。
  • 將子查詢放在比較條件的右邊以增加可讀性。

子查詢不包含 ORDER BY 子句。對一個 SELECT 語句只能用一個 ORDER BY 子句,並且 如果指定了它就必須放在主 SELECT 語句的最後。

  • 在子查詢中可以使用兩種比較條件:單行運算子(>, =, >=, <, <>, <=) 和多行運算子 (IN, ANY, ALL)。

六、mysql資料型別

1、課程大綱

• 資料型別介紹
• 資料型別設定
• 列屬性
• 資料型別的字符集用法
• 選擇適當的資料型別

2、資料型別介紹

• 四種主要類別:

  • 數值型別
  • 字元型別
  • 時間型別
  • 二進位制型別

• 資料型別的 ABC 要素:

  • Appropriate(適當)

  • Brief(簡潔)

  • Complete(完整)

• 例 1:列宣告

CREATE TABLE people ( 

id INT, 

first_name CHAR(30), 

last_name CHAR(30) ); 

• 例 2:不允許負值和未知值

CREATE TABLE people ( 

id INT UNSIGNED NOT NULL, 

first_name CHAR(30), 

last_name CHAR(30) );

3、數值資料型別

• 使用數值資料型別時的注意事項:

  • 資料型別所表示的值的範圍
  • 列值所需的空間量
  • 列精度和範圍(浮點數和定點數)

• 數值資料型別的類:

  • 整數:整數
  • 浮點數:小數
  • 定點數:精確值數值
  • BIT:位欄位值

4、字串資料型別

• 表示給定字符集中的一個字母數字字元序列

• 用於儲存文字或二進位制資料

• 幾乎在每種程式語言中都有實現

• 支援字符集和整理

• 屬於以下其中一類

  • 文字:真實的非結構化字串資料型別
  • 整數:結構化字串型別

5、二進位制字串資料型別

• 位元組序列

  • 二進位制位按八位分組

• 儲存二進位制值,例如:

  • 編譯的計算機程式和應用程式
  • 影象和聲音檔案

• 字元二進位制資料型別的類:

  • 二進位制:固定長度和可變長度的二進位制字串
  • BLOB:二進位制資料的可變長度非結構化集合

6、時間資料型別

7、列屬性

列屬性的類別:

• 數值:適用於數值資料型別(BIT 除外)

• 字串:適用於非二進位制字串資料型別

• 常規:適用於所有資料型別

8、如何選擇資料型別

• 考慮哪些資料型別和字符集可以最大限度地減少儲存和磁碟 I/O。

• 使用固定長度資料型別:

  • 如果儲存的所有字串值的長度相同

• 使用可變長度資料型別:

  • 如果儲存的字串值不同
  • 對於多位元組字符集

• 對於頻繁使用的字元,使用佔用空間較少的多位元組字符集。

  • 使用基本多文種平面 (Basic Multilingual Plane, BMP) 之外的其他 Unicode 字符集。

七、MySQL 客戶端工具及SQL入門

1、課程大綱:

mysql客戶端命令介紹;

mysql獲取幫助的方法細講;

DDL語句之管理資料庫;

DDL語句之管理表與案例介紹;

DML語句之管理表中的資料;

SELECT 檢索資料;

2、mysql介面程式使用及SQL入門

mysql客戶端命令介紹:
• mysql: – 用於資料庫連線管理
- 將 使用者SQL 語句傳送到伺服器
• mysqladmin: – 命令列管理工具
• mysqldump: – 備份資料庫和表的內容

- 用於管理資料庫:
	命令介面自帶命令
	DDL:資料定義語言(create)
	DCL:資料控制語言(grant,revoke)
	DML:資料操作語言(update,delete,insert)
mysql 介面程式:
mysql -uroot -poldboy123 -e "show variables like '%server_id%'"
mysql>:
1,介面自帶的功能
mysql命令:
1.\h或help 或?
顯示介面命令幫助命令。
2.\G
將顯示的內容格式輸出。
3.\T或者tee
日誌記錄,需要先:tee /tmp/test.log
所有mysql操作及輸出都記錄在這個檔案裡。
4.\c 或者CTRL+c
語句後面帶\c,前面的命令不在執行。ctrl+c退出
5.\s 或 status
檢視當前資料庫的基本狀態。
6.\. 或 source
用來執行外部的SQL指令碼:二進位制日誌擷取,備份出來的sql指令碼
7.\ use
use 進入到某個資料庫。
2,伺服器端命令(SQL結構化的查詢語言,mysql介面程式只負責接收SQL)
show 系列命令。

2、伺服器端命令(SQL)

(1)SQL:結構化的查詢語言,mysql介面程式只負責接收SQL,傳送SQL.

(2)SQL種類:

​ DDL:資料庫物件定義語言(create)

​ DCL:資料庫控制語言(grant,revoke)

​ DML:資料行操作語言(update,delete,insert)

​ DQL:資料查詢語言(show,select)

DDL操作:

​ 物件:f

​ 庫:

​ 定義什麼?

​ 1、庫名字

​ 2、庫的基本屬性

​ 如何定義?

​ create database lufei;

​ create shema lf;

​ show databases;

mysql> help create database
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_specification] ...
建立屬性:
create_specification:
字符集:[DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] 
  排序規則:COLLATE [=] collation_name
mysql> create database llf character set utf-8;
mysql> show create database llf;#檢視建庫語句
drop database llf;刪除資料庫

help  後面加命令,幫助不熟悉使用的命令。
修改字符集:
ALTER DATABASE [db_name] CHARACTER SET charset_name collation_name
mysql> alter database lf charset utf8mb4;
                          縮寫
mysql> show create database lf;

​ 表:

​ 表資料

​ 表屬性(元資料):表明,列名字,列定義(資料型別,約束,特殊列屬性)、表的索引資訊。

​ 定義什麼?

​ 定義表的屬性?

use lufei;
create table t1(id int,name varchar(20));
mysql> use lufei;
mysql> create table t1(id int ,name varchar(20));
mysql> show tables;
mysql> show create table t1;
mysql> desc t1;
mysql> drop table t1;

修改表的定義:
		修改:
		(1)在表中新增一列
		alter table t1 add age int;
		(2)新增多列
		alter table t1 add bridate datetime, add gender enum('M','F');
		(3)在指定列後新增一列
		alter table t1 add stu_id int after id;
		(4)在表中最前新增一列
		alter table t1 add sid int first;
		(5)刪除列
		 alter table t1 drop sid;
		(6)修改列名
		alter table t1 change name stu_name varchar(20);
		(7)修改列屬性
		alter table t1 modify stu_id varchar(20);
		(8)修改表名
		rename table t1 to student;
		alter table student rename  as stu;

DML語句:資料庫操作語言

​ insert

update

​ delete

DML語句:資料操作語言
	insert 
	use  lufei
	create table t1 (id int ,name varchar(20));
	insert into t1 values(1,'zhang3');
	select * from t1;
	insert into t1 values (2,'li4'),(3,'wang5'),(4,'ma6');
	insert into t1(name) values ('xyz');
	update
	update  t1  set name='zhang33' ;   ----會更新表中所有行的name欄位,比較危險。
	update  t1  set name='zhang55' where id=1;   ----update在使用時一般都會有where條件去限制。
	delete
	delete from t1 ;  --刪除表中所有行,比較危險。一行一行刪除表中資料。
	delete from t1   where  id=2;
	DDL
	truncate table t1;  ---在物理上刪除表資料,速度比較快。

DQL語句:(資料庫查詢語句)

DQL:
	select語句:
SELECT USER,PASSWORD ,HOST  FROM mysql.user;

-- select 基本查詢

DESC world.city
SELECT  id ,NAME   FROM  world.city;
SELECT * FROM world.`city`;
-- select 條件查詢 where
---- 1、查詢中國(CHN)所有的城市資訊
SELECT * FROM world.`city` WHERE countrycode='CHN';
---- 2、查詢中國(CHN)安徽省所有的城市資訊。
SELECT * FROM world.`city` 
WHERE countrycode='CHN'
AND
district='anhui';

---- 3、查詢世界上人口數量在10w-20w城市資訊
SELECT * FROM world.`city` 
WHERE 
population BETWEEN 100000 AND 200000 ;

---- 4、中國或者日本的所有城市資訊
where字句中的IN
SELECT * FROM world.city
WHERE countrycode IN ('CHN','JPN');

---- 5、模糊查詢
SELECT * FROM world.city
WHERE countrycode LIKE 'ch%';

select 排序並限制

按照人口數量排序輸出中國的城市資訊(asc(預設升序),desc(降序))

-- select 排序並限制
---- 按照人口數量排序輸出中國的城市資訊(ASC\DESC)

SELECT * FROM world.`city` WHERE countrycode='CHN' ORDER BY population ASC;
SELECT * FROM world.`city` WHERE countrycode='CHN' ORDER BY population DESC;

---- 按照多列排序人口+省排序
SELECT * FROM world.`city` WHERE countrycode='CHN' ORDER BY id DESC  ;
按照第5列進行降序排序:
SELECT * FROM city
ORDER BY 5 DESC ;

1-20
SELECT * FROM world.`city` WHERE countrycode='CHN' 
ORDER BY 5 DESC LIMIT 20;

顯示11-20行
SELECT * FROM world.`city` WHERE countrycode='CHN' 
ORDER BY 5 DESC LIMIT 10,10 ;

SELECT * FROM world.`city` WHERE countrycode='CHN' 
ORDER BY 5 DESC LIMIT 10 OFFSET 10 ;

表連線查詢(使用where)

傳統的連線寫法(使用where)
---- 中國所有城市資訊+使用語言
		
SELECT NAME ,countrycode ,population FROM city 
WHERE countrycode ='CHN'	
	
SELECT countrycode ,LANGUAGE FROM countrylanguage;

SELECT ci.NAME ,ci.countrycode ,ci.population,cl.language 
FROM 
city AS ci , countrylanguage AS cl
WHERE ci.countrycode ='CHN' 
AND
ci.CountryCode=cl.CountryCode;

SELECT NAME,ci.countrycode ,cl.language ,ci.population
FROM  city ci , countrylanguage cl
WHERE 
ci.countrycode='chn' AND
ci.`CountryCode`=cl.countrycode;

SELECT NAME,countrycode ,LANGUAGE ,population
FROM  city NATURAL  JOIN  countrylanguage 
WHERE population > 10000000
ORDER BY population;

SELECT NAME,countrycode ,LANGUAGE ,population
FROM  city JOIN  countrylanguage 
USING(countrycode);

---- 查詢青島這個城市,所在的國傢俱體叫什麼名字
DESC city
DESC country

SELECT NAME,countrycode FROM city WHERE NAME='qingdao';

SELECT NAME FROM country WHERE CODE='CHN';
--------------------------------
SELECT ci.name ,ci.countrycode,ci.population ,co.name
FROM city AS ci 
JOIN 
country AS co
ON ci.countrycode=co.code
AND
ci.name='qingdao';

group by +聚合函式 (avg(),max(),min(),sum())

group by +聚合函式(avg()、max()、min()、sum())


SELECT countrycode ,SUM(population) FROM city
WHERE countrycode = 'chn'
GROUP BY countrycode;

union 

用來替換  or 、in()

SELECT * FROM world.city
WHERE countrycode IN ('CHN','JPN');
改寫為:

SELECT * FROM world.city
WHERE countrycode ='CHN'
union
SELECT * FROM world.city
WHERE countrycode ='JPN';

字符集

字符集:

charset:字符集
UTF8
UTF8mb4

gbk

collation:排序規則

a-z ,A-Z  大小寫敏感

aA-zZ     小寫不敏感

show charset;
show collation;

資料庫:

伺服器端字符集:

控制的是,存到mysql中時,字符集控制

客戶端字符集

控制的是使用者的輸入及顯示
系統字符集

控制的是系統相關的顯示,和一些依賴於作業系統的應用
alter database oldboy CHARACTER SET utf8 collate utf8_general_ci;
alter table t1 CHARACTER SET latin1;

注意:更改字符集時,一定要保證由小往大改,後者必須是前者的嚴格超集。生產中別隨便改。

資料型別及列屬性:

數字型別
字元型別
時間型別
列屬性
create table student(id int not null primary key  AUTO_INCREMENT);
create table student1(id int not null primary key  AUTO_INCREMENT,name varchar(20))charset utf8;
create table teacher(id int not null ,name varchar(20) not null);
create table teacher1(id int not null ,name varchar(20) not null,beizhu varchar(20) not null default "ok");

primary key 主鍵:非空、唯一
unique:唯一

獲取元資料:

information_schema :

資料行之外

元資料(定義資料的資料列屬性,列名字等,狀態)

充當資料庫元資料的中央系統資訊庫:

  • 模式和模式物件
  • 伺服器統計資訊(狀態變數,設定,連線)

採用表格式以實現靈活訪問

  • 使用任意select 語句

是“虛擬資料庫”

  • 表並非“真實”表(基表),而是“系統檢視”
  • 根據當前使用者的特權動態填充表

mysql> use information_schema

mysql> show tables;

mysql> desc tables;

mysql> select table_name ,table_schema,engine from world;

顯示資料庫world中表的列的資訊:

mysql> select * from columns where table_schema='world'\G;

mysql> select table_schema,table_name from information_schema.tables where table_schema='world';
+--------------+-----------------+
| table_schema | table_name      |
+--------------+-----------------+
| world        | city            |
| world        | country         |
| world        | countrylanguage |
+--------------+-----------------+
批量拼接語句:
----
mysql> select concat('hellow');
+------------------+
| concat('hellow') |
+------------------+
| hellow           |
+------------------+
1 row in set (0.01 sec)
----
例項:
mysql> select concat("mysqldump -uroot -poldboy123 ",table_schema," ",table_name," >>","/backup/",table_schema,"-",table__name,".bak.sql") from information_schema.tables where table_schema='world';
+-----------------------------------------------------------------------------------------------------------------------------+
| concat("mysqldump -uroot -poldboy123 ",table_schema," ",table_name," >>","/backup/",table_schema,"-",table_name,".bak.sql") |
+-----------------------------------------------------------------------------------------------------------------------------+
| mysqldump -uroot -poldboy123 world city >>/backup/world-city.bak.sql                                                        |
| mysqldump -uroot -poldboy123 world country >>/backup/world-country.bak.sql                                                  |
| mysqldump -uroot -poldboy123 world countrylanguage >>/backup/world-countrylanguage.bak.sql                                  |
+-----------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
例項2:
SELECT CONCAT('CREATE TABLE ', TABLE_SCHEMA, '.',
			 TABLE_NAME, '_backup LIKE ', TABLE_SCHEMA, '.',
			 TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES
			 WHERE TABLE_SCHEMA = ‘world’;
linux命令列使用的命令:
[root@centos6-kvm3 data]# mysqlshow -uroot -poldboy123 world
元資料一般查詢語句:
show
show databases
show create database oldboy
show tables
show create table t1

SOHW databases:列出所有資料庫
SHOW TABLES:列出預設資料庫中的表
SHOW TABLES FROM <database_name>:列出指定資料庫中的表
SHOW COLUMNS FROM <table_name>:顯示錶的列結構
SHOW INDEX FROM <table_name>:顯示錶中有關索引和索引列的資訊
SHOW CHARACTER SET:顯示可用的字符集及其預設整理
SHOW COLLATION:顯示每個字符集的整理
SHOW STATUS:列出當前資料庫狀態
SHOW VARIABLES:列出資料庫中的引數定義值

八、mysql 基礎優化-索引管理

1、課程大綱

索引介紹

索引管理

2、執行計劃獲取及分析

mysql資料庫中索引的型別介紹
BTREE:B+數索引 (主要)
HASH:HASH索引
FULLTEXT:全文索引
RTREE:R樹索引
------
索引管理:
索引建立的在表的列上(欄位)的。
在where後面的列建立索引才會加快查詢速度。
索引分類:
- 主鍵索引
- 普通索引****
- 唯一索引
新增索引方法
alter table test add index index_name(name);
create index index_name on test(name);
查詢表是否有索引資訊:
DESC stu;看他的key列值
mysql> explain select * from stu;
mysql> explain select * from stu where stu_name='zhangsan';
檢視到的type不同。
------

索引及執行計劃
索引基本管理:

建立和刪除:
alter table stu add index idx_name(stu_name);
alter table stu drop index idx_name;
或者

create index inx_name on stu(stu_name);
drop index inx_name on stu;

查詢索引設定
desc stu;

主鍵索引: 唯一、非空
走主鍵索引的查詢效率是最高的,我們儘量每個表有一個主鍵,並且將來查詢的時候計量以主鍵為條件查詢

CREATE TABLE `test` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;

CREATE TABLE `test1` (
  `id` int(4) NOT NULL,
  `name` char(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
增加自增主鍵
alter table test1 change id id int(4) primary key not null auto_increment;

字首索引:
create index index_name on stu(stu_id(8));

聯合索引:
where a女生 and b身高165 and c身材好

index(a,b,c)

特點:字首生效特性。

a,ab,abc,ac   可以走索引。
b bc c 不走索引。

原則:把最常用來作為條件查詢的列放在前面。

走索引:
select  * from people where a='nv' and b>=165 and tizhong<=120;
select  * from people where a='nv' and b>=165;
select  * from people where a='nv';
select  * from people where a='nv' and tizhong<=120;

alter table stu add index minx(gender,age);
唯一性索引:
create unique index index_name on test(name);

3、explain 調取語句的執行計劃

主要是判斷語句是否走索引

explain select stu_name,gender,age from stu where gender='F' and age <20;

mysql> explain select name,gender,age from test where gender='F' and age <20;
+----+-------------+-------+-------+---------------+----------+---------+------+------+-----------------------+
| id | select_type | table | type  | possible_keys | key      | key_len | ref  | rows | Extra                 |
+----+-------------+-------+-------+---------------+----------+---------+------+------+-----------------------+
|  1 | SIMPLE      | test  | range | inx_test      | inx_test | 7       | NULL |    1 | Using index condition |

type : 表示MySQL在表中找到所需行的方式,又稱“訪問型別”,

常見型別如下:

ALL,index, range, ref, eq_ref, const, system, NULL

從左到右,效能從最差到最好

ALL:
Full Table Scan, MySQL將遍歷全表以找到匹配的行

如果顯示ALL,說明:
查詢沒有走索引:
	1、語句本身的問題
	2、索引的問題,沒建立索引

index:Full Index Scan,index與ALL區別為index型別只遍歷索引樹
例子:
explain select count(*) from stu ;

range:索引範圍掃描,對索引的掃描開始於某一點,返回匹配值域的行。
顯	而易見的索引範圍掃描是帶有between或者where子句裡帶有<,>查詢。
where 條件中有範圍查詢或模糊查詢時
>  < >= <=   between  and   in ()   or
like 'xx%'

當mysql使用索引去查詢一系列值時,例如IN()和OR列表,也會顯示range(範圍掃描),當然效能上面是有差異的。

ref:使用非唯一索引掃描或者唯一索引的字首掃描,返回匹配某個單獨值的記錄行

where stu_name='xiaoming'

explain select *  from stu  where stu_name='aa';

eq_ref:類似ref,區別就在使用的索引是唯一索引,對於每個索引鍵值,表中只有一條記錄匹配,簡單來說,
就是多表連線中使用primary key或者 unique key作為關聯條件	

join條件使用的是primary key或者 unique key

const、system:當MySQL對查詢某部分進行優化,並轉換為一個常量時,使用這些型別訪問。
如將主鍵置於where列表中,MySQL就能將該查詢轉換為一個常量

 explain  select * from city where id=1;

NULL:MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,
	  例如從一個索引列裡選取最小值可以通過單獨索引查詢完成。

mysql> explain select name,population from city;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | city  | ALL  | NULL          | NULL | NULL    | NULL | 4188 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
	  
Extra:

Using temporary
Using filesort
Using join buffer

排序   order by  ,group by ,distinct,排序條件上沒有索引
explain select * from city where countrycode='CHN' order by population;
在join 的條件列上沒有建立索引

4、資料庫索引的設計原則:

一、資料庫索引的設計原則:

	為了使索引的使用效率更高,在建立索引時,必須考慮在哪些欄位上建立索引和建立什麼型別的索引。
那麼索引設計原則又是怎樣的?(儘量使用主鍵索引和唯一性索引。)

1.選擇唯一性索引
	唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。
例如,學生表中學號是具有唯一性的欄位。為該欄位建立唯一性索引可以很快的確定某個學生的資訊。
如果使用姓名的話,可能存在同名現象,從而降低查詢速度。

主鍵索引和唯一鍵索引,在查詢中使用是效率最高的。

2.為經常需要排序、分組和聯合操作的欄位建立索引
經常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的欄位,排序操作會浪費很多時間。
如果為其建立索引,可以有效地避免排序操作。

3.為常作為查詢條件的欄位建立索引
如果某個欄位經常用來做查詢條件,那麼該欄位的查詢速度會影響整個表的查詢速度。因此,
為這樣的欄位建立索引,可以提高整個表的查詢速度。

select count(DISTINCT population ) from city;
select count(*) from city;

4.儘量使用字首來索引
如果索引欄位的值很長,最好使用值的字首來索引。例如,TEXT和BLOG型別的欄位,進行全文檢索
會很浪費時間。如果只檢索欄位的前面的若干個字元,這樣可以提高檢索速度。

------------------------以上的是重點關注的,以下是能保證則保證的--------------------

5.限制索引的數目
索引的數目不是越多越好。每個索引都需要佔用磁碟空間,索引越多,需要的磁碟空間就越大。
修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。

6.儘量使用資料量少的索引
如果索引的值很長,那麼查詢的速度會受到影響。例如,對一個CHAR(100)型別的欄位進行全文
檢索需要的時間肯定要比對CHAR(10)型別的欄位需要的時間要多。

7.刪除不再使用或者很少使用的索引
表中的資料被大量更新,或者資料的使用方式被改變後,原有的一些索引可能不再需要。資料庫管理
員應當定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。

5、索引的開發規範

不走索引的情況:
重點關注:
1) 沒有查詢條件,或者查詢條件沒有建立索引 

select * from tab;   全表掃描。
select  * from tab where 1=1;

在業務資料庫中,特別是資料量比較大的表。
是沒有全表掃描這種需求。

1、對使用者檢視是非常痛苦的。
2、對伺服器來講毀滅性的。

(1)select * from tab;

SQL改寫成以下語句:
selec  * from tab  order by  price  limit 10      需要在price列上建立索引

(2)
select  * from  tab where name='zhangsan'          name列沒有索引

改:
	1、換成有索引的列作為查詢條件
	2、將name列建立索引
	

2) 查詢結果集是原表中的大部分資料,應該是30%以上。 

查詢的結果集,超過了總數行數30%,優化器覺得就沒有必要走索引了。

假如:tab表 id,name    id:1-100w  ,id列有索引

select * from tab  where id>500000;


如果業務允許,可以使用limit控制。

怎麼改寫 ?
結合業務判斷,有沒有更好的方式。如果沒有更好的改寫方案
儘量不要在mysql存放這個資料了。放到redis裡面。


3) 索引本身失效,統計資料不真實 

索引有自我維護的能力。
對於表內容變化比較頻繁的情況下,有可能會出現索引失效。


4) 查詢條件使用函式在索引列上,或者對索引列進行運算,運算包括(+,-,*,/,! 等) 
例子: 
錯誤的例子:select * from test where id-1=9; 
正確的例子:select * from test where id=10;


5)隱式轉換導致索引失效.這一點應當引起重視.也是開發中經常會犯的錯誤. 
由於表的欄位tu_mdn定義為varchar2(20),但在查詢時把該欄位作為number型別以where條件傳給資料庫,
這樣會導致索引失效. 錯誤的例子:select * from test where tu_mdn=13333333333; 
正確的例子:select * from test where tu_mdn='13333333333'; 
------------------------
mysql> alter table tab add index inx_tel(telnum);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0


mysql> desc tab;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | YES  |     | NULL    |       |
| name   | varchar(20) | YES  |     | NULL    |       |
| telnum | varchar(20) | YES  | MUL | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)


mysql> select * from tab where telnum='1333333';
+------+------+---------+
| id   | name | telnum  |
+------+------+---------+
|    1 | a    | 1333333 |
+------+------+---------+
1 row in set (0.00 sec)

mysql> select * from tab where telnum=1333333;
+------+------+---------+
| id   | name | telnum  |
+------+------+---------+
|    1 | a    | 1333333 |
+------+------+---------+
1 row in set (0.00 sec)

mysql> explain  select * from tab where telnum='1333333';
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key     | key_len | ref   | rows | Extra                 |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
|  1 | SIMPLE      | tab   | ref  | inx_tel       | inx_tel | 63      | const |    1 | Using index condition |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
1 row in set (0.00 sec)

mysql> explain  select * from tab where telnum=1333333;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | tab   | ALL  | inx_tel       | NULL | NULL    | NULL |    2 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql> explain  select * from tab where telnum=1555555;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | tab   | ALL  | inx_tel       | NULL | NULL    | NULL |    2 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql> explain  select * from tab where telnum='1555555';
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key     | key_len | ref   | rows | Extra                 |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
|  1 | SIMPLE      | tab   | ref  | inx_tel       | inx_tel | 63      | const |    1 | Using index condition |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-----------------------+
1 row in set (0.00 sec)


------------------------

6) 
<>  ,not in 不走索引

EXPLAIN SELECT * FROM teltab WHERE telnum   <> '110';
EXPLAIN  SELECT * FROM teltab WHERE telnum  NOT IN ('110','119');
------------
mysql> select * from tab where telnum <> '1555555';
+------+------+---------+
| id   | name | telnum  |
+------+------+---------+
|    1 | a    | 1333333 |
+------+------+---------+
1 row in set (0.00 sec)

mysql> explain select * from tab where telnum <> '1555555';
-----
單獨的>,<,in 有可能走,也有可能不走,和結果集有關,儘量結合業務新增limit
or或in  儘量改成union

EXPLAIN  SELECT * FROM teltab WHERE telnum   IN ('110','119');
改寫成:

EXPLAIN SELECT * FROM teltab WHERE telnum='110'
UNION ALL
SELECT * FROM teltab WHERE telnum='119'

-----------------------------------
7)   like "%_" 百分號在最前面不走

EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '31%'   走range索引掃描

EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '%110'  不走索引

%linux%類的搜尋需求,可以使用elasticsearch

%linux培訓%

8) 單獨引用複合索引裡非第一位置的索引列. 
列子:
複合索引:

DROP TABLE t1
CREATE TABLE t1 (id INT,NAME VARCHAR(20),age INT ,sex ENUM('m','f'),money INT);

ALTER TABLE t1 ADD INDEX t1_idx(money,age,sex);
DESC t1
SHOW INDEX FROM t1
走索引的情況測試:
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30  AND sex='m';
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30  ;
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30  AND sex='m';    ----->部分走索引
不走索引的:
EXPLAIN SELECT  NAME,age,sex,money FROM t1 WHERE  age=20
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE   age=30  AND sex='m';
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE   sex='m';

九、mysql 儲存引擎

1、課程大綱

儲存引擎的介紹

mysql中的儲存引擎分類

mysql儲存引擎設定

mysql,innodb引擎儲存結構

mysql中的事物

mysql中的鎖

2、mysql儲存引擎介紹

mysql儲存引擎介紹
檔案系統:
作業系統組織和存取資料的一種機制。
檔案系統是一種軟體。
型別:ext2,3,4,xfs資料:
不管使用什麼檔案系統,資料內容不會變化
不同的是,儲存空間,大小,速度
mysql引擎:
可以理解為,mysql的“檔案系統”,只不過功能更加強大。
mysql引擎功能:
除了可以提供基本的存取功能,還有更多功能事物功能,鎖定,備份和恢復,優化以及特殊功能。

3、mysql儲存引擎種類

MySQL 提供以下儲存引擎:
InnoDB
MyISAM
MEMORY
ARCHIVE	
FEDERATED
EXAMPLE
BLACKHOLE
MERGE
NDBCLUSTER
CSV
還可以使用第三方儲存引擎(TokuDB)。

4、資料庫的儲存引擎

儲存引擎查詢

儲存引擎查詢:
show engines;
select @@default_storage_engine;
show create table city;
show table status like 'city'\G
use information_schema 
select table_schema,table_name,engine from information_schema.tables where table_schema='world';
select table_schema,table_name,engine from information_schema.tables where table_schema='mysql';
select table_schema,table_name,engine from information_schema.tables where engine='csv';

儲存引擎的配置:

檢視儲存引擎:
show engines;
select @@default_storage_engine;
mysql> show variables like '%engine%';
+----------------------------+--------+
| Variable_name              | Value  |
+----------------------------+--------+
| default_storage_engine     | InnoDB |
| default_tmp_storage_engine | InnoDB |
| storage_engine             | InnoDB |
+----------------------------+--------+
將儲存引擎設定在配置檔案中,重啟mysql生效。

配置儲存引擎:

1、在啟動配置檔案中設定伺服器儲存引擎:
	[mysqld]
	default-storage-engine=<Storage Engine>
2、使用 SET 命令為當前客戶機會話設定:
	SET @@storage_engine=<Storage Engine>;
3、在 CREATE TABLE 語句指定:
	CREATE TABLE t (i INT) ENGINE = <Storage Engine>;

mysql> show variables like '%engine%';
mysql> use world
mysql> create table test3 (id int ) engine=innodb;
mysql> show create table test3;

5、innodb體系結構:

表空間:

共享表空間:主要存放系統元資料

獨立表空間:主要存放使用者資料

邏輯概念,資料儲存的概念

表空間資料檔案:idb檔案,在/app/mysql/data/lufei

共享表空間的設定:

預設的配置:
innodb_data_file_path    /application/mysql/data/  ibdata1:12M:autoextend 

共享表空間的設定:
共享表空間設定:

innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend

innodb_data_file_path=ibdata1:12M;ibdata2:50M:autoextend    ----錯誤的配置XXX
在 /application/mysql/data/檢視idbdata1實際的大小,然後在增加idbdata2的大小,進行擴充套件。此命令配置在mysql的配置檔案中。
innodb_data_file_path=ibdata1:76M;ibdata2:50M:autoextend    -----正確的配置

獨立表空間:

	除了系統表空間之外,InnoDB 還在資料庫目錄中建立另外的表空間,用於每個 InnoDB 表的 .ibd 檔案。
	InnoDB 建立的每個新表在資料庫目錄中設定一個 .ibd 檔案來搭配表的 .frm 檔案。
	可以使用 innodb_file_per_table 選項控制此設定
	更改該設定僅會更改已建立的新表的預設值。
	
注:在mysql5.6開始,預設的配置為:
	| innodb_file_per_table | ON    |
	
獨立表空間刪除表空間命令:

alter table testtab discard tablespace;

該命令執行後/app/mysql/data/lufei中的testtab的ibd檔案就被刪除。

6、Innodb引擎-事務

組資料操作執行步驟,這些步驟被視為一個工作單元:
	用於對多個語句進行分組
	可以在多個客戶機併發訪問同一個表中的資料時使用
所有步驟都成功或都失敗:
	如果所有步驟正常,則執行
	如果步驟出現錯誤或不完整,則取消

事務ACID:
Atomic(原子性)
	所有語句作為一個單元全部成功執行或全部取消。
Consistent(一致性)
	如果資料庫在事務開始時處於一致狀態,則在執行該事務期間將保留一致狀態。 
Isolated(隔離性)
	事務之間不相互影響。
Durable(永續性)
	事務成功完成後,所做的所有更改都會準確地記錄在資料庫中。所做的更改不會丟失。

7、mysql事務控制語句

事務中的標準語句:DML語句
insert,update,delete三類事物語句。
如果遇到以上三個命令,都是事物型的操作,都會預設在前面新增begin命令。

START TRANSACTION(或 BEGIN):顯式開始一個新事務
1
2
3
COMMIT:永久記錄當前事務所做的更改
BEGIN
1    打標記a
2    打標記b(savepoint時候)
3
ROLLBACK:取消當前事務所做的更改(回滾到所打的標記)

SAVEPOINT:分配事務過程中的一個位置,以供將來引用
ROLLBACK TO SAVEPOINT:取消在 savepoint 之後執行的更改
RELEASE SAVEPOINT:刪除 savepoint 識別符號
SET AUTOCOMMIT:為當前連線禁用或啟用預設 autocommit 模式

儲存:commit是自動儲存的:

mysql> show variables like "%auto%";
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| auto_increment_increment    | 1     |
| auto_increment_offset       | 1     |
| autocommit                  | ON    |
| automatic_sp_privileges     | ON    |
| innodb_autoextend_increment | 64    |
| innodb_autoinc_lock_mode    | 1     |
| innodb_stats_auto_recalc    | ON    |
| sql_auto_is_null            | OFF   |
+-----------------------------+-------+
8 rows in set (0.00 sec)
需要將自動儲存的commit改成關閉:(只修改當前會話)
mysql> set autocommit=0;
檢視全域性commit配置:
mysql> show global variables like "%auto%";
	在有些業務繁忙企業場景下,這種配置可能會對效能產生很大影響,但對於安全性上有很大提高。
將來,我們需要去權衡我們的業務需求去調整是否自動提交。
我們可以通過以下命令進行修改關閉(0是關閉,1是開啟):
	SET GLOBAL AUTOCOMMIT=0;  -所有新建會話	
	SET SESSION AUTOCOMMIT=0; -當前會話
	SELECT @@AUTOCOMMIT;      -檢視設定結果
我們也可以修改配置檔案讓其永久生效:
	vi /etc/my.cnf	
	[mysqld]
	AUTOCOMMIT=0
		
隱式提交語句(commit):
用於隱式提交的 SQL 語句:
	START TRANSACTION
	SET AUTOCOMMIT = 1 
導致提交的非事務語句:
	DDL語句:	(ALTER、CREATE 和 DROP)
	DCL語句:	(GRANT、REVOKE 和 SET PASSWORD)
	鎖定語句:(LOCK TABLES 和 UNLOCK TABLES)
導致隱式提交的語句示例:
	TRUNCATE TABLE
	LOAD DATA INFILE
	SELECT FOR UPDATE