1000道互聯(lián)網(wǎng)java面試題(七)MySQL面試題

首先我個(gè)人屬于在mysql上卡死一次又一次的人。。。畢竟小項(xiàng)目中,又不涉及什么高并發(fā),所以什么表鎖行鎖壓根不用想。甚至sql語(yǔ)句最多也就是個(gè)left join之類(lèi)的,所以實(shí)際項(xiàng)目中sql優(yōu)化近乎沒(méi)有。當(dāng)然了數(shù)據(jù)庫(kù)設(shè)計(jì)更是可著怎么方便怎么來(lái),三大范式完全就是個(gè)擺設(shè)。。總而言之,mysql一直對(duì)于我來(lái)說(shuō)都是一個(gè)忽略的點(diǎn)。
然後面試的時(shí)候往深了問(wèn),一問(wèn)一卡死。有時(shí)候會(huì)痛定思痛,前年有一段時(shí)間死磕MySQL,什么四大隔離級(jí)別啊,臟讀幻讀不可重復(fù)讀啊,甚至關(guān)于B+樹(shù)和hash我都自取其辱的仔細(xì)研究了下。至于索引,復(fù)合索引,索引失效等等,也都一個(gè)一個(gè)demo試過(guò)。
但是!說(shuō)了這么多實(shí)戰(zhàn)經(jīng)驗(yàn)主要還是crud。然後沒(méi)做過(guò)的東西靠死記硬背真的特別容易忘。吐了這么多槽只是為了表示對(duì)MySQL的重視,下面開(kāi)始看關(guān)于MySQL的面試題。

1. MySQL中有幾種鎖?

  1. 表級(jí)鎖:開(kāi)銷(xiāo)小,加鎖快。不會(huì)出現(xiàn)死鎖。鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。
  2. 行級(jí)鎖:開(kāi)銷(xiāo)大,加鎖慢。會(huì)出現(xiàn)死鎖。鎖定粒度小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。
  3. 頁(yè)面鎖:開(kāi)銷(xiāo)和加鎖時(shí)間介于表鎖和行鎖之間,會(huì)出現(xiàn)死鎖。鎖定粒度介于表鎖和行鎖之間,并發(fā)度一般。

2. MySQL中有哪些不同的表格?

共有五種類(lèi)型的表格

  • MyISAM
  • Heap
  • Merge
  • INNODB
  • ISAM

3. 簡(jiǎn)述在MySQL數(shù)據(jù)庫(kù)中MyISAM和INNODB的區(qū)別

MyISAM:不支持事務(wù),但是每次查詢都是原子的。支持表級(jí)鎖,即每次操作都是對(duì)整個(gè)表加鎖。
存儲(chǔ)表的總行數(shù)。
一個(gè)MYISAM表有三個(gè)文件:索引文件,表結(jié)構(gòu)文件,數(shù)據(jù)文件。
采用非聚集索引,索引文件的數(shù)據(jù)域存儲(chǔ)指向數(shù)據(jù)文件的指針。輔索引與主索引基本一致,但是輔索引不用保證唯一性。
INNODB:支持ACID的事務(wù),支持事務(wù)的四種隔離級(jí)別。
支持行級(jí)鎖以及外鍵約束。因此可以支持寫(xiě)并發(fā)。
不存儲(chǔ)總行數(shù)。
一個(gè)INNODB引擎存儲(chǔ)在一個(gè)文件空間(共享表空間,表大小不受操作系統(tǒng)控制,一個(gè)表可能分布在多個(gè)文件里。)。也有可能為多個(gè)(設(shè)置為獨(dú)立表,表大小受操作系統(tǒng)文件大小限制,一般為2G).
主鍵索引采用聚集索引(索引的數(shù)據(jù)域存儲(chǔ)數(shù)據(jù)文件本身)。輔索引的數(shù)據(jù)域存儲(chǔ)主鍵的值。因?yàn)閺妮o索引查找數(shù)據(jù),需要先通過(guò)輔索引找到主鍵值,再訪問(wèn)輔索引。最好使用自增主鍵,防止插入數(shù)據(jù)時(shí)為維持B+樹(shù)結(jié)構(gòu),文件的大調(diào)整。

4. MySQL中INNODB支持的四種食物隔離級(jí)別名稱以及逐級(jí)之間的區(qū)別?

  1. read uncommited:讀到未提交數(shù)據(jù)(讀未提交)
  2. read commited: 讀已提交
  3. repeatable read:可重復(fù)讀
  4. serializable:串行事務(wù)

5. CHAR和VARCHAR的區(qū)別?

  1. CHAR和VARCHAR類(lèi)型在存儲(chǔ)和檢索方面不同。
  2. CHAR列長(zhǎng)度固定為創(chuàng)建表時(shí)聲明的長(zhǎng)度。長(zhǎng)度值范圍是1-255.當(dāng)實(shí)際存儲(chǔ)不足聲明長(zhǎng)度時(shí)它們被用空格填充到特定長(zhǎng)度,檢索CHAR值時(shí)需要?jiǎng)h除尾隨空格。
  3. VARCHAR是變長(zhǎng)的。聲明時(shí)的長(zhǎng)度是可用最大值。

