日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

面试之 Mysql 汇总

發(fā)布時(shí)間:2023/12/20 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试之 Mysql 汇总 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

事務(wù)相關(guān)

什么是事務(wù)?

事務(wù):是由一組SQL語(yǔ)句組成的邏輯處理單元,事務(wù)具有以下4個(gè)屬性,通常簡(jiǎn)稱(chēng)為事務(wù)。事務(wù)的ACID屬性:
(1)原子性(Atomicity):
  事務(wù)是一個(gè)原子操作單元,事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾,因此事務(wù)的操作如果成功就必須要完全應(yīng)用到數(shù)據(jù)庫(kù),如果操作失敗則不能對(duì)數(shù)據(jù)庫(kù)有任何影響。

(2)一致性(Consistent):
  在事務(wù)開(kāi)始和完成時(shí),數(shù)據(jù)都必須保持一致?tīng)顟B(tài)。這意味著所有相關(guān)的數(shù)據(jù)規(guī)則都必須應(yīng)用于事務(wù)的修改,以保持?jǐn)?shù)據(jù)的完整性;事務(wù)結(jié)束時(shí),所有的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如B樹(shù)索引或雙向鏈表)也都必須是正確的。
  一致性是指事務(wù)必須使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變換到另一個(gè)一致性狀態(tài),也就是說(shuō)一個(gè)事務(wù)執(zhí)行之前和執(zhí)行之后都必須處于一致性狀態(tài)。
  例如轉(zhuǎn)賬,假設(shè)用戶A和用戶B兩者的錢(qián)加起來(lái)一共是5000,那么不管A和B之間如何轉(zhuǎn)賬,轉(zhuǎn)幾次賬,事務(wù)結(jié)束后兩個(gè)用戶的錢(qián)相加起來(lái)應(yīng)該還得是5000,這就是事務(wù)的一致性。

(3)隔離性(Isolation):
  數(shù)據(jù)庫(kù)系統(tǒng)提供一定的隔離機(jī)制,保證事務(wù)在不受外部并發(fā)操作影響的“獨(dú)立”環(huán)境執(zhí)行。這意味著事務(wù)處理過(guò)程中的中間狀態(tài)對(duì)外部是不可見(jiàn)的,反之亦然。
  隔離性是當(dāng)多個(gè)用戶并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)時(shí),比如操作同一張表時(shí),數(shù)據(jù)庫(kù)為每一個(gè)用戶開(kāi)啟的事務(wù),不能被其他事務(wù)的操作所干擾,多個(gè)并發(fā)事務(wù)之間要相互隔離。
? ? ? ?即要達(dá)到這么一種效果:對(duì)于任意兩個(gè)并發(fā)的事務(wù)T1和T2,在事務(wù)T1看來(lái),T2要么在T1開(kāi)始之前就已經(jīng)結(jié)束,要么在T1結(jié)束之后才開(kāi)始,這樣每個(gè)事務(wù)都感覺(jué)不到有其他事務(wù)在并發(fā)地執(zhí)行。

(4)持久性(Durable):
  事務(wù)完成之后,它對(duì)于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能夠保持。
  持久性是指一個(gè)事務(wù)一旦被提交了,那么對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)的改變就是永久性的,即便是在數(shù)據(jù)庫(kù)系統(tǒng)遇到故障的情況下也不會(huì)丟失提交事務(wù)的操作。Mysql中會(huì)保存有相應(yīng)的操作日志,即使遭遇故障依然能夠通過(guò)日志恢復(fù)最后一次更新。
  例如我們?cè)谑褂肑DBC操作數(shù)據(jù)庫(kù)時(shí),在提交事務(wù)方法后,提示用戶事務(wù)操作完成,當(dāng)我們程序執(zhí)行完成直到看到提示后,就可以認(rèn)定事務(wù)以及正確提交,即使這時(shí)候數(shù)據(jù)庫(kù)出現(xiàn)了問(wèn)題,也必須要將我們的事務(wù)完全執(zhí)行完成,否則就會(huì)造成我們看到提示事務(wù)處理完畢,但是數(shù)據(jù)庫(kù)因?yàn)楣收隙鴽](méi)有執(zhí)行事務(wù)的重大錯(cuò)誤。

簡(jiǎn)單理解:事務(wù)由一個(gè)或多個(gè)sql語(yǔ)句組成一個(gè)整體;
? ? 在事務(wù)中的操作,要么都執(zhí)行修改,要么都不執(zhí)行,
? ? 只有在該事務(wù)中所有的語(yǔ)句都執(zhí)行成功才會(huì)將修改加入到數(shù)據(jù)庫(kù)中,否則回滾到上一步。

Mysql實(shí)現(xiàn)事務(wù)

# start transaction; # 啟動(dòng)事務(wù): # update from account set money=money-100 where name='a'; # update from account set money=money+100 where name='b'; # commit; # 手動(dòng)關(guān)閉事務(wù)'

MySQL的事務(wù)隔離級(jí)別

  • 未提交讀(Read Uncommitted):允許臟讀,其他事務(wù)只要修改了數(shù)據(jù),即使未提交,本事務(wù)也能看到修改后的數(shù)據(jù)值。也就是可能讀取到其他會(huì)話中未提交事務(wù)修改的數(shù)據(jù)
  • 提交讀(Read Committed):只能讀取到已經(jīng)提交的數(shù)據(jù)。Oracle等多數(shù)數(shù)據(jù)庫(kù)默認(rèn)都是該級(jí)別 (不重復(fù)讀)。
  • 可重復(fù)讀(Repeated Read):可重復(fù)讀。無(wú)論其他事務(wù)是否修改并提交了數(shù)據(jù),在這個(gè)事務(wù)中看到的數(shù)據(jù)值始終不受其他事務(wù)影響。
  • 串行讀(Serializable):完全串行化的讀,每次讀都需要獲得表級(jí)共享鎖,讀寫(xiě)相互都會(huì)阻塞

