1. 程式人生 > 實用技巧 >資料庫MySQL常見面試問題

資料庫MySQL常見面試問題

資料庫MySQL常見面試問題

1.MySQL 主鍵與索引的聯絡與區別

主鍵是為了標識資料庫記錄唯一性,不允許記錄重複,且鍵值不能為空,主鍵也是一個特殊索引。

資料表中只允許有一個主鍵,但是可以有多個索引。

使用主鍵會資料庫會自動建立主索引,也可以在非主鍵上建立索引,方便查詢效率。

索引可以提高查詢速度,它就相當於字典的目錄,可以通過它很快查詢到想要的結果,而不需要進行全表掃描。

主鍵索引外索引的值可以為空。

主鍵也可以由多個欄位組成,組成複合主鍵,同時主鍵肯定也是唯一索引。

唯一索引則表示該索引值唯一,可以由一個或幾個欄位組成,一個表可以有多個唯一索引。

2.資料庫索引是怎麼回事?用的啥資料結構 為什麼B+樹比B樹更合適

https://www.cnblogs.com/aspirant/p/9214485.html

一個索引是儲存的表中一個特定列的值資料結構(最常見的是B-Tree)。索引是在表的列上建立。所以,要記住的關鍵點是索引包含一個表中列的值,並且這些值儲存在一個數據結構中。請記住記住這一點:索引是一種資料結構 。

什麼樣的資料結構可以作為索引?

B-Tree 是最常用的用於索引的資料結構。因為它們是時間複雜度低, 查詢、刪除、插入操作都可以可以在對數時間內完成。另外一個重要原因儲存在B-Tree中的資料是有序的。資料庫管理系統(RDBMS)通常決定索引應該用哪些資料結構。但是,在某些情況下,你在建立索引時可以指定索引要使用的資料結構。

當我們利用索引查詢的時候,不可能把整個索引全部載入到記憶體,只能逐一載入每個磁碟頁,磁碟頁對應索引樹的節點。那麼Mysql衡量查詢效率的標準就是磁碟IO次數。如果我們利用二叉樹作為索引結構,那麼磁碟的IO次數和索引樹的高度是相關的。

那麼為了提高查詢效率,就需要減少磁碟IO數。為了減少磁碟IO的次數,就需要儘量降低樹的高度,需要把原來“瘦高”的樹結構變的“矮胖”,樹的每層的分叉越多越好,因此B樹正好符合我們的要求,這也是B-樹的特徵之一。

B樹 B樹的節點為關鍵字和相應的資料(索引等)

B+樹 B+樹是B樹的一個變形,非葉子節點只儲存索引,不儲存實際的資料,資料都儲存在葉子節點中,B+樹的葉子節點為連結串列

連結串列放資料,非葉子節點是索引。

對比

1.B樹和B+樹同樣適用於高度越低,查詢越快。

2.B樹查詢節點,B+樹只需要查詢所有節點(索引),B樹查詢索引和資料。雖然可能第一個就找到,但在極端情況下,需要全查詢索引和資料,不如B+樹穩定。

3.B+樹和B樹比,B+樹的硬碟空間更少,io的讀寫代價更低。因為B+樹節點只有索引,佔位更少。在查詢的情況下硬碟指標移動更低

雜湊表索引是怎麼工作的?

雜湊表是另外一種你可能看到用作索引的資料結構-這些索引通常被稱為雜湊索引。使用雜湊索引的原因是,在尋找值時雜湊表效率極高。所以,如果使用雜湊索引,對於比較字串是否相等的查詢能夠極快的檢索出的值。例如之前我們討論過的這個查詢(SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’) 就可以受益於建立在Employee_Name 列上的雜湊索引。哈系索引的工作方式是將列的值作為索引的鍵值(key),和鍵值相對應實際的值(value)是指向該表中相應行的指標。因為雜湊表基本上可以看作是關聯陣列,一個典型的資料項就像“Jesus => 0x28939″,而0x28939是對記憶體中表中包含Jesus這一行的引用。在哈系索引的中查詢一個像“Jesus”這樣的值,並得到對應行的在記憶體中的引用,明顯要比掃描全表獲得值為“Jesus”的行的方式快很多。

雜湊索引的缺點