6. 主鍵和候選鍵有什么區(qū)別?

一個(gè)表只有一個(gè)主鍵。
主鍵也是候選鍵,按照慣例,候選鍵可以被指定為主鍵。并且可以用于任何外鍵引用。

7. myisamchk是用來(lái)做什么的?

用來(lái)壓縮MyISAM表,者減少了磁盤(pán)或內(nèi)存使用。

8. 問(wèn)答題

MyISAM Static 和 MyISAM Dynamic 有什么區(qū)別?
  • 在MyISAM Static上所有字段有固定寬度。 MyISAM Static在受損情況下更容易恢復(fù)。
  • 動(dòng)態(tài)MyISAM(MyISAM Dynamic) 表將具有像TEXT,BLOB等字段,以適應(yīng)不同長(zhǎng)度的數(shù)據(jù)類(lèi)型。
如果一個(gè)表有一列定義為T(mén)IMESTAMP。將發(fā)生什么?

每當(dāng)行被更改時(shí),時(shí)間戳字段將獲取當(dāng)前時(shí)間戳。

列設(shè)置為AUTO INCREMENT時(shí),如果在表中達(dá)到最大值,會(huì)發(fā)生什么情況?

它會(huì)停止遞增,任何進(jìn)一步的插入都將產(chǎn)生錯(cuò)誤,因?yàn)槊罔€已被使用。

怎樣才能找出最后一次插入時(shí)分配了那個(gè)自動(dòng)增量?
插入的時(shí)候遞增

最后一條id是4

查詢結(jié)果

這個(gè)題的答案就是LAST_INSERT_ID()函數(shù)。將返回由Auto_increment分配 最后一個(gè)值。并且不需要指定表名稱。

9. 你怎么看到為表格定義的所有索引?

命令行:show index from <tableName>
當(dāng)然了,比我我習(xí)慣用navicat,那么就直接設(shè)計(jì)表,然后有索引欄。

10. like聲明中的%和_是什么意思?

%對(duì)應(yīng)0或者更多個(gè)字符。而_代表一個(gè)字符。
比如 %xx%。則只要這個(gè)字段中包含xx就可以匹配到。
xx。則必須是四個(gè)字符。且第二個(gè),第三個(gè)字符是xx。

11. 列對(duì)比運(yùn)算符是什么?

在SELECT語(yǔ)句的列比較中使用的,=, <>, <=, <, >=, >, <<, >>,<=>, AND, OR 或者LIKE運(yùn)算符。

12. BLOB 和 TEXT有什么區(qū)別?

  • BLOB是一個(gè)二進(jìn)制對(duì)象,可容納可變數(shù)量的數(shù)據(jù)。
  • TEXT是一個(gè)不區(qū)分大小寫(xiě)的BLOB。

BLOB和TEXT類(lèi)型之間的唯一區(qū)別在于對(duì)BLOB值進(jìn)行排序和比較時(shí)是區(qū)分大小寫(xiě)的。而對(duì)TEXT值不區(qū)分大小寫(xiě)。

13. MyISAM表格將在哪里存儲(chǔ),并且還提供其存儲(chǔ)格式?

每個(gè)MyISAM表格以三種格式存儲(chǔ)在磁盤(pán)上:

  • “.frm”文件存儲(chǔ)表的定義
  • 數(shù)據(jù)文件具有“.MYD”(myData)擴(kuò)展名
  • 索引文件具有“.MYI”(myIndex)擴(kuò)展名

14. 如何查看sql語(yǔ)句的最終執(zhí)行語(yǔ)句?

我們知道我們寫(xiě)的sql語(yǔ)句還會(huì)經(jīng)過(guò)解析優(yōu)化后再去執(zhí)行,查看實(shí)際執(zhí)行的語(yǔ)句方法(navicat中):
explain extended sql語(yǔ)句; -- 注意這個(gè)分號(hào)是必須的
show warnings
然后結(jié)果1是索引使用情況,結(jié)果2是實(shí)際執(zhí)行語(yǔ)句。如下圖:


demo

15. 如何顯示前50行?

在MySQL中,limit 0,50就是查詢前50條。
其實(shí)分頁(yè)的實(shí)現(xiàn)就是基于差不多的思路。

16. 可以使用多少列創(chuàng)建索引?

任何標(biāo)準(zhǔn)表最多可以創(chuàng)建16個(gè)索引列。

17. NOW()和 CURRENT_DATE()有什么區(qū)別?

now()方法用于顯示當(dāng)前年月日時(shí)分秒。而current_date()僅顯示年月日。

18. 什么是非標(biāo)準(zhǔn)字符串類(lèi)型?

  • TINYTEXT
  • TEXT
  • MEDIUMTEXT
  • LONGTEXT

