mysql數據庫集群面試題,測試工程師mysql數據庫面試題

本文目錄一覽:

15個 MySQL 基礎面試題,DBA 們準備好了嗎

高級操作 1.Mysql 主從同步配置 2.Mysql 雙master 配置 3.Mysql 雙master+叢庫+keepalived 配置高可用數據庫 客戶端 作為DBA,一定不要用各種GUI工具,mysql自帶命令行client才是你的最佳武器 可選項 1.mysql 分區配置

面試中常問:mysql數據庫做哪些優化也提高mysql性能

在開始演示之前,我們先介紹下兩個概念。

概念一,數據的可選擇性基數,也就是常說的cardinality值。

查詢優化器在生成各種執行計劃之前,得先從統計信息中取得相關數據,這樣才能估算每步操作所涉及到的記錄數,而這個相關數據就是cardinality。簡單來說,就是每個值在每個字段中的唯一值分布狀態。

比如表t1有100行記錄,其中一列為f1。f1中唯一值的個數可以是100個,也可以是1個,當然也可以是1到100之間的任何一個數字。這裡唯一值越的多少,就是這個列的可選擇基數。

那看到這裡我們就明白了,為什麼要在基數高的字段上建立索引,而基數低的的字段建立索引反而沒有全表掃描來的快。當然這個只是一方面,至於更深入的探討就不在我這篇探討的範圍了。

概念二,關於HINT的使用。

這裡我來說下HINT是什麼,在什麼時候用。

HINT簡單來說就是在某些特定的場景下人工協助MySQL優化器的工作,使她生成最優的執行計劃。一般來說,優化器的執行計劃都是最優化的,不過在某些特定場景下,執行計劃可能不是最優化。

比如:表t1經過大量的頻繁更新操作,(UPDATE,DELETE,INSERT),cardinality已經很不準確了,這時候剛好執行了一條SQL,那麼有可能這條SQL的執行計劃就不是最優的。為什麼說有可能呢?

來看下具體演示

譬如,以下兩條SQL,

A:

select * from t1 where f1 = 20;

B:

select * from t1 where f1 = 30;

如果f1的值剛好頻繁更新的值為30,並且沒有達到MySQL自動更新cardinality值的臨界值或者說用戶設置了手動更新又或者用戶減少了sample page等等,那麼對這兩條語句來說,可能不準確的就是B了。

這裡順帶說下,MySQL提供了自動更新和手動更新表cardinality值的方法,因篇幅有限,需要的可以查閱手冊。

那回到正題上,MySQL 8.0 帶來了幾個HINT,我今天就舉個index_merge的例子。

示例表結構:

mysql desc t1;+————+————–+——+—–+———+—————-+| Field      | Type         | Null | Key | Default | Extra          |+————+————–+——+—–+———+—————-+| id         | int(11)      | NO   | PRI | NULL    | auto_increment || rank1      | int(11)      | YES  | MUL | NULL    |                || rank2      | int(11)      | YES  | MUL | NULL    |                || log_time   | datetime     | YES  | MUL | NULL    |                || prefix_uid | varchar(100) | YES  |     | NULL    |                || desc1      | text         | YES  |     | NULL    |                || rank3      | int(11)      | YES  | MUL | NULL    |                |+————+————–+——+—–+———+—————-+7 rows in set (0.00 sec)

表記錄數:

mysql select count(*) from t1;+———-+| count(*) |+———-+|    32768 |+———-+1 row in set (0.01 sec)

這裡我們兩條經典的SQL:

SQL C:

select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;

SQL D:

select * from t1 where rank1 =100  and rank2 =100  and rank3 =100;

表t1實際上在rank1,rank2,rank3三列上分別有一個二級索引。

那我們來看SQL C的查詢計劃。

顯然,沒有用到任何索引,掃描的行數為32034,cost為3243.65。

