主鍵索引:數據列不容許重複,不容許爲NULL。一個表只能有一個主鍵索引。InnoDB的主鍵索引爲聚簇索引,而MyISAM的主鍵索引爲非聚簇索引。 建立:ALTER TABLE table_name ADD PRIMARY KEY (column);
mysql
惟一索引:數據列不容許重複,容許爲NULL,一個表中容許建立多個惟一索引。惟一索引能夠用做業務防重。 建立:ALTER TABLE table_name ADD UNIQUE (column1, column2);
git
普通索引:基本的索引類型,沒有惟一性的限制,容許爲NULL值。 建立:ALTER TABLE table_name ADD KEY (column1, column2)
github
全文索引:是目前搜索引擎使用的一種關鍵技術,InnoDB不支持全文索引,MyISAM支持全文索引。 建立:ALTER TABLE table_name ADD FULLTEXT (column);
算法
聯合索引從左邊的列到右邊的列依次匹配,聯合索引的最左前綴原則以下: 對於聯合索引:index(co1, col2, col3)sql
where col1=1
,where col1=1 and col2=2
,where col1=1 and col2=2 and col3=3
都會走這個索引。第一個語句使用 col1,第二個語句使用 col1,col2,第三個使用 col1,col2,col3;where col2=2
,where col2=2 and col3=3
不會走索引;where col3=3 and col2=2 and col1=1
未經查詢優化的話不會走索引,可是通過查詢優化後會走索引...;where col1=1 and col3=3
僅使用 col1;where col1=1 and col2>2 and col3=3
僅使用 col1,col2;where col1=1 and col2 like 'xx%'
使用 col1,col2;where col1=1 and col2 like '%xx''
僅使用 col1。B-Tree索引:數據庫
B-Tree索引是一棵多路查找平衡樹,InnoDB 和 MyISAM 存儲引擎都支持 B-Tree 索引。InnoDB 支持聚簇索引,InnoDB 默認會爲主鍵建立聚簇索引,聚簇索引的非葉子節點不保存數據,只有葉子節點會保存數據,聚簇索引的葉子節點還會保存相鄰的後一個節點的指針。非聚簇索引葉子節點不保存數據,只保存主鍵索引。緩存
HASH索引:安全
Hash 索引檢索效率高,只須要一次定位,不像 B-Tree 索引須要從根節點到葉子節點,最後才能訪問到頁節點這樣屢次的IO訪問。 Hash索引雖然檢索效率高,可是也有不少的不足之處:併發
Hash 索引僅僅能知足」=」,」IN」和」<=>」查詢,不能使用範圍查詢。 因爲 Hash 索引比較的是進行 Hash 運算以後的 Hash 值,因此它只能用於等值的過濾,不能用於基於範圍的過濾,由於通過相應的 Hash 算法處理以後的 Hash 值的大小關係,並不能保證和Hash運算前徹底同樣。函數
Hash 索引沒法被用來避免數據的排序操做。 因爲 Hash 索引中存放的是通過 Hash 計算以後的 Hash 值,並且 Hash 值的大小關係並不必定和 Hash 運算前的鍵值徹底同樣,因此數據庫沒法利用索引的數據來避免任何排序運算;
Hash 索引不能利用部分索引鍵查詢。 對於組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合併後再一塊兒計算 Hash 值,而不是單獨計算 Hash 值,因此經過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也沒法被利用。
Hash 索引在任什麼時候候都不能避免表掃描。 前面已經知道,Hash 索引是將索引鍵經過 Hash 運算以後,將 Hash運算結果的 Hash 值和所對應的行指針信息存放於一個 Hash 表中,因爲不一樣索引鍵存在相同 Hash 值,因此即便取知足某個 Hash 鍵值的數據的記錄條數,也沒法從 Hash 索引中直接完成查詢,仍是要經過訪問表中的實際數據進行相應的比較,並獲得相應的結果。
Hash 索引遇到大量Hash值相等的狀況後性能並不必定就會比B-Tree索引高。 對於選擇性比較低的索引鍵,若是建立 Hash 索引,那麼將會存在大量記錄指針信息存於同一個 Hash 值相關聯。這樣要定位某一條記錄時就會很是麻煩,會浪費屢次表數據的訪問,而形成總體性能低下。
B-Tree vs. HASH索引
索引名 | HASH | B-Tree |
---|---|---|
是否支持最左前綴匹配原則 | 不支持,只有索引的所有字段都用上纔會匹配到 | 支持,用上索引的第一個字段就能夠匹配索引 |
MyISAM和InnoDB是否支持 | 不支持(只有Memory和NDB引擎索引支持) | 支持 |
範圍查詢可否命中索引 | 不能夠,只有「=」,「IN」,「<=>」(等價於的意思)查詢能命中 | 能夠 |
是否必定會全表掃描 | 是 | 否 |
整數: tinyint、smallint、mediumint、int、bigint
type | Storage | Minumun Value | Maximum Value |
---|---|---|---|
(Bytes) | (Signed/Unsigned) | (Signed/Unsigned) | |
TINYINT | 1 | -128 | 127 |
0 | 255 | ||
SMALLINT | 2 | -32768 | 32767 |
0 | 65535 | ||
MEDIUMINT | 3 | -8388608 | 8388607 |
0 | 16777215 | ||
INT | 4 | -2147483648 | 2147483647 |
0 | 4294967295 | ||
BIGINT | 8 | -9223372036854775808 | 9223372036854775807 |
0 | 18446744073709551615 |
浮點數: float、double、real、decimal
屬性 | 存儲空間 | 精度 | 精確性 | 說明 |
---|---|---|---|---|
FLOAT(M, D) | 4 bytes | 單精度 | 非精確 | 單精度浮點型,m總個數,d小數位 |
DOUBLE(M, D) | 8 bytes | 雙精度 | 比Float精度高 | 雙精度浮點型,m總個數,d小數位 |
FLOAT容易形成精度丟失
定點數DECIMAL
date、time、datetime、timestamp、year
類型 | 字節 | 例 | 精確性 |
---|---|---|---|
DATE | 三字節 | 2015-05-01 | 精確到年月日 |
TIME | 三字節 | 11:12:00 | 精確到時分秒 |
DATETIME | 八字節 | 2015-05-01 11::12:00 | 精確到年月日時分秒 |
TIMESTAMP | 2015-05-01 11::12:00 | 精確到年月日時分秒 |
5.6.4
版本以後,TIMESTAMP
和DATETIME
支持到微秒。TIMESTAMP
會根據系統時區進行轉換,DATETIME
則不會TIMESTAMP
存儲範圍:1970-01-01 00::00:01 to 2038-01-19 03:14:07DATETIME
的存儲範圍:1000-01-01 00:00:00 to 9999-12-31 23:59:59TIMESTAMP
國際化BIGINT
字符串: char、varchar 文本: tinytext、text、mediumtext、longtext
類型 | 單位 | 最大 | 特性 |
---|---|---|---|
CHAR | 字符 | 最大爲255字符 | 存儲定長,容易形成空間的浪費 |
VARCHAR | 字符 | 能夠超過255個字符 | 存儲變長,節省存儲空間 |
TEXT | 字節 | 總大小爲65535字節,約爲64KB | - |
tinyblob、blob、mediumblob、longblob
MVCC的實現,是經過保存數據在某個時間點的快照來實現的,根據事務開始時間的不一樣,每一個事務對於同一張表,同一時刻看到的數據多是不一樣的。
InnoDB的 MVCC ,是經過在每行記錄的後面保存兩個隱藏的列來實現的。這兩個列,一個保存了行的建立時間,一個保存了行的過時時間(或刪除時間), 固然存儲的並非實際的時間值,而是系統版本號。
能夠認爲MVCC是行級鎖的一個變種,可是它在不少狀況下避免了加鎖操做,所以開銷更低。雖然實現機制有所不一樣,但大都實現了非阻塞的讀操做,寫操做也只鎖定必要的行。
在MVCC協議下,每一個讀操做會看到一個一致性的 snapshot,而且能夠實現非阻塞的讀。MVCC 容許數據具備多個版本,這個版本能夠是時間戳或者是全局遞增的事務 ID,在同一個時間點,不一樣的事務看到的數據是不一樣的。
其中,寫操做(insert、delete和update)執行時,須要將系統版本號遞增。 因爲舊數據並不真正的刪除,因此必須對這些數據進行清理,innodb會開啓一個後臺線程執行清理工做,具體的規則是將刪除版本號小於當前系統版本的行刪除,這個過程叫作purge。 經過MVCC很好的實現了事務的隔離性,能夠達到repeated read級別,要實現serializable還必須加鎖。
MVCC只在READ COMMITED 和 REPEATABLE READ 兩個隔離級別下工做。READ UNCOMMITTED老是讀取最新的數據行,而不是符合當前事務版本的數據行。而SERIALIZABLE 則會對全部讀取的行都加鎖。
單條索引記錄上加鎖,InnoDB 的行鎖是經過索引實現的,如沒有索引,則鎖住的不是記錄行而是整個表。
間隙鎖,鎖定一個範圍,但不包括記錄自己。GAP鎖的目的,是爲了防止同一事務的兩次當前讀,出現幻讀的狀況。
Next-key lock 就是 Record lock + Gap lock 的組合,它鎖定的是一個範圍,而且鎖定記錄自己。對於行的查詢,都是採用該方法,主要目的是解決幻讀的問題。
mysql的事務隔離級別是可重複讀(RR,Repeatable Read),而且 innodb_locks_unsafe_for_binlog
參數設置爲0
truncate 和 delete只刪除數據,不刪除表結構 ,drop刪除表結構,而且釋放所佔的空間。
刪除數據的速度,通常來講: drop> truncate > delete
delete屬於DML語言,須要事務管理,commit以後才能生效。drop和truncate屬於DDL語言,操做馬上生效,不可回滾
使用場合:
explain 用於查看 SQL 語句執行計劃,其結果主要包含如下幾個重要參數:id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面對這些字段出現的可能進行解釋。
表示查詢中每一個select子句的類型
表示MySQL在表中找到所需行的方式,又稱「訪問類型」。
經常使用的類型有: ALL, index, range, ref, eq_ref, const, system, NULL(從左到右,性能從差到好)
指出MySQL能使用哪一個索引在表中找到記錄,查詢涉及到的字段上若存在索引,則該索引將被列出,但不必定被查詢使用 該列徹底獨立於EXPLAIN輸出所示的表的次序。這意味着在possible_keys中的某些鍵實際上不能按生成的表次序使用。 若是該列是NULL,則沒有相關的索引。在這種狀況下,能夠經過檢查WHERE子句看是否它引用某些列或適合索引的列來提升你的查詢性能。若是是這樣,創造一個適當的索引而且再次用EXPLAIN檢查查詢
key列顯示MySQL實際決定使用的鍵(索引) 若是沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。