19. 什么是通用SQL函數(shù)?

有一些函數(shù)所有數(shù)據(jù)庫(kù)都支持的,叫做通用sql函數(shù)。如下:

  • CONCAT(A,B) 連接兩個(gè)字符串值以創(chuàng)建單個(gè)字符串輸出。通常用于將兩個(gè)或者多個(gè)字段合并為一個(gè)字段。如下截圖。


    原表

    查詢結(jié)果
  • FORMAT(X,D) 格式化數(shù)字X到D有效數(shù)字。 當(dāng)然了我個(gè)人是覺(jué)得這個(gè)其實(shí)用得不多,它的兄弟DATE_FORMAT用的倒是挺多的(我不知道這個(gè)是不是所有數(shù)據(jù)庫(kù)都支持)。然后用法如下:


    格式化日期
  • CURRDATE(),CURRTIME() 返回當(dāng)前日期或者時(shí)間

  • NOW() 將當(dāng)前日期和時(shí)間作為一個(gè)值返回

  • MONTH(),DAY(),YEAR(),WEEK(),WEEKDAY().從日期中提取給定數(shù)據(jù)。

  • HOUR(),MINUTE(),SECOND() 從時(shí)間中提取給定數(shù)據(jù)

  • DATEDIFF(A,B) 確定兩個(gè)日期之間的差異,通常用于計(jì)算年齡。使用方法如下圖:


    兩個(gè)日期相差的天數(shù)
  • SUBTIME(A,B) A時(shí)間戳減去B的時(shí)間。如下demo


    時(shí)間戳減去秒數(shù)
  • FROMDAYS(int) 將整數(shù)天數(shù)轉(zhuǎn)化為日期。這個(gè)天數(shù)好像是從366開(kāi)始算一天。如下截圖


    測(cè)試demo

20. MySQL支持事務(wù)么?

默認(rèn)的缺省模式下,MySQL是autocommit模式的,所有數(shù)據(jù)庫(kù)更新操作都會(huì)及時(shí)提交。所以缺省情況下是不支持事務(wù)的。
但是如果MySQL表類(lèi)型是INNODB或者BDB的話,就可以使用事務(wù)處理。使用SET AUTOCOMMIT = 0就可以使MySQL允許在非autocommit模式。非autocommit模式下,必須使用commit來(lái)提交更改或者rollback來(lái)回滾更改。

21. MySQL里記錄貨幣用什么字段類(lèi)型好?

NUMERIC和DECIMAL類(lèi)型被MySQL實(shí)現(xiàn)為同樣的類(lèi)型,這在SQL92標(biāo)準(zhǔn)允許。
他們被用于保存準(zhǔn)確經(jīng)度是極其重要的值。例如與金錢(qián)有關(guān)的數(shù)據(jù)。
當(dāng)聲明一個(gè)類(lèi)是這些類(lèi)型之一時(shí),精度和規(guī)模能被指定。
比如 salary DECIMAL(9,2)。9代表存儲(chǔ)值的總的位數(shù)。而2代表小數(shù)點(diǎn)后的位數(shù)。
這種情況下salary字段的值的范圍是:-9999999.99到9999999.99。

22. MySQL有關(guān)權(quán)限的表都有哪幾個(gè)?

MySQL服務(wù)器通過(guò)權(quán)限表來(lái)控制用戶對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),權(quán)限表存放在MySQL數(shù)據(jù)庫(kù)里。由MySQL_install_db腳本初始化。這些權(quán)限表分別是:user,db,table_priv,columns_priv和host。


如下五張權(quán)限表

23. 列的字符串類(lèi)型可以是什么?

  • SET
  • BLOB
  • ENUM
  • CHAR
  • TEXT

24. MySQL數(shù)據(jù)庫(kù)作發(fā)布系統(tǒng)的存儲(chǔ),一天五萬(wàn)條以上的增量,預(yù)計(jì)運(yùn)維三年,怎么優(yōu)化?

  1. 設(shè)計(jì)兩個(gè)的數(shù)據(jù)庫(kù)結(jié)構(gòu),允許部分?jǐn)?shù)據(jù)冗余,盡量避免join查詢,提高效率。
  2. 選擇合適的表字段數(shù)據(jù)類(lèi)型和存儲(chǔ)引擎,適當(dāng)?shù)奶砑铀饕?/li>
  3. MySQL庫(kù)主從讀寫(xiě)分離。
  4. 找規(guī)律分表,減少單表中的數(shù)據(jù)量提高查詢速度。
  5. 添加緩存機(jī)制,比如memcached等。
  6. 不經(jīng)常改動(dòng)的頁(yè)面生成靜態(tài)頁(yè)面。
  7. 書(shū)寫(xiě)高效率的SQL,比如不用select *。

25. 鎖的優(yōu)化策略

  1. 讀寫(xiě)分離
  2. 分段加鎖
  3. 減少鎖持有的時(shí)間
  4. 多個(gè)線程盡量以相同的順序去獲取資源