mysql explain  format=json select * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “3243.65”    },    “table”: {      “table_name”: “t1”,      “access_type”: “ALL”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “rows_examined_per_scan”: 32034,      “rows_produced_per_join”: 115,      “filtered”: “0.36”,      “cost_info”: {        “read_cost”: “3232.07”,        “eval_cost”: “11.58”,        “prefix_cost”: “3243.65”,        “data_read_per_join”: “49K”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))”    }  }}1 row in set, 1 warning (0.00 sec)

我們加上hint給相同的查詢,再次看看查詢計劃。

這個時候用到了index_merge,union了三個列。掃描的行數為1103,cost為441.09,明顯比之前的快了好幾倍。

mysql explain  format=json select /*+ index_merge(t1) */ * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “441.09”    },    “table”: {      “table_name”: “t1”,      “access_type”: “index_merge”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “key”: “union(idx_rank1,idx_rank2,idx_rank3)”,      “key_length”: “5,5,5”,      “rows_examined_per_scan”: 1103,      “rows_produced_per_join”: 1103,      “filtered”: “100.00”,      “cost_info”: {        “read_cost”: “330.79”,        “eval_cost”: “110.30”,        “prefix_cost”: “441.09”,        “data_read_per_join”: “473K”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))”    }  }}1 row in set, 1 warning (0.00 sec)

我們再看下SQL D的計劃:

不加HINT,

mysql explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “534.34”    },    “table”: {      “table_name”: “t1”,      “access_type”: “ref”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “key”: “idx_rank1”,      “used_key_parts”: [        “rank1”      ],      “key_length”: “5”,      “ref”: [        “const”      ],      “rows_examined_per_scan”: 555,      “rows_produced_per_join”: 0,      “filtered”: “0.07”,      “cost_info”: {        “read_cost”: “478.84”,        “eval_cost”: “0.04”,        “prefix_cost”: “534.34”,        “data_read_per_join”: “176”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))”    }  }}1 row in set, 1 warning (0.00 sec)

加了HINT,

