like
:%
匹配任意字符(含0個)_
匹配單個字符between and
:閉區間in (value1, value2, ...)
:判斷是否位於列表order by field1 field2 asc|desc
能夠每一列都按照不一樣的升序/降序進行排列,默認爲升序。除了字段以外,還可使用表達式、函數、別名進行排序。order by 通常放在最後,除了 limit 以外。group by expression
。
select 分組函數,fields from tablename [where] group by 分組列表[having][order by]
select 查詢列表 from t1 [鏈接類型] join t2 on 鏈接條件
inner join
left [outer] join
,左邊的爲主表right [outer] join
,右邊爲主表full [outer] join
cross join
select
語句,稱爲子查詢或內查詢。
limit [offset] size
,offset 表示起始索引,從0開始,默認爲0,size 表示個數insert into table (field1,...) values(value1,...)
支持插入多行insert into table set field1=value1 , field2=value2,...
只能插入一行update table set filed=value,... where...
delete from table where...
刪除一或多行truncate table tablename
整體來講,查詢語法以下:mysql
SELECT DISTINCT select_list
FROM left_table join_type
JOIN right_table
ON join_condition
WHERE where_condition
GROUP BY group_by_list
HAVING having_condition
ORDER BY order_by_condition
LIMIT offset size
複製代碼
外鍵:算法
事務(Transaction)是併發控制的基本單位。所謂的事務,它是一個操做序列,這些操做要麼都執行,要麼都不執行,它是一個不可分割的工做單位。sql
其中,一致性保證了事務的執行結果是正確的。在無併發狀況下,原子性保證了一致性。在併發狀況下,原子性和隔離性保證了一致性。持久性用來應對數據庫崩潰。數據庫
隱式事務:mysql 默認開啓了 autocommit 選項,會隱式提交事務。express
顯式事務:緩存
set autocommit = 0;
start transaction;
該語句可選。commit;
提交 rollback;
回滾第一範式(1NF):數據庫表中的字段都是單一屬性的,不可再分。這個單一屬性由基本類型構成,包括整型、實數、字符型、邏輯型、日期型等。安全
第二範式(2NF):數據庫表中不存在非關鍵字段對任一候選關鍵字段的部分函數依賴(部分函數依賴指的是存在組合關鍵字中的某些字段決定非關鍵字段的狀況),也即全部非關鍵字段都徹底依賴於任意一組候選關鍵字。bash
第三範式(3NF):在第二範式的基礎上,數據表中若是不存在非關鍵字段對任一候選關鍵字段的傳遞函數依賴則符合第三範式。所謂傳遞函數依賴,指的是如 果存在"A → B → C"的決定關係,則C傳遞函數依賴於A。所以,知足第三範式的數據庫表應該不存在以下依賴關係: 關鍵字段 → 非關鍵字段 x → 非關鍵字段y服務器
視圖是一種虛擬的表,能夠和普通表同樣使用,行和列的數據來自定義視圖的查詢中使用的表,在使用視圖的時候動態生成,只保存 sql 邏輯,不保存查詢結果。能夠應用於多個地方用到一樣的查詢結果的情景。數據結構
優勢:
建立視圖: create view 視圖名 as 查詢語句
修改視圖: create or replace view 視圖名 as 查詢語句
或者 alter view 視圖名 as 查詢語句
刪除視圖:drop view 視圖名
查看視圖:desc 視圖名
和show create view 視圖名
索引是一種特殊的文件,包含對數據表裏全部記錄的引用指針。
MySQL 官方定義:索引是幫助 MySQL 高效獲取數據的數據結構。在數據自己以外,數據庫還維護着一個知足特定查找算法的數據結構,這些數據結構以某種方式指向數據,這種數據結構就是索引。索引能夠理解爲已排序的快速查找數據結構。平時所說的索引,若是沒有特別指明,都是指的是 B+ 樹。
通常來講索引自己也很大,不可能所有存儲在內存中,所以索引每每以索引文件的形式存儲在磁盤上。
優勢:
缺點:
Mysql基本存儲結構是頁,各個數據頁組成雙向鏈表,每一個數據頁中的記錄又能夠組成一個單向鏈表。查找時,先遍歷雙向鏈表,定位到所在的頁。每一個數據頁都會爲所存儲的記錄生成頁目錄,經過主鍵查找會在頁目錄使用二分法定位到對應的槽,從槽中遍歷找到指定記錄。非主鍵搜索,會依次遍歷單鏈表中的每條記錄。
SQL 執行順序:
SELECT DISTINCT select_list
FROM left_table join_type
JOIN right_table
ON join_condition
WHERE where_condition
GROUP BY group_by_list
HAVING having_condition
ORDER BY order_by_condition
LIMIT offset size
複製代碼
mysql 處理的順序:
FROM left_table
ON join_condition
join_type JOIN right_table
WHERE where_condition
GROUP BY group_by_list
HAVING having_condition
SELECT
DISTINCT select_list
ORDER BY order_by_condition
LIMIT offset size
複製代碼
CREATE [UNIQUE] INDEX indexName ON table(columnlist);
或者 ALTER table ADD [UNIQUE] INDEX [indexname] ON (columnlist)
DROP INDEX [indexname] on table
SHOW INDEX FROM table
B+ Tree 是基於 B Tree 和葉子節點順序訪問指針進行實現,它具備 B Tree 的平衡性,而且經過順序訪問指針來提升區間查詢的性能。
當沒有索引時,咱們須要遍歷雙向鏈表來定位所在的頁,如今經過索引,能夠很快定位到所在的頁上。底層採用B+樹實現。B+樹是平衡樹的一種,若是對這棵樹進行增刪改,須要從新維持平衡,有額外的開銷。
採用hash算法,把鍵值換成hash值,只須要一次hash算法就能夠當即定位,速度快。
侷限:
MyISAM: B+Tree葉節點的data域存放的是數據記錄的地址。在索引檢索的時候,首先按照B+Tree搜索算法搜索索引,若是指定的Key存在,則取出其 data 域的值,而後以 data 域的值爲地址讀取相應的數據記錄。這被稱爲「非聚簇索引」。
InnoDB: 其數據文件自己就是索引文件。相比MyISAM,索引文件和數據文件是分離的,其表數據文件自己就是按B+Tree組織的一個索引結構,樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,所以InnoDB表數據文件自己就是主索引。這被稱爲「聚簇索引(或彙集索引)」。而其他的索引都做爲輔助索引,輔助索引的data域存儲相應記錄主鍵的值而不是地址,這也是和MyISAM不一樣的地方。在根據主索引搜索時,直接找到key所在的節點便可取出數據;在根據輔助索引查找時,則須要先取出主鍵的值,再走一遍主索引。 所以,在設計表的時候,不建議使用過長的字段做爲主鍵,也不建議使用非單調的字段做爲主鍵,這樣會形成主索引頻繁分裂。
左鏈接 left join 中,左表全都有,left join 用於肯定如何從右表搜索行,則右表創建索引,效率更好。右鏈接同理。
like %xxx
和like %xxx%
沒法使用索引,只有通配符卸載最右才能使用索引。當使用like %xx%
時,可使用覆蓋索引,會使用到索引,可是類型爲 range建議:
Explain 關鍵字用來模擬優化器執行 SQL 查詢語句,從而知道 MySQL 是如何處理 SQL 語句的,從而分析查詢語句或者表結構的性能瓶頸。
使用 explain + sql 語句能夠查看對應的 SQL 語句的執行計劃。
InnoDB的行級鎖是基於索引實現的,若是查詢語句未命中任何索引,那麼InnoDB會使用表級鎖。不一樣於MyISAM老是一次性得到所需的所有鎖,InnoDB的鎖是逐步得到的,當兩個事務都須要得到對方持有的鎖,致使雙方都在等待,這就產生了死鎖。 咱們能夠採起如下方式避免死鎖:
MyISAM採用表級鎖(table-level locking)。 InnoDB支持行級鎖(row-level locking)和表級鎖,默認爲行級鎖。
開啓查詢緩存後在一樣的查詢條件以及數據狀況下,會直接在緩存中返回結果。這裏的查詢條件包括查詢自己、當前要查詢的數據庫、客戶端協議版本號等一些可能影響結果的信息。所以任何兩個查詢在任何字符上的不一樣都會致使緩存不命中。
緩存創建以後,Mysql的查詢緩存系統會跟蹤查詢中涉及的每張表,若是這些表(數據或結構)發生變化,那麼和這張表相關的全部緩存數據都將失效。
緩存雖然可以提高數據庫的查詢性能,可是緩存同時也帶來了額外的開銷,每次查詢後都要作一次緩存操做,失效後還要銷燬。 所以,開啓緩存查詢要謹慎,尤爲對於寫密集的應用來講更是如此。若是開啓,要注意合理控制緩存空間大小。
InnoDB的最大特點就是支持了ACID兼容的事務(Transaction)功能。
是 MySQL 默認的事務型存儲引擎,只有在須要它不支持的特性時,才考慮使用其它存儲引擎。
實現了四個標準的隔離級別,默認級別是可重複讀(REPEATABLE READ)。在可重複讀隔離級別下,經過多版本併發控制(MVCC)+ 間隙鎖(Next-Key Locking)防止幻影讀。
特色:
如今大多數時候咱們使用的都是InnoDB存儲引擎,可是在某些狀況下使用MyISAM更好,好比:MyISAM更適合讀密集的表,而InnoDB更適合寫密集的的表。 在數據庫作主從分離的狀況下,常常選擇MyISAM做爲主庫的存儲引擎。
使用show engines
查詢引擎。
對比項 | MyISAM | InnoDB |
---|---|---|
主鍵和外鍵 | 不支持 | 支持 |
事務 | 不支持 | 支持 |
鎖 | 表鎖 | 行鎖,適合高併發操做 |
緩存 | 只緩存索引,不緩存真實數據 | 緩存索引以及真實數據,對內存要求較高 |
表空間 | 小 | 大 |
小的數據集驅動大的數據集
select * from A where id in(select id from B)
等價於:
for select id from B
for select * from A where A.id = B.id
複製代碼
當 B 表的數據集必須小於 A 表的數據集時,用 in 優於 exists。
select * from A where exists (select * from B where B.id = A.id)
等價於:
for select * from A
for select * from B where B.id=A.id
複製代碼
當 A 表的數據集小於 B 表的數據集時,用 exists 優於 in。
select ... from table where exists (subquery)
複製代碼
該語法的理解爲:將主查詢的數據,放到子查詢作條件驗證,根據驗證結果(TRUE 或 FALSE)來決定主查詢的數據結果是否得以保留。
MySQL 支持兩種方式的排序, FileSort 和 Index。其中 Index 效率更高,使用 MySQL 掃描索引自己完成排序。
ORDER BY 知足兩種狀況時,會使用 Index 方式進行排序。 :
所以,要儘量在索引列上完成排序操做,遵守索引的最佳左前綴原則。
若是 ORDER BY 不在索引列上, filesort 有兩種算法:MySQL 啓動雙路排序和單路排序。
因爲單路排序要取出全部數據,可能致使每次只能取 buffer 大小的數據,從而須要屢次 IO 操做。
提升 order by 的速度:
sort_buffer_size
max_length_for_sort_data
group by 實質是先排序後分組,遵守索引創建的最佳左前綴。
當沒法使用索引列時,嘗試增大sort_buffer_size
和max_length_for_sort_data
。
where 高於 having,能寫在 where 限定的條件就不要去 having 限定了。
水平切分
又稱爲 Sharding,將同一個表中的記錄拆分到多個結構相同的表中,將數據分佈到集羣的不一樣節點上,緩解單個數據庫的壓力。
通常水平查分根據表中的某一字段(通常是主鍵)取模,將一張表的數據拆分到多個表。採用 hash(key)%N 的方法。使用單獨一個數據庫來存儲映射關係。
分片的選擇時取決於最頻繁的查詢SQL的條件,若是某個表的數據有明顯的時間特徵,則一般適合使用時間範圍分片。
能夠將原來的鏈接分解爲多個單表查詢,而後在用戶程序中進行鏈接。
優勢:
缺點:
不少大表對MySQL這種關係型數據庫的需求並不大,並不要求ACID,能夠考慮將這些表歉意到NoSQL,解決水平擴展問題。如日誌類、監控類、統計類數據,非結構化或若結構化數據,對事務要求不強的數據等。
垂直切分
將一張表按列切分紅多個表,將數據庫中標的密集程度部署到不一樣的庫中。如電商數據庫切分紅商品數據庫和用戶數據庫。當一張表的字段過多時考慮垂直拆分,一般將一張表的字段拆分爲主表和擴展表。
主從複製是用來創建一個和主數據庫徹底同樣的數據庫環境,稱爲從數據庫。主數據庫通常是準實時的業務數據庫。
好處:
原理:
基本原理是讓主數據庫處理增刪改操做,從數據庫處理查詢操做。數據庫複製被用來把事務性操做致使的變動同步到集羣中的從數據庫。
大多數業務每每讀多寫少,這時候數據庫的讀性能就會成爲性能瓶頸。
爲了解決讀的性能瓶頸,有多種解決方案。