不能將鎖的粒度過(guò)于細(xì)化。不然可能會(huì)出現(xiàn)線程的加鎖和釋放次數(shù)過(guò)多,反而效率不如一次加一把大鎖。

26. 索引的底層實(shí)現(xiàn)原理和優(yōu)化

底層實(shí)現(xiàn)一般為hash或者B+樹(shù)。(經(jīng)過(guò)優(yōu)化的B+樹(shù))
主要是在所有的葉子節(jié)點(diǎn)中增加了指向下一個(gè)葉子節(jié)點(diǎn)的指針。因此InnoDB建議大部分表使用默認(rèn)自增的主鍵作為主索引。

27. 什么情況下設(shè)置了索引但無(wú)法使用?

  1. 以% 開(kāi)頭的like語(yǔ)句,模糊匹配
  2. OR語(yǔ)句前后沒(méi)有同時(shí)使用索引
  3. 數(shù)據(jù)類(lèi)型出現(xiàn)隱式轉(zhuǎn)化(比如varchar不加單引號(hào)轉(zhuǎn)成數(shù)字。)

28. 實(shí)踐中如何優(yōu)化MySQL

最好按照以下順序優(yōu)化:

  1. SQL語(yǔ)句以及索引的優(yōu)化
  2. 數(shù)據(jù)庫(kù)表結(jié)構(gòu)的優(yōu)化
  3. 系統(tǒng)配置的優(yōu)化
  4. 硬件的優(yōu)化

(附上一個(gè)阿里P8架構(gòu)師寫(xiě)的優(yōu)化總結(jié):https://mikechen.cc/3305.html

29. 優(yōu)化數(shù)據(jù)庫(kù)的方法

  1. 選取最適用的字段屬性。盡可能的把字段設(shè)置為notnull。例如省份,性別等最好用枚舉。
  2. 使用連接(join)來(lái)代替子查詢。
  3. 使用聯(lián)合(union) 來(lái)代替手動(dòng)創(chuàng)建的臨時(shí)表
  4. 事務(wù)處理
  5. 鎖定表,優(yōu)化事務(wù)處理
  6. 使用外鍵,優(yōu)化鎖定表
  7. 建立索引
  8. 優(yōu)化查詢語(yǔ)句

30. 簡(jiǎn)單描述MySQL中,索引,主鍵,唯一索引,聯(lián)合索引的區(qū)別。對(duì)數(shù)據(jù)庫(kù)的性能有什么影響(從讀寫(xiě)兩方面)

索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表所有記錄的引用指針。
普通索引(由關(guān)鍵字key或index定義的索引)的唯一任務(wù)就是加快對(duì)數(shù)據(jù)的訪問(wèn)速度。
普通索引允許被索引的數(shù)據(jù)列包含重復(fù)的值。如果能確定某個(gè)數(shù)據(jù)列將只包含彼此各不相同的值,在為這個(gè)數(shù)據(jù)列創(chuàng)建索引的時(shí)候就應(yīng)該用關(guān)鍵字UNIQUE把它定義為一個(gè)唯一索引。也就是說(shuō):唯一索引可以保證數(shù)據(jù)記錄的唯一性。
主鍵是一種特殊的唯一索引。在一張表中只能定義一個(gè)主鍵索引。主鍵用于唯一標(biāo)識(shí)一條記錄。使用關(guān)鍵字primary key來(lái)創(chuàng)建。
索引可以覆蓋多個(gè)數(shù)據(jù)列,如index(column A,columnB)索引,這個(gè)就是聯(lián)合索引。
索引可以極大的提高數(shù)據(jù)的查詢速度。但是會(huì)降低插入,刪除和更新表的速度。因?yàn)樵趫?zhí)行這些寫(xiě)操作時(shí),還要操作索引文件。

31. 數(shù)據(jù)庫(kù)中的事務(wù)是什么?

事務(wù)(transaction)是作為一個(gè)單元的一組有序的數(shù)據(jù)庫(kù)操作。如果組中的所有操作都成功,則認(rèn)為事務(wù)成功,即使只有一個(gè)操作失敗,事務(wù)也不成功。如果所有操作完成,事務(wù)則提交,其修改將作用于所有其他數(shù)據(jù)庫(kù)進(jìn)程。如果一個(gè)操作失敗則事務(wù)將回滾,該事務(wù)的所有操作的影響都將取消。
事務(wù)特性:

  1. 原子性:即不可分割性,要么全部被執(zhí)行,要么全部不執(zhí)行。
  2. 一致性或可串性:事務(wù)的執(zhí)行使得數(shù)據(jù)庫(kù)從一種正確狀態(tài)轉(zhuǎn)換成另一種正確狀態(tài)。
  3. 隔離性:事務(wù)正確提交之前,不允許把該事務(wù)對(duì)數(shù)據(jù)庫(kù)的任何改變提供給任何其他事務(wù)。
  4. 持久性:事務(wù)正確提交后,其結(jié)果將永久保存在數(shù)據(jù)庫(kù)中,即使在事務(wù)提交后有了其他故障,事務(wù)的處理結(jié)果也會(huì)得到保存。