mysql explain format=json select /*+ index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {  “query_block”: {    “select_id”: 1,    “cost_info”: {      “query_cost”: “5.23”    },    “table”: {      “table_name”: “t1”,      “access_type”: “index_merge”,      “possible_keys”: [        “idx_rank1”,        “idx_rank2”,        “idx_rank3”      ],      “key”: “intersect(idx_rank1,idx_rank2,idx_rank3)”,      “key_length”: “5,5,5”,      “rows_examined_per_scan”: 1,      “rows_produced_per_join”: 1,      “filtered”: “100.00”,      “cost_info”: {        “read_cost”: “5.13”,        “eval_cost”: “0.10”,        “prefix_cost”: “5.23”,        “data_read_per_join”: “440”      },      “used_columns”: [        “id”,        “rank1”,        “rank2”,        “log_time”,        “prefix_uid”,        “desc1”,        “rank3”      ],      “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))”    }  }}1 row in set, 1 warning (0.00 sec)

對比下以上兩個,加了HINT的比不加HINT的cost小了100倍。

總結下,就是說表的cardinality值影響這張的查詢計劃,如果這個值沒有正常更新的話,就需要手工加HINT了。相信MySQL未來的版本會帶來更多的HINT。

mysql數據庫面試題(學生表_課程表_成績表_教師表)

Student(Sid,Sname,Sage,Ssex)學生表

Sid:學號

Sname:學生姓名

Sage:學生年齡

Ssex:學生性別

Course(Cid,Cname,Tid)課程表

Cid:課程編號

Cname:課程名稱

Tid:教師編號

SC(Sid,Cid,score)成績表

Sid:學號

Cid:課程編號

score:成績

Teacher(Tid,Tname)教師表

Tid:教師編號:

Tname:教師名字

1、插入數據

2、刪除課程表所有數據

3、將學生表中的姓名 張三修改為張大山

或者

4、查詢姓’李’的老師的個數:

5、查詢所有課程成績小於60的同學的學號、姓名:

6、查詢沒有學全所有課的同學的學號、姓名

7、查詢平均成績大於60分的同學的學號和平均成績

8、查詢學過“100”並且也學過編號“101”課程的同學的學號、姓名

9、查詢“100”課程比“101”課程成績高的所有學生的學號

10、查詢課程編號“100”的成績比課程編號“101”課程高的所有同學的學號、姓名

11、查詢學過“魯迅”老師所教的所有課的同學的學號、姓名

12、查詢所有同學的學號、姓名、選課數、總成績

13、查詢至少有一門課與學號為“1”同學所學相同的同學的學號和姓名

14、把“SC”表中“魯迅”老師教的課的成績都更改為此課程的平均成績,

錯誤

15、查詢和“2”學號的同學學習的課程完全相同的其他同學學號和姓名

16、刪除學習“魯迅”老師課的SC表記錄

17、向SC表中插入一些記錄,這些記錄要求符合以下條件:沒有上過編號“003”課程的同學學號、002號課的平均成績

18、查詢各科成績最高和最低的分:以如下的形式顯示:課程ID,最高分,最低分

19、按各科平均成績從低到高和及格率的百分數從高到低順序

20、查詢如下課程平均成績和及格率的百分數(用”1行”顯示): 數學(100),語文(101),英語(102)

22、查詢不同老師所教不同課程平均分從高到低顯示

23、查詢如下課程成績第3名到第6名的學生成績單:數學(100),語文(101),英語(102)

23、統計下列各科成績,各分數段人數:課程ID,課程名稱,[100-85],[85-70],[70-60],[ 小於60]

24、查詢學生平均成績及其名次

25、查詢各科成績前三名的記錄(不考慮成績並列情況)

26、查詢每門課程被選修的學生數

27、查詢出只選修一門課程的全部學生的學號和姓名

28、查詢男生、女生人數

29、查詢姓“張”的學生名單

30、查詢同名同姓的學生名單,並統計同名人數

31、1981年出生的學生名單(註:student表中sage列的類型是datetime)

32、查詢平均成績大於85的所有學生的學號、姓名和平均成績

33、查詢每門課程的平均成績,結果按平均成績升序排序,平均成績相同時,按課程號降序排列

34、查詢課程名稱為“英語”,且分數低於60的學生名字和分數

35、查詢所有學生的選課情況

36、查詢任何一門課程成績在70分以上的姓名、課程名稱和分數

37、查詢不及格的課程,並按課程號從大到小的排列

38、查詢課程編號為“101”且課程成績在80分以上的學生的學號和姓名

39、求選了課程的學生人數:

40、查詢選修“魯迅”老師所授課程的學生中,成績最高的學生姓名及其成績

41、檢索至少選修兩門課程的學生學號

42、查詢全部學生都選修的課程的課程號和課程名(1.一個課程被全部的學生選修,2.所有的學生選擇的所有課程)

43、查詢沒學過“魯迅”老師講授的任一門課程的學生姓名

44、查詢兩門以上不及格課程的同學的學號及其平均成績

45、檢索“101”課程分數小於60,按分數降序排列的同學學號

46、刪除“2”同學的“101”課程的成績

MySQL數據庫面試題:A表有10條數據B表有9條數據用左鏈接一共能查出多少條數據

10條數據,左連接就是把左邊的表當成主表,即不管右邊有多少數據,都會展示左邊的10條

java 關於 mysql數據庫的面試題,今天遇到一題面試題不怎麼會求解答

這應該是面試你的動手能力的一個題目,要求你開發一個能夠發布新聞的web項目。數據庫的表結構和實體類給出來了,要你完成剩下的功能。這個必須寫代碼了。

「春招系列」MySQL面試核心25問(附答案)

篇幅所限本文只寫了MySQL25題,像其他的Redis,SSM框架,算法,計網等技術棧的面試題後面會持續更新,個人整理的1000餘道面試八股文會放在文末給大家白嫖,最近有面試需要刷題的同學可以直接翻到文末領取。

如果表使用自增主鍵,那麼每次插入新的記錄,記錄就會順序添加到當前索引節點的後續位置,當一頁寫滿,就會自動開闢一個新的頁。如果使用非自增主鍵(如果身份證號或學號等),由於每次插入主鍵的值近似於隨機,因此每次新紀錄都要被插到現有索引頁得中間某個位置, 頻繁的移動、分頁操作造成了大量的碎片,得到了不夠緊湊的索引結構,後續不得不通過OPTIMIZE TABLE(optimize table)來重建表並優化填充頁面。

Server層按順序執行sql的步驟為:

簡單概括:

可以分為服務層和存儲引擎層兩部分,其中:

服務層包括連接器、查詢緩存、分析器、優化器、執行器等 ,涵蓋MySQL的大多數核心服務功能,以及所有的內置函數(如日期、時間、數學和加密函數等),所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖等。

存儲引擎層負責數據的存儲和提取 。其架構模式是插件式的,支持InnoDB、MyISAM、Memory等多個存儲引擎。現在最常用的存儲引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認的存儲引擎。

Drop、Delete、Truncate都表示刪除,但是三者有一些差別:

Delete 用來刪除表的全部或者一部分數據行,執行Delete之後,用戶需要提交(commmit)或者回滾(rollback)來執行刪除或者撤銷刪除,會觸發這個表上所有的delete觸發器。

Truncate 刪除表中的所有數據,這個操作不能回滾,也不會觸發這個表上的觸發器,TRUNCATE比Delete更快,佔用的空間更小。

Drop 命令從數據庫中刪除表,所有的數據行,索引和權限也會被刪除,所有的DML觸發器也不會被觸發,這個命令也不能回滾。

因此,在不再需要一張表的時候,用Drop;在想刪除部分數據行時候,用Delete;在保留表而刪除所有數據的時候用Truncate。

隔離級別臟讀不可重複讀幻影讀 READ-UNCOMMITTED 未提交讀 READ-COMMITTED 提交讀 REPEATABLE-READ 重複讀 SERIALIZABLE 可串行化讀

MySQL InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ (可重讀)

這裡需要注意的是 :與 SQL 標準不同的地方在於InnoDB 存儲引擎在 REPEATABLE-READ(可重讀)事務隔離級別 下使用的是 Next-Key Lock 鎖 算法,因此可以避免幻讀的產生,這與其他數據庫系統(如 SQL Server)是不同的。所以 說InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ(可重讀) 已經可以完全保證事務的隔離性要 求,即達到了 SQL標準的SERIALIZABLE(可串行化)隔離級別。

因為隔離級別越低,事務請求的鎖越少,所以大部分數據庫系統的隔離級別都是READ-COMMITTED(讀取提交內 容):,但是你要知道的是InnoDB 存儲引擎默認使用 REPEATABLE-READ(可重讀)並不會有任何性能損失 。

InnoDB 存儲引擎在分布式事務 的情況下一般會用到SERIALIZABLE(可串行化)隔離級別。

主要原因:B+樹只要遍歷葉子節點就可以實現整棵樹的遍歷,而且在數據庫中基於範圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節點,效率太低。

文件與數據庫都是需要較大的存儲,也就是說,它們都不可能全部存儲在內存中,故需要存儲到磁盤上。而所謂索引,則為了數據的快速定位與查找,那麼索引的結構組織要盡量減少查找過程中磁盤I/O的存取次數,因此B+樹相比B樹更為合適。數據庫系統巧妙利用了局部性原理與磁盤預讀原理,將一個節點的大小設為等於一個頁,這樣每個節點只需要一次I/O就可以完全載入,而紅黑樹這種結構,高度明顯要深的多,並且由於邏輯上很近的節點(父子)物理上可能很遠,無法利用局部性。

最重要的是,B+樹還有一個最大的好處:方便掃庫。

B樹必須用中序遍歷的方法按序掃庫,而B+樹直接從葉子結點挨個掃一遍就完了,B+樹支持range-query非常方便,而B樹不支持,這是數據庫選用B+樹的最主要原因。

B+樹查找效率更加穩定,B樹有可能在中間節點找到數據,穩定性不夠。

B+tree的磁盤讀寫代價更低:B+tree的內部結點並沒有指向關鍵字具體信息的指針(紅色部分),因此其內部結點相對B 樹更小。如果把所有同一內部結點的關鍵字存放在同一塊盤中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多,相對來說IO讀寫次數也就降低了;

B+tree的查詢效率更加穩定:由於內部結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引,所以,任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當;

視圖是一種虛擬的表,通常是有一個表或者多個表的行或列的子集,具有和物理表相同的功能 游標是對查詢出來的結果集作為一個單元來有效的處理。一般不使用游標,但是需要逐條處理數據的時候,游標顯得十分重要。

而在 MySQL 中,恢復機制是通過回滾日誌(undo log)實現的,所有事務進行的修改都會先記錄到這個回滾日誌中,然後在對數據庫中的對應行進行寫入。當事務已經被提交之後,就無法再次回滾了。

回滾日誌作用:1)能夠在發生錯誤或者用戶執行 ROLLBACK 時提供回滾相關的信息 2) 在整個系統發生崩潰、數據庫進程直接被殺死後,當用戶再次啟動數據庫進程時,還能夠立刻通過查詢回滾日誌將之前未完成的事務進行回滾,這也就需要回滾日誌必須先於數據持久化到磁盤上,是我們需要先寫日誌後寫數據庫的主要原因。

InnoDB

MyISAM

總結

數據庫並發會帶來臟讀、幻讀、丟棄更改、不可重複讀這四個常見問題,其中:

臟讀 :在第一個修改事務和讀取事務進行的時候,讀取事務讀到的數據為100,這是修改之後的數據,但是之後該事務滿足一致性等特性而做了回滾操作,那麼讀取事務得到的結果就是臟數據了。

幻讀 :一般是T1在某個範圍內進行修改操作(增加或者刪除),而T2讀取該範圍導致讀到的數據是修改之間的了,強調範圍。

丟棄修改 :兩個寫事務T1 T2同時對A=0進行遞增操作,結果T2覆蓋T1,導致最終結果是1 而不是2,事務被覆蓋

不可重複讀 :T2 讀取一個數據,然後T1 對該數據做了修改。如果 T2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。

第一個事務首先讀取var變量為50,接着準備更新為100的時,並未提交,第二個事務已經讀取var為100,此時第一個事務做了回滾。最終第二個事務讀取的var和數據庫的var不一樣。

T1 讀取某個範圍的數據,T2 在這個範圍內插入新的數據,T1 再次讀取這個範圍的數據,此時讀取的結果和和第一次讀取的結果不同。

T1 和 T2 兩個事務都對一個數據進行修改,T1 先修改,T2 隨後修改,T2 的修改覆蓋了 T1 的修改。例如:事務1讀取某表中的數據A=50,事務2也讀取A=50,事務1修改A=A+50,事務2也修改A=A+50,最終結果A=100,事務1的修改被丟失。

T2 讀取一個數據,T1 對該數據做了修改。如果 T2 再次讀取這個數據,此時讀取的結果和第一次讀取的結果不同。

悲觀鎖,先獲取鎖,再進行業務操作,一般就是利用類似 SELECT … FOR UPDATE 這樣的語句,對數據加鎖,避免其他事務意外修改數據。當數據庫執行SELECT … FOR UPDATE時會獲取被select中的數據行的行鎖,select for update獲取的行鎖會在當前事務結束時自動釋放,因此必須在事務中使用。

樂觀鎖,先進行業務操作,只在最後實際更新數據時進行檢查數據是否被更新過。Java 並發包中的 AtomicFieldUpdater 類似,也是利用 CAS 機制,並不會對數據加鎖,而是通過對比數據的時間戳或者版本號,來實現樂觀鎖需要的版本判斷。

分庫與分表的目的在於,減小數據庫的單庫單表負擔,提高查詢性能,縮短查詢時間。

通過分表 ,可以減少數據庫的單表負擔,將壓力分散到不同的表上,同時因為不同的表上的數據量少了,起到提高查詢性能,縮短查詢時間的作用,此外,可以很大的緩解表鎖的問題。分表策略可以歸納為垂直拆分和水平拆分:

水平分表 :取模分表就屬於隨機分表,而時間維度分表則屬於連續分表。如何設計好垂直拆分,我的建議:將不常用的字段單獨拆分到另外一張擴展表. 將大文本的字段單獨拆分到另外一張擴展表, 將不經常修改的字段放在同一張表中,將經常改變的字段放在另一張表中。對於海量用戶場景,可以考慮取模分表,數據相對比較均勻,不容易出現熱點和並發訪問的瓶頸。

庫內分表 ,僅僅是解決了單表數據過大的問題,但並沒有把單表的數據分散到不同的物理機上,因此並不能減輕 MySQL 服務器的壓力,仍然存在同一個物理機上的資源競爭和瓶頸,包括 CPU、內存、磁盤 IO、網絡帶寬等。

分庫與分錶帶來的分布式困境與應對之策 數據遷移與擴容問題—-一般做法是通過程序先讀出數據,然後按照指定的分表策略再將數據寫入到各個分表中。分頁與排序問題—-需要在不同的分表中將數據進行排序並返回,並將不同分表返回的結果集進行匯總和再次排序,最後再返回給用戶。

不可重複讀的重點是修改,幻讀的重點在於新增或者刪除。

視圖是虛擬的表,與包含數據的表不一樣,視圖只包含使用時動態檢索數據的查詢;不包含任何列或數據。使用視圖可以簡化複雜的 sql 操作,隱藏具體的細節,保護數據;視圖創建後,可以使用與表相同的方式利用它們。

視圖不能被索引,也不能有關聯的觸發器或默認值,如果視圖本身內有order by 則對視圖再次order by將被覆蓋。

創建視圖:create view xxx as xxxx

對於某些視圖比如未使用聯結子查詢分組聚集函數Distinct Union等,是可以對其更新的,對視圖的更新將對基表進行更新;但是視圖主要用於簡化檢索,保護數據,並不用於更新,而且大部分視圖都不可以更新。

B+tree的磁盤讀寫代價更低,B+tree的查詢效率更加穩定 數據庫索引採用B+樹而不是B樹的主要原因:B+樹只要遍歷葉子節點就可以實現整棵樹的遍歷,而且在數據庫中基於範圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節點,效率太低。

B+樹的特點

在最頻繁使用的、用以縮小查詢範圍的字段,需要排序的字段上建立索引。不宜:1)對於查詢中很少涉及的列或者重複值比較多的列 2)對於一些特殊的數據類型,不宜建立索引,比如文本字段(text)等。

如果一個索引包含(或者說覆蓋)所有需要查詢的字段的值,我們就稱 之為“覆蓋索引”。

我們知道在InnoDB存儲引 擎中,如果不是主鍵索引,葉子節點存儲的是主鍵+列值。最終還是要“回表”,也就是要通過主鍵再查找一次,這樣就 會比較慢。覆蓋索引就是把要查詢出的列和索引是對應的,不做回表操作!

舉例 :

學號姓名性別年齡系別專業 20020612李輝男20計算機軟件開發 20060613張明男18計算機軟件開發 20060614王小玉女19物理力學 20060615李淑華女17生物動物學 20060616趙靜男21化學食品化學 20060617趙靜女20生物植物學

主鍵為候選鍵的子集,候選鍵為超鍵的子集,而外鍵的確定是相對於主鍵的。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/237571.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:05
下一篇 2024-12-12 12:05

相關推薦

發表回復

登錄後才能評論