雜湊表是無順的資料結構,對於很多型別的查詢語句雜湊索引都無能為力。舉例來說,假如你想要找出所有小於40歲的員工。你怎麼使用使用雜湊索引進行查詢?這不可行,因為雜湊表只適合查詢鍵值對-也就是說查詢相等的查詢(例:like “WHERE name = ‘Jesus’)。雜湊表的鍵值對映也暗示其鍵的儲存是無序的。這就是為什麼雜湊索引通常不是資料庫索引的預設資料結構-因為在作為索引的資料結構時,其不像B-Tree那麼靈活

3.建立索引的注意事項

索引可以提高資料的訪問速度,但同時也增加了插入、更新和刪除操作的處理時間,解決此問題就是分析應用程式的業務處理、資料使用,為經常被用作查詢條件、或者被要求排序的欄位建立索引。索引是建立在資料庫表中的某些列的上面。因此,在建立索引的時候,應該仔細考慮在哪些列上可以建立索引,在哪些列上不能建立索引。

建立規則:

1、表的主鍵、外來鍵必須有索引;

2、資料量超過300的表應該有索引;

3、經常與其他表進行連線的表,在連線欄位上應該建立索引;

4、經常出現在Where子句中的欄位,特別是大表的欄位,應該建立索引;

5、索引應該建在選擇性高的欄位上;

6、索引應該建在小欄位上,對於大的文字欄位甚至超長欄位,不要建索引;

7、複合索引的建立需要進行仔細分析;儘量考慮用單欄位索引代替

8、頻繁進行資料操作的表,不要建立太多的索引;

9、刪除無用的索引,避免對執行計劃造成負面影響;

建立索引需要注意的地方:

  1. 限制表上的索引數目。對一個存在大量更新操作的表,所建索引的數目一般不要超過3個,最多不要超過5個。索引雖說提高了訪問速度,但太多索引會影響資料的更新操作。

  2. 避免在取值朝一個方向增長的欄位(例如:日期型別的欄位)上,建立索引;對複合索引,避免將這種型別的欄位放置在最前面

  3. 對複合索引,按照欄位在查詢條件中出現的頻度建立索引

  4. 刪除不再使用,或者很少被使用的索引。

4.MYSQL事務特性和實現原理

ACID表示原子性(atomicity)、一致性(consistency)、隔離性(isolation)和永續性(durability)。一個很好的事務處理系統,必須具備這些標準特性:

原子性(atomicity)

一個事務必須被視為一個不可分割的最小工作單元,整個事務中的所有操作要麼全部提交成功,要麼全部失敗回滾,對於一個事務來說,不可能只執行其中的一部分操作,這就是事務的原子性

是利用Innodb的undo log。undo log名為回滾日誌,是實現原子性的關鍵,當事務回滾時能夠撤銷所有已經成功執行的sql語句,他需要記錄你要回滾的相應日誌資訊。

一致性(consistency)

資料庫總是從一個一致性的狀態轉換到另一個一致性的狀態。(在前面的例子中,一致性確保了,即使在執行第三、四條語句之間時系統崩潰,支票賬戶中也不會損失200美元,因為事務最終沒有提交,所以事務中所做的修改也不會儲存到資料庫中。)

資料庫通過原子性、隔離性、永續性來保證一致性

隔離性(isolation)

通常來說,一個事務所做的修改在最終提交以前,對其他事務是不可見的。(在前面的例子中,當執行完第三條語句、第四條語句還未開始時,此時有另外的一個賬戶彙總程式開始執行,則其看到支票帳戶的餘額並沒有被減去200美元。)

利用的是鎖和MVCC機制。MVCC,即多版本併發控制(Multi Version Concurrency Control),一個行記錄資料有多個版本對快照資料,這些快照資料在undo log中。如果一個事務讀取的行正在做DELELE或者UPDATE操作,讀取操作不會等行上的鎖釋放,而是讀取該行的快照版本。

永續性(durability)

一旦事務提交,則其所做的修改會永久儲存到資料庫。(此時即使系統崩潰,修改的資料也不會丟失。永續性是個有佔模糊的概念,因為實際上永續性也分很多不同的級別。有些永續性策略能夠提供非常強的安全保障,而有些則未必,而且不可能有能做到100%的永續性保證的策略。)