簡(jiǎn)而言之可以如下理解:
事務(wù)就是被綁定在一起作為一個(gè)邏輯單元的SQL語(yǔ)句組合,如果任何一個(gè)語(yǔ)句操作失敗則整個(gè)操作都失敗。就會(huì)回滾到操作前的狀態(tài)(或者上個(gè)節(jié)點(diǎn))。為了確保要么執(zhí)行要么不執(zhí)行就可以使用事務(wù)。要將一組語(yǔ)句作為事務(wù)考慮,就要通過(guò)ACID測(cè)試。即原子性,一致性,隔離性和持久性。

32, SQL注入漏洞產(chǎn)生的原因以及如何防止?

SQL注入產(chǎn)生的原因:程序開(kāi)發(fā)過(guò)程中不規(guī)范書(shū)寫(xiě)sql語(yǔ)句和對(duì)特殊字符進(jìn)行過(guò)濾,導(dǎo)致接口可以提交一些sql語(yǔ)句正常執(zhí)行。(通俗點(diǎn)當(dāng)我們把一些參數(shù)拼接到sql語(yǔ)句時(shí),如果傳過(guò)來(lái)的不是一個(gè)參數(shù)值而是sql的一部分。從而執(zhí)行了和預(yù)計(jì)中完全不一樣的sql)。
防止sql注入的方式也很多,簡(jiǎn)單說(shuō)幾種:

  1. 開(kāi)啟配置文件中magic_quotes_gpc和magic_quotes_runtime設(shè)置。
  2. sql語(yǔ)句書(shū)寫(xiě)盡量不要省略雙引號(hào)和單引號(hào)。
  3. 過(guò)濾掉一些敏感詞,比如update,insert,delete,select,where等。
  4. 對(duì)數(shù)據(jù)庫(kù)表的命名和字段的命名不要太直白,盡量不讓人猜到。

33. 為表中的字段選擇合適的數(shù)據(jù)類(lèi)型

字段類(lèi)型優(yōu)先級(jí):整形>date,time>enum,char>varchar>blob,text
用言語(yǔ)講就是優(yōu)先考慮數(shù)字類(lèi)型,其次是日期或者二進(jìn)制類(lèi)型,最后是字符串類(lèi)型。同級(jí)別的數(shù)據(jù)類(lèi)型應(yīng)該優(yōu)先選擇占用空間小的數(shù)據(jù)類(lèi)型。

34. 存儲(chǔ)時(shí)期

  • Datetime:以yyyy-MM-dd HH:mm:ss格式存儲(chǔ)日期時(shí)間。精確到秒,占用8個(gè)字節(jié)的存儲(chǔ)空間,datetime類(lèi)型與時(shí)區(qū)無(wú)關(guān)系。
  • Timestamp:以時(shí)間戳格式存儲(chǔ),占用四個(gè)字節(jié)。范圍自1970/1/1到2038/1/19.顯示依賴于所指定的時(shí)區(qū)。默認(rèn)這行數(shù)據(jù)修改時(shí)可以自動(dòng)的修改timestamp列的值。
  • Date: 占用的字節(jié)數(shù)比字符串,datetime,int存儲(chǔ)要少。使用date僅僅需要三個(gè)字符。存儲(chǔ)年月日。還可以利用日期時(shí)間函數(shù)進(jìn)行日期間的計(jì)算。
  • Time:存儲(chǔ)時(shí)間部分的數(shù)據(jù)。

注意:不要使用字符串類(lèi)型來(lái)存儲(chǔ)日期時(shí)間數(shù)據(jù)(因?yàn)槿掌陬?lèi)型比字符串占用的存儲(chǔ)空間小,而且查找或者過(guò)濾,甚至一些時(shí)間計(jì)算上可以利用日期的函數(shù)。)
使用int存儲(chǔ)時(shí)間日期不如使用timestamp類(lèi)型。

35. 對(duì)于關(guān)系型數(shù)據(jù)庫(kù)而言,索引是相當(dāng)重要的概念,請(qǐng)回答以下幾個(gè)問(wèn)題:

索引的目的是什么?
快速訪問(wèn)數(shù)據(jù)庫(kù)表中的特定信息。提高檢索速度。
創(chuàng)建唯一性索引,保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性。
加速表和表之間的鏈接。
使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),可以顯著減少查詢中分組和排序的時(shí)間。
索引對(duì)數(shù)據(jù)庫(kù)系統(tǒng)的負(fù)面影響是什么?
創(chuàng)建索引和維護(hù)索引需要耗費(fèi)時(shí)間,這個(gè)時(shí)間隨著數(shù)據(jù)量的增加而增加。索引需要占用物理空間。不光是表需要占用數(shù)據(jù)空間,每個(gè)索引也需要占用物理空間。當(dāng)對(duì)表進(jìn)行增刪改的時(shí)候索引也要?jiǎng)討B(tài)維護(hù),這樣就降低了數(shù)據(jù)的維護(hù)速度。
為數(shù)據(jù)表建立索引的原則有哪些?
在最頻繁使用的,用以縮小查詢范圍的字段上建立索引。
在頻繁使用的,需要排序的字段上建立索引。
什么情況下不宜建立索引?
對(duì)于查詢中很少涉及到的列或者重復(fù)制比較多的列不宜建立索引。
對(duì)于一些特殊的數(shù)據(jù)類(lèi)型比如blob,text等,不宜建立索引。