MySQL數(shù)據(jù)庫(kù)(InnoDB引擎)默認(rèn)使用可重復(fù)讀( Repeatable read)

事務(wù)的并發(fā)問(wèn)題

  • 臟讀:事務(wù)A讀取了事務(wù)B更新的數(shù)據(jù),然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)
  • 不可重復(fù)讀:事務(wù) A 多次讀取同一數(shù)據(jù),事務(wù) B 在事務(wù)A多次讀取的過(guò)程中,對(duì)數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí),結(jié)果 不一致。
  • 幻讀:系統(tǒng)管理員A將數(shù)據(jù)庫(kù)中所有學(xué)生的成績(jī)從具體分?jǐn)?shù)改為ABCDE等級(jí),但是系統(tǒng)管理員B就在這個(gè)時(shí)候插入了一條具體分?jǐn)?shù)的記錄,當(dāng)系統(tǒng)管理員A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒(méi)有改過(guò)來(lái),就好像發(fā)生了幻覺(jué)一樣,這就叫幻讀。

小結(jié):不可重復(fù)讀的和幻讀很容易混淆,不可重復(fù)讀側(cè)重于修改,幻讀側(cè)重于新增或刪除。解決不可重復(fù)讀的問(wèn)題只需鎖住滿足條件的行,解決幻讀需要鎖表

事務(wù)隔離級(jí)別臟讀不可重復(fù)讀幻讀
讀未提交(read-uncommitted)
不可重復(fù)讀(read-committed)
可重復(fù)讀(repeatable-read)
串行化(serializable)

索引和約束

mysql 每個(gè)表最多16個(gè)約束

詳細(xì)請(qǐng)參考:https://blog.csdn.net/fenglepeng/article/details/103141756

數(shù)據(jù)庫(kù)五大約束

primary KEY:設(shè)置主鍵約束;
UNIQUE:設(shè)置唯一性約束,不能有重復(fù)值;
DEFAULT 默認(rèn)值約束 ? ?
NOT NULL:設(shè)置非空約束,該字段不能為空;
FOREIGN key :設(shè)置外鍵約束。

MySQL索引種類(lèi)

  • 普通索引:僅加速查詢
  • 唯一索引:加速查詢 + 列值唯一(可以有null)
  • 主鍵索引:加速查詢 + 列值唯一 + 表中只有一個(gè)(不可以有null)
  • 組合索引:多列值組成一個(gè)索引,專(zhuān)門(mén)用于組合搜索,其效率大于索引合并
  • 全文索引:對(duì)文本的內(nèi)容進(jìn)行分詞,進(jìn)行搜索

# 其他
? ? 1、索引合并:利用多個(gè)單列索引查詢
? ? 2、覆蓋索引:在索引表中就能將想要的數(shù)據(jù)查詢到

什么是索引合并?

# 索引合并訪問(wèn)方法可以在查詢中對(duì)一個(gè)表使用多個(gè)索引,對(duì)它們同時(shí)掃描,并且合并結(jié)果。
# 此訪問(wèn)方法合并來(lái)自單個(gè)表的索引掃描; 它不會(huì)將掃描合并到多個(gè)表中。

什么是覆蓋索引?

# 解釋一:
  就是select的數(shù)據(jù)列只用從索引中就能夠取得,不必從數(shù)據(jù)表中讀取,換句話說(shuō)查詢列要被所使用的索引覆蓋。
# 解釋二:
  索引是高效找到行的一個(gè)方法,當(dāng)能通過(guò)檢索索引就可以讀取想要的數(shù)據(jù),那就不需要再到數(shù)據(jù)表中讀取行了。
  如果一個(gè)索引包含了(或覆蓋了)滿足查詢語(yǔ)句中字段與條件的數(shù)據(jù)就叫做覆蓋索引。
# 注意:MySQL只能使用B-Tree索引做覆蓋索引

索引在什么情況下遵循最左前綴的規(guī)則?

主鍵和外鍵的區(qū)別?

'主鍵'
? ? 唯一標(biāo)識(shí)一條記錄
? ? 用來(lái)保證數(shù)據(jù)的完整性
? ? 主鍵只能有一個(gè)
'外鍵'
? ? 表的外鍵是另一個(gè)表的主鍵,外鍵可以有重復(fù)的,可以是空值
? ? 用來(lái)和其他表建立聯(lián)系用的
? ? 一個(gè)表可以有多個(gè)外鍵

列舉創(chuàng)建索引但是無(wú)法命中索引的8種情況。

使用'like ‘%xx’';select * from tb1 where name like '%cn';
使用'函數(shù)';select * from tb1 where reverse(name)='zgc';
使用'or';select * from tb1 where nid=1 or ?email='zgc@gmial.com';
? ? ? 特別的:當(dāng)or條件中有未建立索引的列才失效,以下會(huì)走索引
? ? ? ? ? ? # select * from tb1 where nid=1 or name='zgc';
? ? ? ? ? ? # select * from tb1 where nid=1 or email='zgc@gmial.com' and name='zgc';
類(lèi)型不一致,如果列是字符串類(lèi)型,傳入條件是必須用引號(hào)引起來(lái),不然則可能會(huì)無(wú)法命中
? ? select * from tb1 where name=666;
含有'!= ';?select * from tb1 where name != 'zgc';
? ? 特別的:如果是主鍵,還是會(huì)走索引;select * from tb1 where nid != 123;
含有'>';select * from tb1 where name > 'zgc';
? ? 特別的:如果是主鍵或者索引是整數(shù)類(lèi)型,則還是會(huì)走索引
? ? ? ? ? ? # select * from tb1 where nid > 123;
? ? ? ? ? ? # select * from tb1 where name > 123;
含有'order by';select email from tb1 order by name desc;
? ? 當(dāng)根據(jù)索引排序時(shí),選擇的映射如果不是索引,則不走索引
? ? 特別的:如果對(duì)主鍵排序,則還是走索引:
? ? ? ? ? ? # select * from tb1 order by nid desc;