是利用Innodb的redo log。當做資料修改的時候,不僅在記憶體中操作,還會在redo log中記錄這次操作。當事務提交的時候,會將redo log日誌進行刷盤(redo log一部分在記憶體中,一部分在磁碟上)。當資料庫宕機重啟的時候,會將redo log中的內容恢復到資料庫中,再根據undo log和binlog內容決定回滾資料還是提交資料。redo log體積小,刷盤快。redo log是一直往末尾進行追加,屬於順序IO。效率顯然比隨機IO來的快

5.redis的原理和優點

redis是一個key-value儲存系統.和Memcached類似,它支援儲存的value型別相對更多,包括string(字串)、list(連結串列)、set(集合)、zset(sorted set --有序集合)和hashs(雜湊型別)

這些資料型別都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的.

在此基礎上,redis支援各種不同方式的排序.與memcached一樣,為了保證效率,資料都是快取在記憶體中.區別的是redis會週期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步.

Redis的優點:

效能極高 – Redis能支援超過 100K+ 每秒的讀寫頻率。

豐富的資料型別 – Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。

原子 – Redis的所有操作都是原子性的,同時Redis還支援對幾個操作全並後的原子性執行。

豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。

6.Mysql中的鎖機制

Mysql用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。這些鎖統稱為悲觀鎖

MySQL的鎖機制比較簡單,其最 顯著的特點是不同的儲存引擎支援不同的鎖機制。比如,MyISAM和MEMORY儲存引擎採用的是表級鎖(table-level locking);BDB儲存引擎採用的是頁面鎖(page-level locking),但也支援表級鎖;InnoDB儲存引擎既支援行級鎖(row-level locking),也支援表級鎖,但預設情況下是採用行級鎖。

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。

行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般

從上述特點可見,很難籠統地說哪種鎖更好,只能就具體應用的特點來說哪種鎖更合適!僅從鎖的角度 來說:表級鎖更適合於以查詢為主,只有少量按索引條件更新資料的應用,如Web應用;而行級鎖則更適合於有大量按索引條件併發更新少量不同資料,同時又有 併發查詢的應用,如一些線上事務處理(OLTP)系統。

7.ABC聯合索引生效問題

對於複合索引:Mysql從左到右的使用索引中的欄位,一個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c)。 可以支援a | a,b| a,b,c 3種組合進行查詢,但不支援 b,c進行查詢 .當最左側欄位是常量引用時,索引就十分有效。

以下是一些例子:

複製程式碼

select * from myTest where a=3 and b=5 and c=4; ---- abc順序 abc三個索引都在where條件裡面用到了,而且都發揮了作用``
select * from myTest where c=4 and b=6 and a=3; where裡面的條件順序在查詢之前會被mysql自動優化,效果跟上一句一樣 ``
select * from myTest where a=3 and c=7; a用到索引,b沒有用,所以c是沒有用到索引效果的(b沒有使用到,所以索引達不到 c ,所以c未使用索引) ``
select * from myTest where a=3 and b>7 and c=3; ---- b範圍值,斷點,阻塞了c的索引 a用到了,b也用到了,c沒有用到,這個地方b是範圍值,也算斷點,只不過自身用到了索引 ``
select * from myTest where b=3 and c=4; — 聯合索引必須按照順序使用,並且需要全部使用 因為a索引沒有使用,所以這裡 bc都沒有用上索引效果 ``
select * from myTest where a>4 and b=7 and c=9; a用到了 b沒有使用,c沒有使用(a用了範圍所以,相當於斷點,之後的b,c都沒有用到索引) ``
select * from myTest where a=3 order by b; a用到了索引,b在結果排序中也用到了索引的效果,a下面任意一段的b是排好序的 ``
select * from myTest where a=3 order by c; a用到了索引,但是這個地方c沒有發揮排序效果,因為中間斷點了,使用 explain 可以看到 filesort ``
select * from mytable where b=3 order by a; b沒有用到索引,排序中a也沒有發揮索引效果

以下條件會導致索引失效:

1.不在索引列上做任何操作(計算、函式、(自動or手動)型別轉換),會導致索引失效而轉向全表掃描

2.儲存引擎不能使用索引範圍條件右邊的列(例如 只用到b , c)

3.儘量使用覆蓋索引(只訪問索引的查詢(索引列和查詢列一致)),減少select ***

