1. 背景
本文講查詢數(shù)據(jù)。
2.知識
基本的就是 增刪改查。一般說 CRUD, CRUD是指在做計算處理時的增加(Create)、檢索(Retrieve)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫。
2.1 簡單查詢
SELECT 語句用于從數(shù)據(jù)庫中檢索查詢。
示例:
select * from tb_table1 where name='li4'```
- where 關(guān)鍵字后面跟查詢條件
- from 關(guān)鍵字后面跟表名或者視圖名
- order by 后跟排序的字段
2.2 插入
使用 insert into 語句可以插入一條數(shù)據(jù)記錄。
insert into tb_table1 (name,deptId) values ('wang',0);
- insert into 后跟表名,括號內(nèi)寫字段名
- values 后的括號內(nèi)寫具體字段對應(yīng)的值
2.2 更新
update 用于更新一條數(shù)據(jù)記錄的值。
update tb_table1 set name='zhang33' where id=1;
- update 后跟 表名
- set 后跟 修改的字段和值
- where 指定篩選條件
2.3 刪除
delete 用于刪除一條數(shù)據(jù)記錄。
delete from tb_table1 where name='li4';
- delete 后跟 表名
- where 指定篩選條件
2.4 高級查詢
是否包含在內(nèi) --- 使用 IN 關(guān)鍵字的查詢
select * from tb_table1 where id in (1,3,4);
select * from tb_table1 where name in ('wang','zhang33');
范圍區(qū)間查詢 --- 使用 BETWEEN AND 關(guān)鍵字的查詢
select * from tb_table1 where id between 2 and 4;
字符串模糊搜索 --- 使用 LIKE 關(guān)鍵字的查詢
select * from tb_table1 where name like 'zh%'
- % 百分號是通配符,這里表示 zh 開頭的都查詢出來。
查看空值(NULL) --- 使用 IS NULL 關(guān)鍵字的查詢
select * from tb_table1 where salary is NULL; # 正確
select * from tb_table1 where salary = NULL; # 錯誤的,查不到結(jié)果。
多條件查詢 --- 使用 AND 、OR關(guān)鍵字的查詢
select * from tb_table1 where deptId=0 and salary is null;
多字段排序 -- Order by 后使用多個字段
select * from tb_table1 order by name, deptId;
分組 -- 使用 group by
select count(*) from tb_table1 group by class;
select count(*),class from tb_table1 group by class;
分組后再過濾 -- 在 group by 中使用 having
select count(*),class from tb_table1 group by class having class = 1;
分頁查詢 -- 使用 LIMIT
mysql> select * from tb_table1 limit 4,2;
- LIMIT 后第一個數(shù)字 指 跳過多少行。
- LIMIT 后逗號后的數(shù)字指 取多少行。
計數(shù),求和,平均,取最大最小值 -- 使用聚合函數(shù)
select count(deptId),class from tb_table1 group by class;
select sum(deptId),class from tb_table1 group by class;
select avg(deptId),class from tb_table1 group by class;
select min(Id),class from tb_table1 group by class;
select max(Id),class from tb_table1 group by class;
連接查詢: 內(nèi)連接,左連接,右連接
# 內(nèi)連接 inner join
select * from tb_table1 as t inner join account as a on t.id = a.userId;
# 左連接
select * from tb_table1 as t left join account as a on t.id = a.userId;
# 右連接
select * from tb_table1 as t right join account as a on t.id = a.userId;
子查詢, ANY SOME IN 等
select * from tb_table1 where id IN (select userId from account WHERE money>100)
合并查詢 -- 使用 UNION
select * from tb_table1 where deptId =1 union select * from tb_table1 where deptId =2;
正則表達(dá)式查詢 -- 使用 REGEXP
select * from tb_table1 WHERE name REGEXP '^z';
3. 索引
3.1 概念
索引就像是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。
它是對數(shù)據(jù)庫表中一列或多列的值進(jìn)行排序的一種結(jié)構(gòu),使用索引可快速訪問數(shù)據(jù)庫表中的特定信息。
索引是一個單獨(dú)存儲在磁盤上的數(shù)據(jù)庫結(jié)構(gòu),它們存儲著對數(shù)據(jù)表里的數(shù)據(jù)記錄的應(yīng)用指針。
- 其中MySQL中的索引的存儲類型有兩種:BTREE、HASH。 也就是用樹或者Hash值來存儲該字段,具體又和標(biāo)的存儲引擎有關(guān)。
- MyISAM 和 InnoDB 存儲引擎只支持 BTREE 索引。
- MEMORY / HEAP 存儲引擎可以支持 BTREE 和 HASH 索引。
不使用索引的情況下進(jìn)行檢索時,需要遍歷和讀取整個表,是很耗時的操作。而有了索引后,MySQL 不在全部掃描,直接在索引里找,借助于索引特殊的數(shù)據(jù)結(jié)構(gòu)(比如 BTREE)可以快速定位這一行數(shù)據(jù)的位置。
索引的分類:
普通索引和唯一索引
- 普通索引:是MySQL的基本索引類型,允許重復(fù)和空值。
- 唯一索引:值必須是唯一的,可以空值但不能重復(fù)。即使是組合索引也必須唯一。
- 主鍵索引:是一種特殊的唯一索引,不能有空值。
單列索引和組合索引
- 單列索引:一個索引僅包含一個列 的索引。
- 組合索引: 由多個字段組合創(chuàng)建的索引。注意在查詢條件中使用了左邊的字段時,索引才被使用。
全文索引
全文索引( FULLTEXT) ,在創(chuàng)建了全文索引的列上支持值的全文檢索。它可以在 CHAR, VARCHAR 或者 TEXT 類型的列上創(chuàng)建。
注意:只有 MyISAM 引擎的表才能創(chuàng)建全文索引
3.2 創(chuàng)建索引
創(chuàng)建索引的三個方法:
- 創(chuàng)建表時即創(chuàng)建索引
- 在已存在的表上,使用 “ALTER TABLE” 關(guān)鍵字創(chuàng)建索引
- 在已存在的表上,使用 “CREATE INDEX” 關(guān)鍵字創(chuàng)建索引
3.2.1 創(chuàng)建表時即創(chuàng)建索引
1、創(chuàng)建普通索引, 在建表時使用關(guān)鍵 “ INDEX ”。示例:
CREATE TABLE book
(
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
bookName VARCHAR(255) NOT NULL ,
authors VARCHAR(255) NOT NULL,
info VARCHAR(255) NOT NULL,
comment VARCHAR(255) NOT NULL,
year_publication YEAR NOT NULL,
INDEX(year_publication)
);
2、創(chuàng)建 唯一索引, 在建表時使用關(guān)鍵 “ UNIQUE INDEX ”。示例:
CREATE TABLE table1
(
id INT NOT NULL,
name varchar(255) NOT NULL,
UNIQUE INDEX TheUniqueIdx1(id)
);
3、創(chuàng)建單列索引:
CREATE TABLE table2
(
id INT NOT NULL,
name varchar(255) NOT NULL,
INDEX TheSingleIdx1(name(20))
);
#注意,指定了索引長度 20
4、創(chuàng)建組合索引:
CREATE TABLE table5
(
id INT NOT NULL,
name varchar(255) NOT NULL,
age INT NOT NULL,
INDEX TheMultiIdx2(id,name,age)
);
5、創(chuàng)建 全文索引,使用關(guān)鍵字 " FULLTEXT INDEX "。只有 MyISAM 存儲引擎才支持 全文索引,且僅可以為 CHAR, VARCHAR, 和 TEXT 列創(chuàng)建全文索引。
CREATE TABLE table7
(
id INT NOT NULL,
info VARCHAR(255) NOT NULL,
FULLTEXT INDEX TheFulltextIdx(info)
) ENGINE=MyISAM
6、創(chuàng)建空間索引,使用 “ SPATIAL INDEX ” 關(guān)鍵字。它作用于字段類型為 GEOMETRY 上。
CREATE TABLE table8
(
id INT NOT NULL,
poi GEOMETRY NOT NULL,
SPATIAL INDEX TheSpatialIdx(poi)
) ENGINE=MyISAM
3.2.2 使用 “ALTER TABLE” 關(guān)鍵字在已存在的表上創(chuàng)建索引
和建表時類似,示例:
# 普通索引
ALTER TABLE book ADD INDEX TheIdx1(bookName);
# 唯一索引
ALTER TABLE book ADD UNIQUE INDEX TheIdx2(id);
# 組合索引
ALTER TABLE book ADD UNIQUE INDEX TheIdx3(id,authors);
3.2.3 使用 “CREATE INDEX” 關(guān)鍵字在已存在的表上創(chuàng)建索引
CREATE INDEX 其實(shí)等效于 ALTER TABLE,在 MySQL中 CREATE INDEX 被映射到一個 ALTER TABLE 語句上。示例:
# 普通索引
CREATE INDEX BkIndex11 ON book(bookName);
# 唯一索引
CREATE UNIQUE INDEX BkIndex12 ON book(id);
# 組合索引
CREATE UNIQUE INDEX BkIndex13 ON book(authors,info);
3.3 刪除索引
在 MySQL 中可以使用 ALTER TABLE 或者 DROP INDEX 語句來刪除一個索引。
兩種方法是等效的,DROP INDEX 在內(nèi)部被映射到一個 ALTER TABLE 上。
# 刪除一個索引
ALTER TABLE book DROP INDEX TheIdx1;
# 刪除一個索引
DROP INDEX TheIdx2 ON book;
3.4 擴(kuò)展知識
聚簇索引和非聚簇索引
聚簇索引并不是一種獨(dú)特的索引類型,而是一種數(shù)據(jù)存儲方式。
即按照索引的存儲方式分類:
- 聚簇索引 (Clustered Index)
- 非聚簇索引 (Non- Clustered Index),又叫二級索引 (secondary index )
簡單說就是:
- 聚簇索引中 索引的順序就是數(shù)據(jù)的物理存儲順序;
- 而非聚簇索引的索引順序與數(shù)據(jù)物理排列順序無關(guān)。
InnoDB 引擎是按 B+TREE 結(jié)構(gòu)存儲的
InnoDB中,表數(shù)據(jù)文件本身就是按B+Tree組織的一個索引結(jié)構(gòu),聚簇索引就是按照每張表的主鍵構(gòu)造一顆B+樹,同時葉子節(jié)點(diǎn)中存放了整張表的行記錄數(shù)據(jù),也將聚集索引的葉子節(jié)點(diǎn)稱為數(shù)據(jù)頁。
Innobd中的主鍵索引是一種聚簇索引,非聚簇索引都是輔助索引,像復(fù)合索引、前綴索引、唯一索引。
非聚簇索引(輔助索引) 是在聚簇索引之上創(chuàng)建的索引,輔助索引訪問數(shù)據(jù)總是需要二次查找。輔助索引葉子節(jié)點(diǎn)存儲的不再是行的物理位置,而是主鍵值。通過輔助索引首先找到的是主鍵值,再通過主鍵值找到數(shù)據(jù)行的數(shù)據(jù)頁,再通過數(shù)據(jù)頁中的Page Directory找到數(shù)據(jù)行。
這兩種索引內(nèi)部都是B+樹,聚簇索引的葉子節(jié)點(diǎn)存放著一整行的數(shù)據(jù)。而非聚簇索引存放的是主鍵,要定位到數(shù)據(jù)記錄行 還需要通過主鍵再到B+樹上檢索一次。
Innodb使用的是聚簇索引,MyISam使用的是非聚簇索引。
4. 擴(kuò)展
EXPLAIN 關(guān)鍵字,用于獲取查詢執(zhí)行計劃(即 MySQL 如何執(zhí)行查詢的說明。
EXPLAIN 在對SQL優(yōu)化分析時很有用,我們可以用 explain 這個命令來查看一個這些SQL語句的執(zhí)行計劃,查看該SQL語句有沒有使用上了索引,有沒有做全表掃描,這都可以通過explain命令來查看。
比如:
EXPLAIN select * from book where year_publication= 1990 \G;
# 執(zhí)行后:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: book
partitions: NULL
type: ref
possible_keys: year_publication
key: year_publication
key_len: 1
ref: const
rows: 1
filtered: 100.00
Extra: Using index condition
1 row in set, 1 warning (0.00 sec)
參考:https://dev.mysql.com/doc/refman/8.0/en/explain.html
END