#組合索引最左前綴
? ? 如果組合索引為:(name,email)
? ? name and email # 使用索引
? ? name ? ? ? ? ? # 使用索引
? ? email ? ? ? ? ?# 不使用索引

在對(duì)name做了唯一索引前提下,簡(jiǎn)述以下區(qū)別:

select * from tb where name = ‘小明’
select * from tb where name = ‘小明’ limit 1
沒(méi)做唯一索引的話,前者查詢會(huì)全表掃描,效率低些
limit 1,只要找到對(duì)應(yīng)一條數(shù)據(jù),就不繼續(xù)往下掃描.
然而 name 字段添加唯一索引了,加不加limit 1,意義都不大;

1000w條數(shù)據(jù),使用limit offset 分頁(yè)時(shí),為什么越往后翻越慢?如何解決?

例如:
#limit 100000,20; 從第十萬(wàn)條開(kāi)始往后取二十條,
#limit 20 offset 100000; limit后面是取20條數(shù)據(jù),offset后面是從先掃描前10w行,然后從10W條數(shù)據(jù)開(kāi)始讀
因?yàn)楫?dāng)一個(gè)數(shù)據(jù)庫(kù)表過(guò)于龐大,LIMIT offset, length中的offset值過(guò)大,則SQL查詢語(yǔ)句會(huì)非常緩慢
--------------------------------------------------------------------------
'優(yōu)化一'
先查看主鍵,再分頁(yè):
select * from tb where id in (select id from tb where limit 10 offset 30)
--------------------------------------------------------------------------
'優(yōu)化二'
記錄當(dāng)前頁(yè),數(shù)據(jù)、ID、最大值和最小值(用于where查詢)
在翻頁(yè)時(shí),根據(jù)條件進(jìn)行篩選,篩選完畢后,再根據(jù) limit offset 查詢
select * from(select * from tb where id > 2222) as B limit 10 offset 0;
# 如果用戶自己修改頁(yè)碼,也可能導(dǎo)致變慢,此時(shí)可以對(duì) url 頁(yè)碼進(jìn)行加密,例如rest framework
--------------------------------------------------------------------------
'優(yōu)化三'
可以按照當(dāng)前業(yè)務(wù)需求,看是否可以設(shè)置只允許看前200頁(yè);
一般情況下,沒(méi)人會(huì)咔咔看個(gè)幾十上百頁(yè)的;

MySQL中InnoDB引擎的行鎖是通過(guò)加在什么上完成(或稱(chēng)實(shí)現(xiàn))的?

InnoDB行鎖是通過(guò)給索引上的索引項(xiàng)加鎖來(lái)實(shí)現(xiàn)的,這一點(diǎn)MySQL與Oracle不同,后者是通過(guò)在數(shù)據(jù)塊中對(duì)相應(yīng)數(shù)據(jù)行加鎖來(lái)實(shí)現(xiàn)的。InnoDB這種行鎖實(shí)現(xiàn)特點(diǎn)意味著:只有通過(guò)索引條件檢索數(shù)據(jù),InnoDB才使用行級(jí)鎖,否則,InnoDB將使用表鎖!

InnoDB存儲(chǔ)引擎MVCC的實(shí)現(xiàn)策略

MVCC的實(shí)現(xiàn),通過(guò)保存數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)的快照來(lái)實(shí)現(xiàn)的。這意味著一個(gè)事務(wù)無(wú)論運(yùn)行多長(zhǎng)時(shí)間,在同一個(gè)事務(wù)里能夠看到數(shù)據(jù)一致的視圖。根據(jù)事務(wù)開(kāi)始的時(shí)間不同,同時(shí)也意味著在同一個(gè)時(shí)刻不同事務(wù)看到的相同表里的數(shù)據(jù)可能是不同的。

innodb:在每一行數(shù)據(jù)中額外保存兩個(gè)隱藏的列:當(dāng)前行創(chuàng)建時(shí)的版本號(hào)和刪除時(shí)的版本號(hào)(可能為空,其實(shí)還有一列稱(chēng)為回滾指針,用于事務(wù)回滾,不在本文范疇)。這里的版本號(hào)并不是實(shí)際的時(shí)間值,而是系統(tǒng)版本號(hào)。每開(kāi)始新的事務(wù),系統(tǒng)版本號(hào)都會(huì)自動(dòng)遞增。事務(wù)開(kāi)始時(shí)刻的系統(tǒng)版本號(hào)會(huì)作為事務(wù)的版本號(hào),用來(lái)和查詢每行記錄的版本號(hào)進(jìn)行比較。

每個(gè)事務(wù)又有自己的版本號(hào),這樣事務(wù)內(nèi)執(zhí)行CRUD操作時(shí),就通過(guò)版本號(hào)的比較來(lái)達(dá)到數(shù)據(jù)版本控制的目的。

索引與鎖有什么關(guān)系?