4.mysql在使用不等於(!=或者<>)的時候**無法使用索引會導致全表掃描

5.is null,is not null也無法使用索引

6.ike以萬用字元開頭(’%abc…’)mysql索引失效會變成全表掃描的操作。問題:解決like‘%字串%’時索引不被使用的方法

8.資料庫事務隔離級別

一般的資料庫,都包括以下四種隔離級別:

讀未提交(Read Uncommitted)

讀提交(Read Committed)

可重複讀(Repeated Read)

序列化(Serializable)

事務沒有隔離存在的問題:

髒讀:事務A添加了資料庫但是沒有提交事務,事務B也可以查詢到

不可重複讀: 事務A修改資料庫,導致事務B兩次的查詢結果不一樣。不可重複讀的重點是修改: 同樣的條件, 你讀取過的資料, 再次讀取出來發現值不一樣了

幻讀:事務A新增或刪除資料庫,導致事務B兩次的查詢結果不一樣。幻讀的重點在於新增或者刪除 (資料條數變化)。同樣的條件, 第1次和第2次讀出來的記錄數不一樣

(1).讀未提交(Read Uncommitted)

讀未提交,就是可以讀到未提交的內容。因此,在這種隔離級別下,查詢是不會加鎖的,也由於查詢的不加鎖,所以這種隔離級別的一致性是最差的,可能會產生“髒讀”、“不可重複讀”、“幻讀”。如無特殊情況,基本是不會使用這種隔離級別的。

(2).讀提交(Read Committed)

大部分資料庫採用的預設隔離級別。一個事務的更新操作結果只有在該事務提交之後,另一個事務才可以的讀取到同一筆資料更新後的結果。

那為什麼“讀提交”同“讀未提交”一樣,都沒有查詢加鎖,但是卻能夠避免髒讀呢?

這就要說道另一個機制“快照(snapshot)”,而這種既能保證一致性又不加鎖的讀也被稱為“快照讀(Snapshot Read)”

假設沒有“快照讀”,那麼當一個更新的事務沒有提交時,另一個對更新資料進行查詢的事務會因為無法查詢而被阻塞,這種情況下,併發能力就相當的差。

而“快照讀”就可以完成高併發的查詢,不過,“讀提交”只能避免“髒讀”,並不能避免“不可重複讀”和“幻讀”。

(3).可重複讀(Repeated Read)

可重複讀,就是專門針對“不可重複讀”這種情況而制定的隔離級別,自然,它就可以有效的避免“不可重複讀”。mysql的預設級別。整個事務過程中,對同一筆資料的讀取結果是相同的,不管其他事務是否在對共享資料進行更新,也不管更新提交與否。

在這個級別下,普通的查詢同樣是使用的“快照讀”,但是,和“讀提交”不同的是,當事務啟動時,就不允許進行“修改操作(Update)”了,而“不可重複讀”恰恰是因為兩次讀取之間進行了資料的修改,因此,“可重複讀”能夠有效的避免“不可重複讀”,但卻避免不了“幻讀”,因為幻讀是由於“插入或者刪除操作(Insert or Delete)”而產生的。

(4).序列化(Serializable)

這是資料庫最高的隔離級別,這種級別下,事務“序列化順序執行”,也就是一個一個排隊執行。

這種級別下,“髒讀”、“不可重複讀”、“幻讀”都可以被避免,但是執行效率奇差,效能開銷也最大,所以基本沒人會用。

9. Mysql之drop、delete、truncate的區別

一、不同點

1.truncate table 和 delete只刪除記錄不刪除表的結構,drop語句將刪除表的結構依賴的約束(constrain),觸發器(trigger),索引(index);

語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger),索引(index);依賴於該表的儲存過程/函式將保留,但是變為invalid狀態

2.truncate之後的自增欄位從頭開始計數了,而delete的仍保留原來的最在數值。

二、 總結:

1.在速度上,一般來說,drop> truncate > delete。

2.在使用drop和truncate時一定要注意,雖然可以恢復,但為了減少麻煩,還是要慎重。

3.如果想刪除部分資料用delete,注意帶上where子句,回滾段要足夠大;

如果想刪除表,當然用drop;

如果想保留表而將所有資料刪除,如果和事務無關,用truncate即可;

如果和事務有關,或者想觸發trigger,還是用delete

