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