沒(méi)有建立索引的話我們?cè)谶M(jìn)行數(shù)據(jù)選取或者定位的時(shí)候是通過(guò)全表掃描的形式來(lái)進(jìn)行的,比如存在這樣一張表user(id,name,phone,address);并且這張表中并沒(méi)有任何索引,那么sql:delete from user where name='張三' 這樣一個(gè)語(yǔ)句是如何定義到張三這個(gè)記錄的,因?yàn)闆](méi)有索引,所以在數(shù)據(jù)庫(kù)實(shí)現(xiàn)的時(shí)候是對(duì)整張表進(jìn)行掃描的,那么數(shù)據(jù)庫(kù)是不是會(huì)把整張表鎖定起來(lái)。

?

在mysql中的鎖看起來(lái)是很復(fù)雜的,因?yàn)橛?strong>一大堆的東西和名詞:排它鎖,共享鎖,表鎖,頁(yè)鎖,間隙鎖,意向排它鎖,意向共享鎖,行鎖,讀鎖,寫(xiě)鎖,樂(lè)觀鎖,悲觀鎖,死鎖。這些名詞有的博客又直接寫(xiě)鎖的英文的簡(jiǎn)寫(xiě)--->X鎖,S鎖,IS鎖,IX鎖,MMVC...

對(duì)于UPDATE、DELETE、INSERT語(yǔ)句,InnoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖(X)

MyISAM在執(zhí)行查詢語(yǔ)句SELECT前,會(huì)自動(dòng)給涉及的所有表加讀鎖,在執(zhí)行更新操作(UPDATE、DELETE、INSERT等)前,會(huì)自動(dòng)給涉及的表加寫(xiě)鎖,這個(gè)過(guò)程并不需要用戶干預(yù)

數(shù)據(jù)庫(kù)事務(wù)有不同的隔離級(jí)別,不同的隔離級(jí)別對(duì)鎖的使用是不同的,鎖的應(yīng)用最終導(dǎo)致不同事務(wù)的隔離級(jí)別

MVCC(Multi-Version Concurrency Control)多版本并發(fā)控制,可以簡(jiǎn)單地認(rèn)為:MVCC就是行級(jí)鎖的一個(gè)變種(升級(jí)版)

事務(wù)的隔離級(jí)別就是通過(guò)鎖的機(jī)制來(lái)實(shí)現(xiàn),只不過(guò)隱藏了加鎖細(xì)節(jié)

表鎖中我們讀寫(xiě)是阻塞的,基于提升并發(fā)性能的考慮,MVCC一般讀寫(xiě)是不阻塞的(所以說(shuō)MVCC很多情況下避免了加鎖的操作)

MVCC實(shí)現(xiàn)的讀寫(xiě)不阻塞正如其名:多版本并發(fā)控制--->通過(guò)一定機(jī)制生成一個(gè)數(shù)據(jù)請(qǐng)求時(shí)間點(diǎn)的一致性數(shù)據(jù)快照(Snapshot),并用這個(gè)快照來(lái)提供一定級(jí)別(語(yǔ)句級(jí)或事務(wù)級(jí))的一致性讀取。從用戶的角度來(lái)看,好像是數(shù)據(jù)庫(kù)可以提供同一數(shù)據(jù)的多個(gè)版本

表中字段建立索引應(yīng)該遵循幾個(gè)原則:

  • 1)越小的數(shù)據(jù)類(lèi)型通常更好:越小的數(shù)據(jù)類(lèi)型通常在磁盤(pán)、內(nèi)存中都需要更少的空間,處理起來(lái)更快。
  • 2)簡(jiǎn)單的數(shù)據(jù)類(lèi)型更好:整型數(shù)據(jù)比起字符,處理開(kāi)銷(xiāo)更小,因?yàn)樽址谋容^更復(fù)雜,處理起來(lái)也更耗時(shí)。
  • 3)盡量避免NULL:應(yīng)該指定列為NOT NULL。含有空值的列很難進(jìn)行查詢優(yōu)化,因?yàn)樗鼈兪沟盟饕⑺饕慕y(tǒng)計(jì)信息以及比較運(yùn)算更加復(fù)雜。你應(yīng)該用0、一個(gè)特殊的值或者一個(gè)空串代替空值。
  • 4)對(duì)非唯一的字段,例如“性別”這種大量重復(fù)值的字段,增加索引也沒(méi)有什么意義,所以索引的建立應(yīng)當(dāng)更多的選取唯一性更高的字段。

1、列舉常見(jiàn)的關(guān)系型數(shù)據(jù)庫(kù)和非關(guān)系型都有那些?

關(guān)系型:sqllite、db2、oracle、access、SQLserver、MySQL
?????# 注意:sql語(yǔ)句通用,需要有表結(jié)構(gòu)
非關(guān)系型:mongodb、redis、memcache
????# 非關(guān)系型數(shù)據(jù)庫(kù)是key-value存儲(chǔ)的,沒(méi)有表結(jié)構(gòu)。

2、MySQL常見(jiàn)數(shù)據(jù)庫(kù)引擎

MySQL有多種存儲(chǔ)引擎:MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE

3、MyISAM 和 InnoDB 的區(qū)別

1)事務(wù)支持:
? ???MyISAM:強(qiáng)調(diào)的是性能,每次查詢具有原子性,其執(zhí)行數(shù)度比InnoDB類(lèi)型更快,但是不提供事務(wù)支持。
?????InnoDB:提供事務(wù)支持事務(wù),外部鍵等高級(jí)數(shù)據(jù)庫(kù)功能。 具有事務(wù)(commit)、回滾(rollback)和崩潰修復(fù)能力(crash recovery capabilities)的事務(wù)安全(transaction-safe (ACID compliant))型表。

2)MyISAM適合查詢以及插入為主的應(yīng)用,InnoDB適合頻繁修改以及涉及到安全性較高的應(yīng)用。