如果是整理表內部的碎片,可以用truncate跟上reuse stroage,再重新匯入/插入資料

10. Mysql之儲存引擎

資料庫儲存引擎是資料庫底層軟體組織,資料庫管理系統(DBMS)使用資料引擎進行建立、查詢、更新和刪除資料。不同的儲存引擎提供不同的儲存機制、索引技巧、鎖定水平等功能,使用不同的儲存引擎,還可以獲得特定的功能。

InnoDB儲存引擎

InnoDB是事務型資料庫的首選引擎,通過上圖也看到了,InnoDB是目前MYSQL的預設事務型引擎,是目前最重要、使用最廣泛的儲存引擎。支援事務安全表(ACID),支援行鎖定和外來鍵。InnoDB主要特性有:

1、InnoDB給MySQL提供了具有提交、回滾和崩潰恢復能力的事物安全(ACID相容)儲存引擎。InnoDB鎖定在行級並且也在SELECT語句中提供一個類似Oracle的非鎖定讀。這些功能增加了多使用者部署和效能。在SQL查詢中,可以自由地將InnoDB型別的表和其他MySQL的表型別混合起來,甚至在同一個查詢中也可以混合

2、InnoDB是為處理巨大資料量的最大效能設計。它的CPU效率可能是任何其他基於磁碟的關係型資料庫引擎鎖不能匹敵的

3、InnoDB儲存引擎完全與MySQL伺服器整合,InnoDB儲存引擎為在主記憶體中快取資料和索引而維持它自己的緩衝池。InnoDB將它的表和索引在一個邏輯表空間中,表空間可以包含數個檔案(或原始磁碟檔案)。這與MyISAM表不同,比如在MyISAM表中每個表被存放在分離的檔案中。InnoDB表可以是任何尺寸,即使在檔案尺寸被限制為2GB的作業系統上

4、InnoDB支援外來鍵完整性約束,儲存表中的資料時,每張表的儲存都按主鍵順序存放,如果沒有顯示在表定義時指定主鍵,InnoDB會為每一行生成一個6位元組的ROWID,並以此作為主鍵

5、InnoDB被用在眾多需要高效能的大型資料庫站點上

InnoDB不建立目錄,使用InnoDB時,MySQL將在MySQL資料目錄下建立一個名為ibdata1的10MB大小的自動擴充套件資料檔案,以及兩個名為ib_logfile0和ib_logfile1的5MB大小的日誌檔案。

場景:由於其支援事務處理,支援外來鍵,支援崩潰修復能力和併發控制。如果需要對事務的完整性要求比較高(比如銀行),要求實現併發控制(比如售票),那選擇InnoDB有很大的優勢。如果需要頻繁的更新、刪除操作的資料庫,也可以選擇InnoDB,因為支援事務的提交(commit)和回滾(rollback)。

MyISAM儲存引擎

MyISAM基於ISAM儲存引擎,並對其進行擴充套件。它是在Web、資料倉儲和其他應用環境下最常使用的儲存引擎之一。

MyISAM擁有較高的插入、查詢速度,但不支援事物和外來鍵。

MyISAM主要特性有:

1、大檔案(達到63位檔案長度)在支援大檔案的檔案系統和作業系統上被支援

2、當把刪除和更新及插入操作混合使用的時候,動態尺寸的行產生更少碎片。這要通過合併相鄰被刪除的塊,以及若下一個塊被刪除,就擴充套件到下一塊自動完成

3、每個MyISAM表最大索引數是64,這可以通過重新編譯來改變。每個索引最大的列數是16

4、最大的鍵長度是1000位元組,這也可以通過編譯來改變,對於鍵長度超過250位元組的情況,一個超過1024位元組的鍵將被用上

5、BLOB和TEXT列可以被索引,支援FULLTEXT型別的索引,而InnoDB不支援這種型別的索引

6、NULL被允許在索引的列中,這個值佔每個鍵的0~1個位元組

7、所有數字鍵值以高位元組優先被儲存以允許一個更高的索引壓縮

8、每個MyISAM型別的表都有一個AUTO_INCREMENT的內部列,當INSERT和UPDATE操作的時候該列被更新,同時AUTO_INCREMENT列將被重新整理。所以說,MyISAM型別表的AUTO_INCREMENT列更新比InnoDB型別的AUTO_INCREMENT更快