36. 解釋MySQL外連接,內(nèi)連接與自連接的區(qū)別

這個(gè)必須要先說(shuō)一下交叉連接:交叉連接又叫笛卡爾積,它是指不用任何條件,直接一個(gè)表的所有記錄與另一個(gè)表的所有記錄一一匹配。
內(nèi)連接:是有條件的交叉連接。根據(jù)某個(gè)條件篩選出符合條件的記錄,不符合條件的記錄不會(huì)出現(xiàn)在結(jié)果集中,即內(nèi)連接值連接匹配的行。(如下圖)

內(nèi)連接,外連接

外連接:如上圖,結(jié)果集不僅包含共有部分,共有+左表數(shù)據(jù)屬于左(外)連接。共有+右表數(shù)據(jù)屬于右(外)連接。這些數(shù)據(jù)全部包含的屬于全外連接。
左外連接和右外連接中另一個(gè)表沒(méi)有的數(shù)據(jù)用null填充,MySQL目前不支持全外連接。

37. MySQL中事務(wù)回滾機(jī)制概述

事務(wù)是用戶定義的一個(gè)數(shù)據(jù)庫(kù)操作序列。這些操作要么不做,要么全做,是一個(gè)不可分割的工作單位。事務(wù)回滾是指將該事務(wù)已經(jīng)完成的對(duì)數(shù)據(jù)庫(kù)的更新操作撤銷(xiāo)。
(正好這兩天我遇到了一個(gè)生活著的事務(wù)的例子:叫外賣(mài)的時(shí)候之前看了一家的小菜挺好,加購(gòu)以后要下單了才發(fā)現(xiàn)買(mǎi)這個(gè)小菜必須搭配某主食。我看了下主食并不想要,所以現(xiàn)在只有兩個(gè)操作:1.把主食也加購(gòu),2,不買(mǎi)小菜了。這個(gè)主食和小菜我們可以理解成一個(gè)事務(wù)。要么全買(mǎi),要么全不買(mǎi)。)

項(xiàng)目中,要同時(shí)修改數(shù)據(jù)庫(kù)中兩個(gè)不同表時(shí),如果他們不是一個(gè)事務(wù)的話,當(dāng)?shù)谝粋€(gè)表修改完,可能第二個(gè)表的修改因?yàn)槟承┰驔](méi)能修改。這個(gè)時(shí)候第一個(gè)表已經(jīng)是修改完的狀態(tài),而第二個(gè)表是未修改狀態(tài)。
而如果我們把這兩個(gè)操作放到一個(gè)事務(wù)中,第一個(gè)表修改完,第二個(gè)表因?yàn)楫惓](méi)能修改的話,第一個(gè)表和第二個(gè)表都回到未修改狀態(tài),這個(gè)就是事務(wù)的回滾。

38. SQL語(yǔ)句包括哪幾部分?每部分都有哪些操作關(guān)鍵字?

SQL語(yǔ)句分四種:

  • 數(shù)據(jù)定義DDL
  • 數(shù)據(jù)操縱DML
  • 數(shù)據(jù)控制DCL
  • 數(shù)據(jù)查詢DQL

數(shù)據(jù)定義DDL:CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE/DROP INDEX等。(簡(jiǎn)單來(lái)說(shuō)就是增刪改表,索引)
數(shù)據(jù)操縱DML: SELECT, INSERT, UPDATE, DELETE等(簡(jiǎn)單來(lái)說(shuō)增刪改查記錄)
數(shù)據(jù)控制DCL: GRANT, REVOKE(這兩個(gè)比較少用到,是給數(shù)據(jù)庫(kù)用戶授權(quán)/撤銷(xiāo)授權(quán)的)
數(shù)據(jù)查詢DQL:SELECT

39. 完整性約束包括哪些?