3)InnoDB支持外鍵,MyISAM不支持。InnoDB支持MVCC(多版本并發(fā)控制), 而MyISAM不支持。

4)從MySQL5.5.5以后,InnoDB是默認(rèn)引擎。

5)MyISAM支持全文類(lèi)型索引,而InnoDB不支持全文索引。

6)InnoDB中不保存表的總行數(shù),select count(*) from table時(shí),InnoDB需要掃描整個(gè)表計(jì)算有多少行,但MyISAM只需簡(jiǎn)單讀出保存好的總行數(shù)即可。注:當(dāng)count(*)語(yǔ)句包含where條件時(shí)MyISAM也需掃描整個(gè)表。

7)對(duì)于自增長(zhǎng)的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯(lián)合索引。

8)清空整個(gè)表時(shí),InnoDB是一行一行的刪除,效率非常慢。MyISAM則會(huì)重建表。MyisAM使用delete語(yǔ)句刪除后并不會(huì)立刻清理磁盤(pán)空間,需要定時(shí)清理,命令:OPTIMIZE table dept;

9)InnoDB支持行鎖(某些情況下還是鎖整表,如?update table set a=1 where user like ‘%lee%’)

10)存儲(chǔ)結(jié)構(gòu):
? ? ? ? MyISAM:每個(gè)MyISAM在磁盤(pán)上存儲(chǔ)成三個(gè)文件。第一個(gè)文件的名字以表的名字開(kāi)始,擴(kuò)展名指出文件類(lèi)型。.frm文件存儲(chǔ)表定義。數(shù)據(jù)文件的擴(kuò)展名為.MYD (MYData)。索引文件的擴(kuò)展名是.MYI (MYIndex)。
? ? ? ? InnoDB:所有的表都保存在同一個(gè)數(shù)據(jù)文件中(也可能是多個(gè)文件,或者是獨(dú)立的表空間文件),InnoDB表的大小只受限于操作系統(tǒng)文件的大小,一般為2GB

11)表主鍵:
? ? ? ? ?MyISAM:允許沒(méi)有任何索引和主鍵的表存在,索引都是保存行的地址。
? ? ? ? ?InnoDB:如果沒(méi)有設(shè)定主鍵或者非空唯一索引,就會(huì)自動(dòng)生成一個(gè)字節(jié)的主鍵(用戶不可見(jiàn)),數(shù)據(jù)是主索引的一部分,附加索引保存的是主索引的值。

12)可移植性、備份及恢復(fù):
? ? ? ? MyISAM:數(shù)據(jù)是以文件的形式存儲(chǔ),所以在跨平臺(tái)的數(shù)據(jù)轉(zhuǎn)移中會(huì)很方便。在備份和恢復(fù)時(shí)可單獨(dú)針對(duì)某個(gè)表進(jìn)行操作。
? ? ? ?InnoDB:免費(fèi)的方案可以是拷貝數(shù)據(jù)文件、備份 binlog,或者用 mysqldump,在數(shù)據(jù)量達(dá)到幾十G的時(shí)候就相對(duì)痛苦了

應(yīng)用場(chǎng)景:

  • MyISAM不支持事務(wù)處理等高級(jí)功能,但它提供高速存儲(chǔ)和檢索,以及全文搜索能力。如果應(yīng)用中需要執(zhí)行大量的SELECT查詢,那么MyISAM是更好的選擇。
  • InnoDB用于需要事務(wù)處理的應(yīng)用程序,包括ACID事務(wù)支持。如果應(yīng)用中需要執(zhí)行大量的INSERT或UPDATE操作,則應(yīng)該使用InnoDB,這樣可以提高多用戶并發(fā)操作的性能。一般都選用InnoDB

Mysql中有哪幾種鎖?

表鎖:select * from tb for update;(鎖:for update)
行鎖:select id ,name from tb where id=2 for update;(鎖:for update)

  • MyISAM支持表鎖,InnoDB支持表鎖和行鎖,默認(rèn)為行鎖
  • 表級(jí)鎖:開(kāi)銷(xiāo)小,加鎖快,不會(huì)出現(xiàn)死鎖。鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)量最低
  • 行級(jí)鎖:開(kāi)銷(xiāo)大,加鎖慢,會(huì)出現(xiàn)死鎖。鎖力度小,發(fā)生鎖沖突的概率小,并發(fā)度最高

3、簡(jiǎn)述數(shù)據(jù)三大范式?

據(jù)庫(kù)的三大特性:
'實(shí)體':表
'屬性':表中的數(shù)據(jù)(字段)
'關(guān)系':表與表之間的關(guān)系
----------------------------------------------------
數(shù)據(jù)庫(kù)設(shè)計(jì)三大范式:
第一范式(1NF):字段具有原子性,不可再分。(所有關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)都滿足第一范式數(shù)據(jù)庫(kù)表中的字段都是單一屬性的,不可再分)
第二范式(2NF)是在第一范式(1NF)的基礎(chǔ)上建立起來(lái)的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。要求數(shù)據(jù)庫(kù)表中的每個(gè)實(shí)例或行必須可以被惟一地區(qū)分。通常需要為表加上一個(gè)列,以存儲(chǔ)各個(gè)實(shí)例的惟一標(biāo)識(shí)。這個(gè)惟一屬性列被稱(chēng)為主關(guān)鍵字或主鍵。
滿足第三范式(3NF)必須先滿足第二范式(2NF)。簡(jiǎn)而言之,第三范式(3NF)要求一個(gè)數(shù)據(jù)庫(kù)表中不包含已在其它表中已包含的非主關(guān)鍵字信息。
所以第三范式具有如下特征:
?1. 每一列只有一個(gè)值
?2. 每一行都能區(qū)分。
?3. 每一個(gè)表都不包含其他表已經(jīng)包含的非主關(guān)鍵字信息。