9、可以把資料檔案和索引檔案放在不同目錄

10、每個字元列可以有不同的字符集

11、有VARCHAR的表可以固定或動態記錄長度

12、VARCHAR和CHAR列可以多達64KB

儲存格式:

1、靜態表(預設):欄位都是非變長的(每個記錄都是固定長度的)。儲存非常迅速、容易快取,出現故障容易恢復;佔用空間通常比動態表多。

2、動態表:佔用的空間相對較少,但是頻繁的更新刪除記錄會產生碎片,需要定期執行optimize table或myisamchk -r命令來改善效能,而且出現故障的時候恢復比較困難。

3、壓縮表:使用myisampack工具建立,佔用非常小的磁碟空間。因為每個記錄是被單獨壓縮的,所以只有非常小的訪問開支。

靜態表的資料在儲存的時候會按照列的寬度定義補足空格,在返回資料給應用之前去掉這些空格。如果需要儲存的內容後面本來就有空格,在返回結果的時候也會被去掉。(其實是資料型別char的行為,動態表中若有這個資料型別也同樣會有這個問題)

使用MyISAM引擎建立資料庫,將產生3個檔案。檔案的名字以表名字開始,副檔名之處檔案型別:frm檔案儲存表定義、資料檔案的副檔名為.MYD(MYData)、索引檔案的副檔名時.MYI(MYIndex)。

場景:如果表主要是用於插入新記錄和讀出記錄,那麼選擇MyISAM能實現處理高效率。

MERGE儲存引擎

MERGE儲存引擎是一組MyISAM表的組合,這些MyISAM表結構必須完全相同,儘管其使用不如其它引擎突出,但是在某些情況下非常有用。說白了,Merge表就是幾個相同MyISAM表的聚合器;Merge表中並沒有資料,對Merge型別的表可以進行查詢、更新、刪除操作,這些操作實際上是對內部的MyISAM表進行操作。

場景:對於伺服器日誌這種資訊,一般常用的儲存策略是將資料分成很多表,每個名稱與特定的時間端相關。例如:可以用12個相同的表來儲存伺服器日誌資料,每個表用對應各個月份的名字來命名。當有必要基於所有12個日誌表的資料來生成報表,這意味著需要編寫並更新多表查詢,以反映這些表中的資訊。與其編寫這些可能出現錯誤的查詢,不如將這些表合併起來使用一條查詢,之後再刪除Merge表,而不影響原來的資料,刪除Merge表只是刪除Merge表的定義,對內部的表沒有任何影響。

MEMORY儲存引擎

MEMORY儲存引擎將表中的資料儲存到記憶體中,未查詢和引用其他表資料提供快速訪問。MEMORY主要特性有:

1、MEMORY表的每個表可以有多達32個索引,每個索引16列,以及500位元組的最大鍵長度

2、MEMORY儲存引擎執行HASH和BTREE縮影

3、可以在一個MEMORY表中有非唯一鍵值

4、MEMORY表使用一個固定的記錄長度格式

5、MEMORY不支援BLOB或TEXT列

6、MEMORY支援AUTO_INCREMENT列和對可包含NULL值的列的索引

7、MEMORY表在所由客戶端之間共享(就像其他任何非TEMPORARY表)

8、MEMORY表記憶體被儲存在記憶體中,記憶體是MEMORY表和伺服器在查詢處理時的空閒中,建立的內部表共享

9、當不再需要MEMORY表的內容時,要釋放被MEMORY表使用的記憶體,應該執行DELETE FROM或TRUNCATE TABLE,或者刪除整個表(使用DROP TABLE)

MEMORY儲存引擎預設使用雜湊(HASH)索引,其速度比使用B+Tree型要快,但也可以使用B樹型索引。由於這種儲存引擎所儲存的資料儲存在記憶體中,所以其儲存的資料具有不穩定性,比如如果mysqld程序發生異常、重啟或計算機關機等等都會造成這些資料的消失,所以這種儲存引擎中的表的生命週期很短,一般只使用一次。現在mongodb、redis等NOSQL資料庫愈發流行,MEMORY儲存引擎的使用場景越來越少。

場景:如果需要該資料庫中一個用於查詢的臨時表。

ARCHIVE儲存引擎