數(shù)據(jù)完整性是指數(shù)據(jù)的精確和可靠性。
分為以下四類(lèi):

  1. 實(shí)體完整性: 規(guī)定表的每一行在表中是唯一的實(shí)體。
  2. 域完整性:是指表中的列必須滿足某種特定的數(shù)據(jù)類(lèi)型約束。其中約束又包括取值范圍,精度等規(guī)定。
  3. 參照完整性: 是指兩個(gè)表的主關(guān)鍵字和外關(guān)鍵字的數(shù)據(jù)應(yīng)一致。保證了表之間的數(shù)據(jù)的一致性。防止了數(shù)據(jù)丟失或者無(wú)意義的數(shù)據(jù)在數(shù)據(jù)庫(kù)中擴(kuò)散。
  4. 用戶定義的完整性: 不同的關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)根據(jù)其應(yīng)用環(huán)境的不同,往往還需要一些特殊的約束條件,用戶定義的完整性即針對(duì)某個(gè)特定關(guān)系數(shù)據(jù)庫(kù)的約束條件。它反映某一具體應(yīng)用必須滿足的語(yǔ)義要求。

與表有關(guān)的約束:列的非空約束。表的主鍵約束,唯一約束,指定類(lèi)型約束,外鍵約束等。

40. 什么是鎖?

數(shù)據(jù)庫(kù)是一個(gè)多用戶使用的共享資源。當(dāng)多個(gè)用戶并發(fā)的存取數(shù)據(jù)時(shí),在數(shù)據(jù)庫(kù)中就會(huì)產(chǎn)生多個(gè)事務(wù)同時(shí)存取同一數(shù)據(jù)的情況,若對(duì)并發(fā)操作不加控制就可能會(huì)讀取和存取不正確的數(shù)據(jù),破壞數(shù)據(jù)庫(kù)的一致性。
加鎖是實(shí)現(xiàn)數(shù)據(jù)庫(kù)并發(fā)控制的一個(gè)非常重要的技術(shù)。當(dāng)事務(wù)在對(duì)某個(gè)數(shù)據(jù)對(duì)象進(jìn)行操作前,先向系統(tǒng)發(fā)出請(qǐng)求,對(duì)其加鎖。加鎖后事務(wù)就對(duì)該數(shù)據(jù)對(duì)象有了一定的控制,在改事務(wù)釋放鎖之前,其他的事務(wù)不能對(duì)此數(shù)據(jù)對(duì)象進(jìn)行更新操作。
基本鎖類(lèi)型:表級(jí)鎖和行級(jí)鎖(這個(gè)第一個(gè)題好像就說(shuō)了,還有個(gè)頁(yè)面鎖,其中優(yōu)缺點(diǎn)都有介紹)

41. 什么叫視圖?游標(biāo)是什么?

視圖是一種虛擬的表。具有和物理表相同的功能。可以對(duì)視圖進(jìn)行增/改/查操作。視圖通常是由一個(gè)表或者多個(gè)表的行或列的子集。對(duì)視圖的修改不影響基本表。
它使得我們獲取數(shù)據(jù)更容易,相比于多表查詢。
游標(biāo)是對(duì)查詢出來(lái)的結(jié)果集作為一個(gè)單元來(lái)有效的處理。游標(biāo)可以定在該單元中的特定行。從結(jié)果集的當(dāng)前行檢索一行或者多行??梢詫?duì)結(jié)果集當(dāng)前行做修改。
一般不使用游標(biāo),但是當(dāng)需要逐條處理數(shù)據(jù)的時(shí)候,游標(biāo)顯得極其重要。

42. 什么是存儲(chǔ)過(guò)程?用什么來(lái)調(diào)用?

存儲(chǔ)過(guò)程是一個(gè)預(yù)編譯的SQL語(yǔ)句。優(yōu)點(diǎn)是允許模塊化的設(shè)計(jì),就是說(shuō)只需要?jiǎng)?chuàng)建一次以后在該程序中就可以調(diào)用多次。如果某次操作需要執(zhí)行多次SQL,使用存儲(chǔ)過(guò)程比單純sql語(yǔ)句執(zhí)行要快。可以用一個(gè)命令對(duì)象來(lái)調(diào)用存儲(chǔ)過(guò)程。

43. 如何通俗的理解三個(gè)范式?

第一范式:列的不可再分。是對(duì)屬性的原子性約束。要求屬性具有原子性,不可再分解。舉個(gè)例子:如果是存地址,可以分為省市區(qū)詳細(xì)地址四個(gè)字段。而不是所有的地址放在一個(gè)字段。否則就是可再分的,不具有原子性。
第二范式:在滿足第一范式的前提下,一行數(shù)據(jù)只做一件事。這個(gè)是對(duì)記錄的唯一性約束。要求記錄有唯一標(biāo)識(shí),即實(shí)體的唯一性。打個(gè)比方:我們常用的下訂單功能:商品件數(shù)不定,但是訂單就是一個(gè)訂單。如果每個(gè)商品都保存這個(gè)訂單的信息(訂單號(hào),下單時(shí)間,訂單金額等)就是冗余。這個(gè)時(shí)候我們應(yīng)該拆分成訂單表和訂單對(duì)應(yīng)商品表。保證一個(gè)表只做一件事。
第三范式:滿足1,2后,表中的每一列都直接與主鍵相關(guān)而不是間接相關(guān)。這個(gè)是對(duì)表的冗余性的約束。即任何字段不能由其他字段派生出來(lái)。它要求的是不要有冗余字段。這個(gè)怎么說(shuō)呢,繼續(xù)第二范式的例子:用戶直接下訂單。也就是用戶和訂單是有關(guān)系的。而訂單包含商品,也就是訂單和商品是有關(guān)系的。本質(zhì)上用戶購(gòu)買(mǎi)的是商品,但是??!我們不應(yīng)該在訂單商品表中摻雜用戶的信息。因?yàn)橛脩?>訂單->商品,這個(gè)是間接的關(guān)系了。