6、簡(jiǎn)述數(shù)據(jù)庫(kù)設(shè)計(jì)中一對(duì)多和多對(duì)多的應(yīng)用場(chǎng)景?

一對(duì)一關(guān)系示例:
  一個(gè)學(xué)生對(duì)應(yīng)一個(gè)學(xué)生檔案材料,或者每個(gè)人都有唯一的身份證編號(hào)。
一對(duì)多關(guān)系示例:(下拉單選)
  一個(gè)學(xué)生只屬于一個(gè)班,但是一個(gè)班級(jí)有多名學(xué)生。
多對(duì)多關(guān)系示例:(下拉多選)
  一個(gè)學(xué)生可以選擇多門(mén)課,一門(mén)課也有多名學(xué)生。

7、如何基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)商城商品計(jì)數(shù)器?

參考:點(diǎn)擊查看

8、常見(jiàn)SQL(必備)

詳見(jiàn):點(diǎn)擊查看

9、簡(jiǎn)述觸發(fā)器、函數(shù)、視圖、存儲(chǔ)過(guò)程?

觸發(fā)器:
? ? 對(duì)數(shù)據(jù)庫(kù)某個(gè)表進(jìn)行【增、刪、改】前后,自定義的一些SQL操作
函數(shù):
? ? 在SQL語(yǔ)句中使用的函數(shù) #例如:select sleep(2)
? ? 聚合函數(shù):max、sam、min、avg
? ? 時(shí)間格式化:date_format
? ? 字符串拼接:concat
? ? 自定制函數(shù):(觸發(fā)函數(shù)通過(guò) select)
視圖:
? ? 對(duì)某些表進(jìn)行SQL查詢,將結(jié)果實(shí)時(shí)顯示出來(lái)(是虛擬表),只能查詢不能更新
存儲(chǔ)過(guò)程:
? ? 將提前定義好的SQL語(yǔ)句保存到數(shù)據(jù)庫(kù)中并命名;以后在代碼中調(diào)用時(shí)直接通過(guò)名稱(chēng)即可
? ? 參數(shù)類(lèi)型:in、out、inout

13、MySQL常見(jiàn)的函數(shù)?

'當(dāng)前時(shí)間'
? ? select now();
'時(shí)間格式化'
? ? select DATE_FORMAT(NOW(), '%Y(年)-%m(月)-%d(日) %H(時(shí)):%i(分):%s(秒)')
'日期加減'
? ? select DATE_ADD(DATE, INTERVAL expr unit)
? ? select DATE_ADD(NOW(), INTERVAL 1 DAY) #當(dāng)前日期加一天
? ? \expr:正數(shù)(加)、負(fù)數(shù)(減)
? ? \unit:支持毫秒microsecond、秒second、小時(shí)hour、天day、周week、年year
'類(lèi)型轉(zhuǎn)換'
? ? cast( expr AS TYPE)?
? ? select CAST(123 AS CHAR)
'字符串拼接'
? ? concat(str1,str2,……)
? ? select concat('hello','2','world') --> hellow2world
'聚合函數(shù)'
? ? avg() #平均值
? ? count() #返回指定列/行的個(gè)數(shù)
? ? min() #最小值
? ? max() #最大值
? ? sum() #求和
? ? group_concat() #返回屬于一組的列值,連接組合而成的結(jié)果
'數(shù)學(xué)函數(shù)'
? ? abs() #絕對(duì)值
? ? bin() #二進(jìn)制
? ? rand() #隨機(jī)數(shù)

15、如何開(kāi)啟慢日志查詢?

可以通過(guò)修改配置文件開(kāi)啟
slow_query_log=ON ? ? ? # 是否開(kāi)啟慢日志記錄
long_query_time=2 ? ? ? # 時(shí)間限制,超過(guò)此時(shí)間,則記錄
slow_query_log_file=/usr/slow.log ?# 日志文件
long_queries_not_using_indexes=ON ?# 是否記錄使用索引的搜索

16、數(shù)據(jù)庫(kù)導(dǎo)入導(dǎo)出命令(結(jié)構(gòu)+數(shù)據(jù))?

# 導(dǎo)出:
? ? mysqldump --no-defaults -uroot -p 數(shù)據(jù)庫(kù)名字 > 導(dǎo)出路徑
? ? '--no-defaults':解決“unknown option --no-beep”報(bào)錯(cuò)
# 導(dǎo)入:
? ? 1、mysqldump -uroot -p 數(shù)據(jù)庫(kù)名稱(chēng) < 路徑
? ? 2、進(jìn)入數(shù)據(jù)庫(kù); source + 要導(dǎo)入數(shù)據(jù)庫(kù)文件路徑

數(shù)據(jù)庫(kù)優(yōu)化方案?

詳細(xì)可參考:https://blog.csdn.net/fenglepeng/article/details/103400418