Archive是歸檔的意思,在歸檔之後很多的高階功能就不再支援了,僅僅支援最基本的插入和查詢兩種功能。在MySQL 5.5版以前,Archive是不支援索引,但是在MySQL 5.5以後的版本中就開始支援索引了。Archive擁有很好的壓縮機制,它使用zlib壓縮庫,在記錄被請求時會實時壓縮,所以它經常被用來當做倉庫使用。

場景:由於高壓縮和快速插入的特點Archive非常適合作為日誌表的儲存引擎,但是前提是不經常對該表進行查詢操作。

11.常見的關係型資料庫和非關係型資料庫

關係型資料庫: 採用了關係模型來組織資料的資料庫

非關係型資料庫:用於儲存那些型別不固定的,也沒有什麼規律的資料。

資料庫 型別 特性 優點 缺點
關係型資料庫 SQLite、Oracle、mysql 1、關係型資料庫,是指採用了關係模型來組織 資料的資料庫; 2、關係型資料庫的最大特點就是事務的一致性; 3、簡單來說,關係模型指的就是二維表格模型, 而一個關係型資料庫就是由二維表及其之間的聯絡所組成的一個數據組織。 1. 用的都是表結構,比較容易理解 2. 使用的是通用的SQL語言 3. 減少了資料的冗餘和資料不一致的情況發生 4. 可以進行表或者多個表之間的複雜查詢 1. 固定的表結構,靈活性欠缺 2. 為了維持表結構而犧牲了讀寫效能 3. 高併發讀寫能力較差
非關係型資料庫 MongoDb、redis、HBase 1、使用鍵值對儲存資料; 2、分散式; 3、一般不支援ACID特性; 4、非關係型資料庫嚴格上不是一種資料庫,應該是一種資料結構化儲存方法的集合。 1. 格式靈活,資料型別多種多樣,可以是鍵對值,甚至是文件,圖片,應用場景廣泛,但是關係型資料庫只支援原有的資料型別 2. 由於是非關係型,資料沒有耦合性,容易擴充套件 3. 無須通過sql層的解析,讀寫能力較高 4. 成本低,nosql資料庫部署簡單,基本都是開源軟體 1. 不提供sql支援,學習成本高 2. 無事務支援 3. 由於資料型別靈活,也導致了資料結構相對複雜,在複雜查詢方面比較麻煩

12. Mysql的索引比較

普通索引:最基本的索引,沒有任何限制

唯一索引:與"普通索引"類似,不同的就是:索引列的值必須唯一,但允許有空值。

主鍵索引:主鍵索引(主索引)是唯一索引的特定型別。表中建立主鍵時自動建立的索引 。一個表只能建立一個主索引。不允許有空值。

全文索引:僅可用於 MyISAM 表,針對較大的資料,生成全文索引很耗時好空間。

組合索引:為了更多的提高mysql效率可建立組合索引,遵循”最左字首“原則。

聚集索引:聚集索引的作用物件是一張表資料的實體地址,聚集索引使得資料按照實體地址順序的儲存在儲存介質中,資料的實體地址也是連續的,因此聚集索引是查詢速度最快的索引,其查詢原理是二分法。

非聚集索引:非聚集索引定義的原則往往是基於業務邏輯。非聚集索引在實體地址上不相鄰,更像是一個數據字典索引。非聚集索引速度比聚集索引慢,但是一個表中非聚集可以建立多個。

聚集索引和非聚集索引的區別:

聚集索引和非聚集索引的根本區別是表中記錄的物理順序和索引的排列順序是否一致。

1.聚集索引表中記錄的物理順序與鍵值的索引順序相同。

1)聚集索引的表中記錄的物理順序與索引的排列順序一致

優點:查詢速度快,因為一旦具有第一個索引值的記錄被找到,具有連續索引值的記錄也一定物理的緊跟其後。

缺點:對錶進行修改速度較慢,這是為了保持表中的記錄的物理順序與索引的順序一致,而把記錄插入到資料頁的相應位置, 必須在資料頁中進行資料重排,降低了執行速度。在插入新記錄時資料檔案為了維持 B+Tree 的特性而頻繁的分裂調整,十分低效。

使用聚集索引的場合為:

A.某列包含了小數目的不同值。

B.排序和範圍查詢。