任何脫離實(shí)際的要求都是純扯淡!注意這句話不是我說(shuō)的,是陽(yáng)哥(尚硅谷講師周陽(yáng))說(shuō)的。也就是實(shí)際上范式落實(shí)到實(shí)際中是不能百分百遵守的,完全按照范式來(lái)不見(jiàn)得會(huì)做出好東西。因?yàn)橛袝r(shí)候?qū)嶋H的需求就是這么操蛋,阿里不都說(shuō)了合理的冗余是必要的么!下面簡(jiǎn)單說(shuō)下范式化設(shè)計(jì)的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):可以盡量的減少數(shù)據(jù)冗余,使得更新快,體積小。如果數(shù)據(jù)異常,數(shù)據(jù)修改比較容易。
缺點(diǎn):對(duì)于查詢需要多個(gè)表進(jìn)行關(guān)聯(lián),使得寫(xiě)更優(yōu)化,但是讀更復(fù)雜。更難進(jìn)行索引優(yōu)化。

44. 什么是基本表?什么是視圖?

基本表是指本身獨(dú)立存在的表,在SQL中一個(gè)關(guān)系就對(duì)應(yīng)一個(gè)表。
視圖是從一個(gè)或者幾個(gè)基本表導(dǎo)出的表。視圖本身不獨(dú)立存儲(chǔ)在數(shù)據(jù)庫(kù)中,是一個(gè)虛表。

45. 視圖的優(yōu)點(diǎn)?

  1. 簡(jiǎn)化用戶的操作
  2. 視圖使用戶能以多種角度看待同一個(gè)數(shù)據(jù)。
  3. 試圖為數(shù)據(jù)庫(kù)提供了一定程度的邏輯獨(dú)立性
  4. 視圖能夠?qū)C(jī)密數(shù)據(jù)提供安全保護(hù)。

46. null是什么意思?

null這個(gè)值表示的是unknown(未知),它不是“”(空串)。任何值與null值比較都會(huì)是null。我們可以使用is null 來(lái)進(jìn)行null判斷。

47. 主鍵/外鍵/索引的區(qū)別?

主鍵: 一條記錄的唯一標(biāo)識(shí),不能有重復(fù)的,也不許為空。(主鍵約束包含非空和唯一約束。)
作用是用來(lái)保證數(shù)據(jù)的完整性。
一個(gè)表只能有一個(gè)主鍵。
外鍵:表的外鍵是另一個(gè)表的主鍵??梢杂兄貜?fù),也可以有空值。
作用是用來(lái)和其他表建立聯(lián)系。
一個(gè)表可以有多個(gè)外鍵。
索引: 為了提高查詢排序的速度而專門(mén)對(duì)一些列進(jìn)行排序。
一個(gè)表可以有多個(gè)索引。

48. 你可以用什么來(lái)確保表里的字段只接受特定范圍里的值?

可以用Check限制。他在數(shù)據(jù)庫(kù)表里被定義,用來(lái)限制輸入該列的值。

49. 簡(jiǎn)單說(shuō)下對(duì)SQL語(yǔ)句優(yōu)化的方法

  1. Where字句中,表之間的鏈接必須寫(xiě)在最前面??梢赃^(guò)濾掉最大數(shù)量記錄的條件寫(xiě)在where子句的末尾。having寫(xiě)在最后。
  2. 用 exists代替in,用not exists代替not in
  3. 避免在索引上使用計(jì)算
  4. 避免在索引上使用 is null和 is not null
  5. 對(duì)查詢進(jìn)行優(yōu)化,應(yīng)該盡量避免全表掃描,首先應(yīng)該考慮在where已經(jīng)order by涉及的列上建立索引。
  6. 應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行null判斷,否則會(huì)放棄使用索引而進(jìn)行全表掃描。
  7. 應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行表達(dá)式操作,否則也會(huì)放棄使用索引而進(jìn)行全表掃描。

至此,這本書(shū)中MySQL方面的面試題就結(jié)束啦!全文50個(gè)題目。其中一個(gè)現(xiàn)在已經(jīng)很少用了所以我沒(méi)記錄。剩下別的其實(shí)也有很多重復(fù)的題目或者說(shuō)比較老的題目,不過(guò)多看看總沒(méi)有錯(cuò)!本篇筆記如果稍微幫到你了記得點(diǎn)個(gè)喜歡點(diǎn)個(gè)關(guān)注。也祝大家身體健健康康,工作順利吧!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容