1、創(chuàng)建數(shù)據(jù)表時(shí)把固定長(zhǎng)度的放在前面
2、將固定數(shù)據(jù)放入內(nèi)存:choice字段(django中用到,1,2,3對(duì)應(yīng)相應(yīng)內(nèi)容)
3、char不可變,varchar可變
4、聯(lián)合索引遵循最左前綴(從最左側(cè)開(kāi)始檢索)
5、避免使用 select *
6、讀寫(xiě)分離:
? ? #利用數(shù)據(jù)庫(kù)的主從分離:主,用于刪除、修改、更新;從,用于查
? ? #實(shí)現(xiàn):兩臺(tái)服務(wù)器同步數(shù)據(jù)
? ? \原生SQL:select * from db.tb
? ? \ORM:model.User.object.all().using('default')
? ? \路由:db router
7、分庫(kù)
? ? # 當(dāng)數(shù)據(jù)庫(kù)中的表太多,將某些表分到不同數(shù)據(jù)庫(kù),例如:1W張表時(shí)
? ? # 代價(jià):連表查詢跨數(shù)據(jù)庫(kù),代碼變多
8、分表
? ? # 水平分表:將某些列拆分到另一張表,例如:博客+博客詳情
? ? # 垂直分表:將某些歷史信息,分到另外一張表中,例如:支付寶賬單
9、加緩存
? ? # 利用redis、memcache(常用數(shù)據(jù)放到緩存里,提高取數(shù)據(jù)速度)
? ? # 緩存不夠可能會(huì)造成雪崩現(xiàn)象
10、如果只想獲取一條數(shù)據(jù)
? ? select * from tb where name = 'zgc' limit 1;

19、簡(jiǎn)述MySQL的執(zhí)行計(jì)劃?

詳細(xì)可參考:https://blog.csdn.net/fenglepeng/article/details/103392319

# explain + SQL語(yǔ)句
# SQL在數(shù)據(jù)庫(kù)中執(zhí)行時(shí)的表現(xiàn)情況,通常用于SQL性能分析,優(yōu)化等場(chǎng)景。
?'explain select * from rbac_userinfo where id=1;'

24、簡(jiǎn)述數(shù)據(jù)庫(kù)讀寫(xiě)分離?

# 利用數(shù)據(jù)庫(kù)的主從分離:主,用于刪除、修改、更新;從,用于查
#實(shí)現(xiàn):兩臺(tái)服務(wù)器同步數(shù)據(jù)(減輕服務(wù)器的壓力)
? ? ? ?原生SQL: select * from db.tb
? ? ? ?ORM:model.User.object.all().using('default')
? ? ? ?路由:db router

25、簡(jiǎn)述數(shù)據(jù)庫(kù)分庫(kù)分表?(水平、垂直)

# 1、分庫(kù)
? ? 當(dāng)數(shù)據(jù)庫(kù)中的表太多,將某些表分到不同數(shù)據(jù)庫(kù),例如:1W張表時(shí)
? ? 代價(jià):連表查詢跨數(shù)據(jù)庫(kù),代碼變多
# 2、分表
? ? 水平分表:將某些列拆分到另一張表,例如:博客+博客詳情
? ? 垂直分表:將某些歷史信息,分到另外一張表中,例如:支付寶賬單

char和varchar、Varbinary 存儲(chǔ)字符的區(qū)別?

char使用固定長(zhǎng)度的空間進(jìn)行存儲(chǔ),char(4)存儲(chǔ)4個(gè)字符,根據(jù)編碼方式的不同占用不同的字節(jié),gbk編碼方式,不論是中文還是英文,每個(gè)字符占用2個(gè)字節(jié)的空間,utf8編碼方式,每個(gè)字符占用3個(gè)字節(jié)的空間。

如果需要存儲(chǔ)的字符串的長(zhǎng)度跟所有值的平均長(zhǎng)度相差不大(定值),適合用char。
對(duì)于經(jīng)常改變的值,char優(yōu)于varchar,原因是固定長(zhǎng)度的行不容易產(chǎn)生碎片。

對(duì)于很短的列,char優(yōu)于varchar,原因是varchar需要額外一個(gè)或兩個(gè)字節(jié)存儲(chǔ)字符串的長(zhǎng)度。

varchar保存可變長(zhǎng)度的字符串,使用額外的一個(gè)或兩個(gè)字節(jié)存儲(chǔ)字符串長(zhǎng)度,varchar(10),除了需要存儲(chǔ)10個(gè)字符,還需要1個(gè)字節(jié)存儲(chǔ)長(zhǎng)度信息(10),超過(guò)255的長(zhǎng)度需要2個(gè)字節(jié)來(lái)存儲(chǔ)

binary保存二進(jìn)制字符串,它保存的是字節(jié)而不是字符,沒(méi)有字符集限制

binary(8)可以保存8個(gè)字符,每個(gè)字符占1個(gè)字節(jié),共占8個(gè)字節(jié)(01串)

delete、drop、truncate區(qū)別

  • truncate?和?delete只刪除數(shù)據(jù),不刪除表結(jié)構(gòu)?,drop刪除表結(jié)構(gòu),并且釋放所占的空間。
  • 刪除數(shù)據(jù)的速度,drop> truncate > delete
  • delete屬于DML語(yǔ)言,需要事務(wù)管理,commit之后才能生效。drop和truncate屬于DDL語(yǔ)言,操作立刻生效,不可回滾。
  • 使用場(chǎng)合:
    • 當(dāng)你不再需要該表時(shí), 用?drop;
    • 當(dāng)你仍要保留該表,但要?jiǎng)h除所有記錄時(shí), 用?truncate;
    • 當(dāng)你要?jiǎng)h除部分記錄時(shí)(always with a where clause),?用?delete.

Float、Decimal 存儲(chǔ)金額的區(qū)別?

浮點(diǎn)數(shù)計(jì)算都不準(zhǔn)(只要不是2的整數(shù)倍都會(huì)有問(wèn)題)。decimal存儲(chǔ)其實(shí)是string類(lèi)型存儲(chǔ)。

Datetime、Timestamp 存儲(chǔ)時(shí)間的區(qū)別?