2) 非聚集索引的記錄的物理順序和索引的順序不一致

使用非聚集索引的場合為:

a.此列包含了大數目的不同值;

b.頻繁更新的列

2.一個表只能有一個聚集索引。一個表中可以擁有多個非聚集索引

3.聚集索引和非聚集索引都採用了 B+樹的結構,但非聚集索引的葉子層並不與實際的資料頁相重疊,而採用中的記錄在葉子層包含一個指向表資料頁中的指標的方式。 非聚集索引的儲存結構與前面是一樣的,不同的是在葉子結點的資料部分存的不再是具體的資料,而資料的聚集索引的key。所以通過非聚集索引查詢的過程是先找到該索引key對應的聚集索引的key,然後再拿聚集索引的key到主鍵索引樹上查詢對應的資料,這個過程稱為 回表

4.非聚集索引新增記錄時,不會引起資料順序的重組。

主鍵索引和唯一索引的區別:

(1) 對於主鍵/unique constraint , oracle/sql server/mysql等都會自動建立唯一索引;

(2) 主鍵不一定只包含一個欄位,所以在主鍵的其中一個欄位建唯一索引還是有必要的;

(3) 主鍵可作外來鍵,唯一索引不可;

(4) 主鍵不可為空,唯一索引可;

(5) 主鍵可是多個欄位的組合;

(6) 主鍵索引一定是唯一索引, 唯一索引不是主鍵索引

(7) 主鍵可以與外來鍵 構成 參照完整性約束, 防止資料不一致

13.等值查詢和範圍查詢

等值查詢索引結構 hash比較好

範圍查詢-- b+樹

14. union和union all的區別

UNION用的比較多union all是直接連線,取到得是所有值,記錄可能有重複 union 是取唯一值,記錄沒有重複

1、UNION 的語法如下: [SQL 語句 1] UNION [SQL 語句 2] 2、UNION ALL 的語法如下: [SQL 語句 1] UNION ALL [SQL 語句 2] 效率: UNION和UNION ALL關鍵字都是將兩個結果集合併為一個,但這兩者從使用和效率上來說都有所不同。 1、對重複結果的處理:UNION在進行錶鏈接後會篩選掉重複的記錄,Union All不會去除重複記錄。 2、對排序的處理:Union將會按照欄位的順序進行排序;UNION ALL只是簡單的將兩個結果合併後就返回。 從效率上說,UNION ALL 要比UNION快很多,所以,如果可以確認合併的兩個結果集中不包含重複資料且不需要排序時的話,那麼就使用UNION ALL。

15. 回表查詢

InnoDB聚集索引的葉子節點儲存行記錄,因此InnoDB必須要有且只有一個聚集索引。

而innodb普通索引的葉子節點儲存主鍵值,普通索引因為無法直接定位行記錄,其查詢過程在通常情況下是需要掃描兩遍索引樹的。第一遍先通過普通索引定位到主鍵值id=5,然後第二遍再通過聚集索引定位到具體行記錄。這就是所謂的回表查詢,即先定位主鍵值,再根據主鍵值定位行記錄,效能相對於只掃描一遍聚集索引樹的效能要低一些。

索引覆蓋

索引覆蓋是一種避免回表查詢的優化策略。具體的做法就是將要查詢的資料作為索引列建立普通索引(可以是單列索引,也可以一個索引語句定義所有要查詢的列,即聯合索引),這樣的話就可以直接返回索引中的的資料,不需要再通過聚集索引去定位行記錄,避免了回表的情況發生。

覆蓋索引的優點

1.索引條目通常遠小於資料行的大小,因為覆蓋索引只需要讀取索引,極大地減少了資料的訪問量。

2.索引是按照列值順序儲存的,對於IO密集的範圍查詢會比隨機從磁碟讀取每一行資料的IO小很多。

3.一些儲存引擎比如MyISAM在記憶體中只快取索引,資料則依賴作業系統來快取,因此要訪問資料的話需要一次系統呼叫,使用覆蓋索引則避免了這一點。

4.由於InnoDB的聚簇索引,覆蓋索引對InnoDB引擎下的資料庫表特別有用。因為InnoDB的二級索引在葉子節點中儲存了行的主鍵值,如果二級索引能夠覆蓋查詢,就避免了對主鍵索引的二次查詢。