對(duì)于TIMESTAMP,它把客戶端插入的時(shí)間從當(dāng)前時(shí)區(qū)轉(zhuǎn)化為UTC(世界標(biāo)準(zhǔn)時(shí)間)進(jìn)行存儲(chǔ)。查詢時(shí),將其又轉(zhuǎn)化為客戶端當(dāng)前時(shí)區(qū)進(jìn)行返回。對(duì)于跨時(shí)區(qū)的業(yè)務(wù),TIMESTAMP更為合適。

而對(duì)于DATETIME,不做任何改變,基本上是原樣輸入和輸出。

HAVING 子句 和 WHERE的異同點(diǎn)?

語(yǔ)法上:where 用表中列名,having用select結(jié)果別名
影響結(jié)果范圍:where從表讀出數(shù)據(jù)的行數(shù),having返回客戶端的行數(shù)
索引:where 可以使用索引,having不能使用索引,只能在臨時(shí)結(jié)果集操作
where后面不能使用聚集函數(shù),having是專(zhuān)門(mén)使用聚集函數(shù)的。

mysql 備份

mysql的復(fù)制原理以及流程。

Mysql內(nèi)建的復(fù)制功能是構(gòu)建大型,高性能應(yīng)用程序的基礎(chǔ)。將Mysql的數(shù)據(jù)分布到多個(gè)系統(tǒng)上去,這種分布的機(jī)制,是通過(guò)將Mysql的某一臺(tái)主機(jī)的數(shù)據(jù)復(fù)制到其它主機(jī)(slaves)上,并重新執(zhí)行一遍來(lái)實(shí)現(xiàn)的.

復(fù)制過(guò)程中一個(gè)服務(wù)器充當(dāng)主服務(wù)器,而一個(gè)或多個(gè)其它服務(wù)器充當(dāng)從服務(wù)器。主服務(wù)器將更新寫(xiě)入二進(jìn)制日志文件,并維護(hù)文件的一個(gè)索引以跟蹤日志循環(huán)。這些日志可以記錄發(fā)送到從服務(wù)器的更新。 當(dāng)一個(gè)從服務(wù)器連接主服務(wù)器時(shí),它通知主服務(wù)器在日志中讀取的最后一次成功更新的位置。從服務(wù)器接收從那時(shí)起發(fā)生的任何更新,然后封鎖并等待主服務(wù)器通知新的更新。 過(guò)程如下

主服務(wù)器把更新記錄到二進(jìn)制日志文件中。
從服務(wù)器把主服務(wù)器的二進(jìn)制日志拷貝到自己的中繼日志(replay log)中。
從服務(wù)器重做中繼日志中的時(shí)間,把更新應(yīng)用到自己的數(shù)據(jù)庫(kù)上。

mysql支持的復(fù)制類(lèi)型?

基于語(yǔ)句的復(fù)制: 在主服務(wù)器上執(zhí)行的SQL語(yǔ)句,在從服務(wù)器上執(zhí)行同樣的語(yǔ)句。MySQL默認(rèn)采用基于語(yǔ)句的復(fù)制,效率比較高。 一旦發(fā)現(xiàn)沒(méi)法精確復(fù)制時(shí),會(huì)自動(dòng)選著基于行的復(fù)制。
基于行的復(fù)制:把改變的內(nèi)容復(fù)制過(guò)去,而不是把命令在從服務(wù)器上執(zhí)行一遍. 從mysql5.0開(kāi)始支持
混合類(lèi)型的復(fù)制: 默認(rèn)采用基于語(yǔ)句的復(fù)制,一旦發(fā)現(xiàn)基于語(yǔ)句的無(wú)法精確的復(fù)制時(shí),就會(huì)采用基于行的復(fù)制。

MySQL的binlog有有幾種錄入格式?分別有什么區(qū)別?

有三種格式,statement,row和mixed.

  • statement模式下,記錄單元為語(yǔ)句.即每一個(gè)sql造成的影響會(huì)記錄.由于sql的執(zhí)行是有上下文的,因此在保存的時(shí)候需要保存相關(guān)的信息,同時(shí)還有一些使用了函數(shù)之類(lèi)的語(yǔ)句無(wú)法被記錄復(fù)制.

  • row級(jí)別下,記錄單元為每一行的改動(dòng),基本是可以全部記下來(lái)但是由于很多操作,會(huì)導(dǎo)致大量行的改動(dòng)(比如alter table),因此這種模式的文件保存的信息太多,日志量太大.

  • mixed. 一種折中的方案,普通操作使用statement記錄,當(dāng)無(wú)法使用statement的時(shí)候使用row.

MySQL中空值和NULL的區(qū)別?

  • 空值(”)是不占用空間的,判斷空字符用 = ” 或者 <> ” 來(lái)進(jìn)行處理。
  • NULL值是未知的,且占用空間,不走索引;判斷 NULL 用 IS NULL 或者 is not null ,SQL 語(yǔ)句函數(shù)中可以使用 ifnull ()函數(shù)來(lái)進(jìn)行處理。
  • 無(wú)法比較 NULL 和 0;它們是不等價(jià)的。
  • 無(wú)法使用比較運(yùn)算符來(lái)測(cè)試 NULL 值,比如 =, <, 或者 <>。
  • NULL?值可以使用?<=>?符號(hào)進(jìn)行比較,該符號(hào)與等號(hào)作用相似,但對(duì)NULL有意義。
  • 進(jìn)行 count ()統(tǒng)計(jì)某列的記錄數(shù)的時(shí)候,如果采用的 NULL 值,會(huì)別系統(tǒng)自動(dòng)忽略掉,但是空值是統(tǒng)計(jì)到其中。

總結(jié)

以上是生活随笔為你收集整理的面试之 Mysql 汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。