一、數(shù)據(jù)庫(kù)知識(shí)(通用)篇
1.說(shuō)說(shuō)主鍵、外鍵、超鍵、候選鍵
超鍵:在關(guān)系中能唯一標(biāo)識(shí)元組的屬性集稱為關(guān)系模式的超鍵。一個(gè)屬性可以為作為一個(gè)超鍵,多個(gè)屬性組合在一起也可以作為一個(gè)超鍵。超鍵包含候選鍵和主鍵。候選鍵:是最小超鍵,即沒(méi)有冗余元素的超鍵。主鍵:數(shù)據(jù)庫(kù)表中對(duì)儲(chǔ)存數(shù)據(jù)對(duì)象予以唯一和完整標(biāo)識(shí)的數(shù)據(jù)列或?qū)傩缘慕M合。一個(gè)數(shù)據(jù)列只能有一個(gè)主鍵,且主鍵的取值不能缺失,即不能為空值(Null)。外鍵:在一個(gè)表中存在的另一個(gè)表的主鍵稱此表的外鍵。
2.為什么用自增列作為主鍵?
如果我們定義了主鍵(PRIMARY KEY),那么InnoDB會(huì)選擇主鍵作為聚集索引、如果沒(méi)有顯式定義主鍵,則InnoDB會(huì)選擇第一個(gè)不包含有NULL值的唯一索引作為主鍵索引、如果也沒(méi)有這樣的唯一索引,則InnoDB會(huì)選擇內(nèi)置6字節(jié)長(zhǎng)的ROWID作為隱含的聚集索引(ROWID隨著行記錄的寫(xiě)入而主鍵遞增,這個(gè)ROWID不像ORACLE的ROWID那樣可引用,是隱含的)。數(shù)據(jù)記錄本身被存于主索引(一顆B+Tree)的葉子節(jié)點(diǎn)上。這就要求同一個(gè)葉子節(jié)點(diǎn)內(nèi)(大小為一個(gè)內(nèi)存頁(yè)或磁盤(pán)頁(yè))的各條數(shù)據(jù)記錄按主鍵順序存放,因此每當(dāng)有一條新的記錄插入時(shí),MySQL會(huì)根據(jù)其主鍵將其插入適當(dāng)?shù)墓?jié)點(diǎn)和位置,如果頁(yè)面達(dá)到裝載因子(InnoDB默認(rèn)為15/16),則開(kāi)辟一個(gè)新的頁(yè)(節(jié)點(diǎn))如果表使用自增主鍵,那么每次插入新的記錄,記錄就會(huì)順序添加到當(dāng)前索引節(jié)點(diǎn)的后續(xù)位置,當(dāng)一頁(yè)寫(xiě)滿,就會(huì)自動(dòng)開(kāi)辟一個(gè)新的頁(yè)如果使用非自增主鍵(如果身份證號(hào)或?qū)W號(hào)等),由于每次插入主鍵的值近似于隨機(jī),因此每次新記錄都要被插到現(xiàn)有索引頁(yè)的中間某個(gè)位置,此時(shí)MySQL不得不為了將新記錄插到合適位置而移動(dòng)數(shù)據(jù),甚至目標(biāo)頁(yè)面可能已經(jīng)被回寫(xiě)到磁盤(pán)上而從緩存中清掉,此時(shí)又要從磁盤(pán)上讀回來(lái),這增加了很多開(kāi)銷,同時(shí)頻繁的移動(dòng)、分頁(yè)操作造成了大量的碎片,得到了不夠緊湊的索引結(jié)構(gòu),后續(xù)不得不通過(guò)OPTIMIZE TABLE來(lái)重建表并優(yōu)化填充頁(yè)面。
3.觸發(fā)器的作用是什么?
觸發(fā)器是一種特殊的存儲(chǔ)過(guò)程,主要是通過(guò)事件來(lái)觸發(fā)而被執(zhí)行的。它可以強(qiáng)化約束,來(lái)維護(hù)數(shù)據(jù)的完整性和一致性,可以跟蹤數(shù)據(jù)庫(kù)內(nèi)的操作從而不允許未經(jīng)許可的更新和變化??梢月?lián)級(jí)運(yùn)算。如,某表上的觸發(fā)器上包含對(duì)另一個(gè)表的數(shù)據(jù)操作,而該操作又會(huì)導(dǎo)致該表觸發(fā)器被觸發(fā)。
4.什么是存儲(chǔ)過(guò)程?用什么來(lái)調(diào)用?
存儲(chǔ)過(guò)程是一個(gè)預(yù)編譯的SQL語(yǔ)句,優(yōu)點(diǎn)是允許模塊化的設(shè)計(jì),就是說(shuō)只需創(chuàng)建一次,以后在該程序中就可以調(diào)用多次。如果某次操作需要執(zhí)行多次SQL,使用存儲(chǔ)過(guò)程比單純SQL語(yǔ)句執(zhí)行要快。調(diào)用:1)可以用一個(gè)命令對(duì)象來(lái)調(diào)用存儲(chǔ)過(guò)程。2)可以供外部程序調(diào)用,比如:java程序。
5.說(shuō)說(shuō)存儲(chǔ)過(guò)程的優(yōu)缺點(diǎn)?
優(yōu)點(diǎn):1)存儲(chǔ)過(guò)程是預(yù)編譯過(guò)的,執(zhí)行效率高。2)存儲(chǔ)過(guò)程的代碼直接存放于數(shù)據(jù)庫(kù)中,通過(guò)存儲(chǔ)過(guò)程名直接調(diào)用,減少網(wǎng)絡(luò)通訊。3)安全性高,執(zhí)行存儲(chǔ)過(guò)程需要有一定權(quán)限的用戶。4)存儲(chǔ)過(guò)程可以重復(fù)使用,可減少數(shù)據(jù)庫(kù)開(kāi)發(fā)人員的工作量。缺點(diǎn):移植性差
6.說(shuō)說(shuō)存儲(chǔ)過(guò)程與函數(shù)的區(qū)別
(1)存儲(chǔ)過(guò)程用戶在數(shù)據(jù)庫(kù)中完成特定操作或者任務(wù)(如插入,刪除等),函數(shù)用于返回特定的數(shù)據(jù)。(2)存儲(chǔ)過(guò)程聲明用procedure,函數(shù)用function。(3)存儲(chǔ)過(guò)程不需要返回類型,函數(shù)必須要返回類型。(4)存儲(chǔ)過(guò)程可作為獨(dú)立的pl-sql執(zhí)行,函數(shù)不能作為獨(dú)立的plsql執(zhí)行,必須作為表達(dá)式的一部分。(5)存儲(chǔ)過(guò)程只能通過(guò)out和in/out來(lái)返回值,函數(shù)除了可以使用out,in/out以外,還可以使用return返回值。(6)sql語(yǔ)句(DML或SELECT)中不可用調(diào)用存儲(chǔ)過(guò)程,而函數(shù)可以。
7.什么叫視圖?游標(biāo)是什么?
視圖:是一種虛擬的表,具有和物理表相同的功能。可以對(duì)視圖進(jìn)行增,改,查,操作,試圖通常是有一個(gè)表或者多個(gè)表的行或列的子集。對(duì)視圖的修改會(huì)影響基本表。它使得我們獲取數(shù)據(jù)更容易,相比多表查詢。游標(biāo):是對(duì)查詢出來(lái)的結(jié)果集作為一個(gè)單元來(lái)有效的處理。游標(biāo)可以定在該單元中的特定行,從結(jié)果集的當(dāng)前行檢索一行或多行。可以對(duì)結(jié)果集當(dāng)前行做修改。一般不使用游標(biāo),但是需要逐條處理數(shù)據(jù)的時(shí)候,游標(biāo)顯得十分重要。
8.視圖的優(yōu)缺點(diǎn)有哪些?
優(yōu)點(diǎn):1對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),因?yàn)橐晥D可以有選擇性的選取數(shù)據(jù)庫(kù)里的一部分。2)用戶通過(guò)簡(jiǎn)單的查詢可以從復(fù)雜查詢中得到結(jié)果。3)維護(hù)數(shù)據(jù)的獨(dú)立性,試圖可從多個(gè)表檢索數(shù)據(jù)。4)對(duì)于相同的數(shù)據(jù)可產(chǎn)生不同的視圖。缺點(diǎn):性能:查詢視圖時(shí),必須把視圖的查詢轉(zhuǎn)化成對(duì)基本表的查詢,如果這個(gè)視圖是由一個(gè)復(fù)雜的多表查詢所定義,那么,那么就無(wú)法更改數(shù)據(jù)
9.說(shuō)說(shuō)drop、truncate、 delete區(qū)別
最基本:1) drop直接刪掉表。2) truncate刪除表中數(shù)據(jù),再插入時(shí)自增長(zhǎng)id又從1開(kāi)始。3) delete刪除表中數(shù)據(jù),可以加where字句。
(1) DELETE語(yǔ)句執(zhí)行刪除的過(guò)程是每次從表中刪除一行,并且同時(shí)將該行的刪除操作作為事務(wù)記錄在日志中保存以便進(jìn)行進(jìn)行回滾操作。TRUNCATE TABLE 則一次性地從表中刪除所有的數(shù)據(jù)并不把單獨(dú)的刪除操作記錄記入日志保存,刪除行是不能恢復(fù)的。并且在刪除的過(guò)程中不會(huì)激活與表有關(guān)的刪除觸發(fā)器。執(zhí)行速度快。(2) 表和索引所占空間。當(dāng)表被TRUNCATE 后,這個(gè)表和索引所占用的空間會(huì)恢復(fù)到初始大小,而DELETE操作不會(huì)減少表或索引所占用的空間。drop語(yǔ)句將表所占用的空間全釋放掉。(3) 一般而言,drop > truncate > delete(4) 應(yīng)用范圍。TRUNCATE 只能對(duì)TABLE;DELETE可以是table和view(5) TRUNCATE 和DELETE只刪除數(shù)據(jù),而DROP則刪除整個(gè)表(結(jié)構(gòu)和數(shù)據(jù))。(6) truncate與不帶where的delete :只刪除數(shù)據(jù),而不刪除表的結(jié)構(gòu)(定義)drop語(yǔ)句將刪除表的結(jié)構(gòu)被依賴的約束(constrain),觸發(fā)器(trigger)索引(index);依賴于該表的存儲(chǔ)過(guò)程/函數(shù)將被保留,但其狀態(tài)會(huì)變?yōu)椋篿nvalid。(7) delete語(yǔ)句為DML(data maintain Language),這個(gè)操作會(huì)被放到 rollback segment中,事務(wù)提交后才生效。如果有相應(yīng)的 tigger,執(zhí)行的時(shí)候?qū)⒈挥|發(fā)。(8) truncate、drop是DLL(data define language),操作立即生效,原數(shù)據(jù)不放到 rollback segment中,不能回滾。(9) 在沒(méi)有備份情況下,謹(jǐn)慎使用 drop 與 truncate。要?jiǎng)h除部分?jǐn)?shù)據(jù)行采用delete且注意結(jié)合where來(lái)約束影響范圍。回滾段要足夠大。要?jiǎng)h除表用drop;若想保留表而將表中數(shù)據(jù)刪除,如果與事務(wù)無(wú)關(guān),用truncate即可實(shí)現(xiàn)。如果和事務(wù)有關(guān),或老師想觸發(fā)trigger,還是用delete。(10) Truncate table 表名 速度快,而且效率高,因?yàn)??truncate table 在功能上與不帶 WHERE 子句的 DELETE 語(yǔ)句相同:二者均刪除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系統(tǒng)和事務(wù)日志資源少。DELETE 語(yǔ)句每次刪除一行,并在事務(wù)日志中為所刪除的每行記錄一項(xiàng)。TRUNCATE TABLE 通過(guò)釋放存儲(chǔ)表數(shù)據(jù)所用的數(shù)據(jù)頁(yè)來(lái)刪除數(shù)據(jù),并且只在事務(wù)日志中記錄頁(yè)的釋放。(11) TRUNCATE TABLE 刪除表中的所有行,但表結(jié)構(gòu)及其列、約束、索引等保持不變。新行標(biāo)識(shí)所用的計(jì)數(shù)值重置為該列的種子。如果想保留標(biāo)識(shí)計(jì)數(shù)值,請(qǐng)改用 DELETE。如果要?jiǎng)h除表定義及其數(shù)據(jù),請(qǐng)使用 DROP TABLE 語(yǔ)句。(12) 對(duì)于由 FOREIGN KEY 約束引用的表,不能使用 TRUNCATE TABLE,而應(yīng)使用不帶 WHERE 子句的 DELETE 語(yǔ)句。由于 TRUNCATE TABLE 不記錄在日志中,所以它不能激活觸發(fā)器。
10.什么是臨時(shí)表,臨時(shí)表什么時(shí)候刪除?
臨時(shí)表可以手動(dòng)刪除:DROP TEMPORARY TABLE IF EXISTS temp_tb;臨時(shí)表只在當(dāng)前連接可見(jiàn),當(dāng)關(guān)閉連接時(shí),MySQL會(huì)自動(dòng)刪除表并釋放所有空間。因此在不同的連接中可以創(chuàng)建同名的臨時(shí)表,并且操作屬于本連接的臨時(shí)表。創(chuàng)建臨時(shí)表的語(yǔ)法與創(chuàng)建表語(yǔ)法類似,不同之處是增加關(guān)鍵字TEMPORARY,如:
CREATE TEMPORARY TABLE tmp_table (
? ? ? ? NAME VARCHAR (10) NOT NULL,
? ? ? ? time date NOT NULL
);
select * from tmp_table;
11.說(shuō)說(shuō)非關(guān)系型數(shù)據(jù)庫(kù)和關(guān)系型數(shù)據(jù)庫(kù)區(qū)別,優(yōu)勢(shì)比較?
非關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)勢(shì):性能:NOSQL是基于鍵值對(duì)的,可以想象成表中的主鍵和值的對(duì)應(yīng)關(guān)系,而且不需要經(jīng)過(guò)SQL層的解析,所以性能非常高??蓴U(kuò)展性:同樣也是因?yàn)榛阪I值對(duì),數(shù)據(jù)之間沒(méi)有耦合性,所以非常容易水平擴(kuò)展。關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)勢(shì):復(fù)雜查詢:可以用SQL語(yǔ)句方便的在一個(gè)表以及多個(gè)表之間做非常復(fù)雜的數(shù)據(jù)查詢。事務(wù)支持:使得對(duì)于安全性能很高的數(shù)據(jù)訪問(wèn)要求得以實(shí)現(xiàn)。其他:1.對(duì)于這兩類數(shù)據(jù)庫(kù),對(duì)方的優(yōu)勢(shì)就是自己的弱勢(shì),反之亦然。2.NOSQL數(shù)據(jù)庫(kù)慢慢開(kāi)始具備SQL數(shù)據(jù)庫(kù)的一些復(fù)雜查詢功能,比如MongoDB。3.對(duì)于事務(wù)的支持也可以用一些系統(tǒng)級(jí)的原子操作來(lái)實(shí)現(xiàn)例如樂(lè)觀鎖之類的方法來(lái)曲線救國(guó),比如Redis set nx。
12.什么是數(shù)據(jù)庫(kù)范式,根據(jù)某個(gè)場(chǎng)景設(shè)計(jì)數(shù)據(jù)表?
第一范式:(確保每列保持原子性)所有字段值都是不可分解的原子值。第一范式是最基本的范式。如果數(shù)據(jù)庫(kù)表中的所有字段值都是不可分解的原子值,就說(shuō)明該數(shù)據(jù)庫(kù)表滿足了第一范式。第一范式的合理遵循需要根據(jù)系統(tǒng)的實(shí)際需求來(lái)定。比如某些數(shù)據(jù)庫(kù)系統(tǒng)中需要用到“地址”這個(gè)屬性,本來(lái)直接將“地址”屬性設(shè)計(jì)成一個(gè)數(shù)據(jù)庫(kù)表的字段就行。但是如果系統(tǒng)經(jīng)常會(huì)訪問(wèn)“地址”屬性中的“城市”部分,那么就非要將“地址”這個(gè)屬性重新拆分為省份、城市、詳細(xì)地址等多個(gè)部分進(jìn)行存儲(chǔ),這樣在對(duì)地址中某一部分操作的時(shí)候?qū)⒎浅7奖?。這樣設(shè)計(jì)才算滿足了數(shù)據(jù)庫(kù)的第一范式,如下表所示。上表所示的用戶信息遵循了第一范式的要求,這樣在對(duì)用戶使用城市進(jìn)行分類的時(shí)候就非常方便,也提高了數(shù)據(jù)庫(kù)的性能。第二范式:(確保表中的每列都和主鍵相關(guān))在一個(gè)數(shù)據(jù)庫(kù)表中,一個(gè)表中只能保存一種數(shù)據(jù),不可以把多種數(shù)據(jù)保存在同一張數(shù)據(jù)庫(kù)表中。第二范式在第一范式的基礎(chǔ)之上更進(jìn)一層。第二范式需要確保數(shù)據(jù)庫(kù)表中的每一列都和主鍵相關(guān),而不能只與主鍵的某一部分相關(guān)(主要針對(duì)聯(lián)合主鍵而言)。也就是說(shuō)在一個(gè)數(shù)據(jù)庫(kù)表中,一個(gè)表中只能保存一種數(shù)據(jù),不可以把多種數(shù)據(jù)保存在同一張數(shù)據(jù)庫(kù)表中。比如要設(shè)計(jì)一個(gè)訂單信息表,因?yàn)橛唵沃锌赡軙?huì)有多種商品,所以要將訂單編號(hào)和商品編號(hào)作為數(shù)據(jù)庫(kù)表的聯(lián)合主鍵。第三范式:(確保每列都和主鍵列直接相關(guān),而不是間接相關(guān)) 數(shù)據(jù)表中的每一列數(shù)據(jù)都和主鍵直接相關(guān),而不能間接相關(guān)。第三范式需要確保數(shù)據(jù)表中的每一列數(shù)據(jù)都和主鍵直接相關(guān),而不能間接相關(guān)。比如在設(shè)計(jì)一個(gè)訂單數(shù)據(jù)表的時(shí)候,可以將客戶編號(hào)作為一個(gè)外鍵和訂單表建立相應(yīng)的關(guān)系。而不可以在訂單表中添加關(guān)于客戶其它信息(比如姓名、所屬公司等)的字段。BCNF:符合3NF,并且,主屬性不依賴于主屬性。若關(guān)系模式屬于第二范式,且每個(gè)屬性都不傳遞依賴于鍵碼,則R屬于BC范式。通常BC范式的條件有多種等價(jià)的表述:每個(gè)非平凡依賴的左邊必須包含鍵碼;每個(gè)決定因素必須包含鍵碼。BC范式既檢查非主屬性,又檢查主屬性。當(dāng)只檢查非主屬性時(shí),就成了第三范式。滿足BC范式的關(guān)系都必然滿足第三范式。還可以這么說(shuō):若一個(gè)關(guān)系達(dá)到了第三范式,并且它只有一個(gè)候選碼,或者它的每個(gè)候選碼都是單屬性,則該關(guān)系自然達(dá)到BC范式。一般,一個(gè)數(shù)據(jù)庫(kù)設(shè)計(jì)符合3NF或BCNF就可以了。第四范式:要求把同一表內(nèi)的多對(duì)多關(guān)系刪除。第五范式:從最終結(jié)構(gòu)重新建立原始結(jié)構(gòu)。
13.什么是 內(nèi)連接、外連接、交叉連接、笛卡爾積等?
內(nèi)連接: 只連接匹配的行左外連接: 包含左邊表的全部行(不管右邊的表中是否存在與它們匹配的行),以及右邊表中全部匹配的行右外連接: 包含右邊表的全部行(不管左邊的表中是否存在與它們匹配的行),以及左邊表中全部匹配的行例如1:
SELECT a.,b. FROM luntan LEFT JOIN usertable as b ON a.username=b.username
例如2:
SELECT a.,b. FROM city as a FULL OUTER JOIN user as b ON a.username=b.username
全外連接: 包含左、右兩個(gè)表的全部行,不管另外一邊的表中是否存在與它們匹配的行。交叉連接: 生成笛卡爾積-它不使用任何匹配或者選取條件,而是直接將一個(gè)數(shù)據(jù)源中的每個(gè)行與另一個(gè)數(shù)據(jù)源的每個(gè)行都一一匹配例如:
SELECT type,pub_name FROM titles CROSS JOIN publishers ORDER BY type
14.varchar和char的使用場(chǎng)景?
1.char的長(zhǎng)度是不可變的,而varchar的長(zhǎng)度是可變的。定義一個(gè)char[10]和varchar[10]。如果存進(jìn)去的是‘csdn’,那么char所占的長(zhǎng)度依然為10,除了字符‘csdn’外,后面跟六個(gè)空格,varchar就立馬把長(zhǎng)度變?yōu)?了,取數(shù)據(jù)的時(shí)候,char類型的要用trim()去掉多余的空格,而varchar是不需要的。2.char的存取速度還是要比varchar要快得多,因?yàn)槠溟L(zhǎng)度固定,方便程序的存儲(chǔ)與查找。char也為此付出的是空間的代價(jià),因?yàn)槠溟L(zhǎng)度固定,所以難免會(huì)有多余的空格占位符占據(jù)空間,可謂是以空間換取時(shí)間效率。varchar是以空間效率為首位。3.char的存儲(chǔ)方式是:對(duì)英文字符(ASCII)占用1個(gè)字節(jié),對(duì)一個(gè)漢字占用兩個(gè)字節(jié)。varchar的存儲(chǔ)方式是:對(duì)每個(gè)英文字符占用2個(gè)字節(jié),漢字也占用2個(gè)字節(jié)。4.兩者的存儲(chǔ)數(shù)據(jù)都非unicode的字符數(shù)據(jù)。
15.SQL語(yǔ)言分類
SQL語(yǔ)言共分為四大類:一、數(shù)據(jù)查詢語(yǔ)言DQL二、數(shù)據(jù)操縱語(yǔ)言DML三、數(shù)據(jù)定義語(yǔ)言DDL四、數(shù)據(jù)控制語(yǔ)言DCL。
數(shù)據(jù)查詢語(yǔ)言DQL數(shù)據(jù)查詢語(yǔ)言DQL基本結(jié)構(gòu)是由SELECT子句,F(xiàn)ROM子句,WHERE子句組成的查詢塊:SELECTFROMWHERE
數(shù)據(jù)操縱語(yǔ)言DML數(shù)據(jù)操縱語(yǔ)言DML主要有三種形式:1) 插入:INSERT2) 更新:UPDATE3) 刪除:DELETE
數(shù)據(jù)定義語(yǔ)言DDL數(shù)據(jù)定義語(yǔ)言DDL用來(lái)創(chuàng)建數(shù)據(jù)庫(kù)中的各種對(duì)象-----表、視圖、索引、同義詞、聚簇等如:CREATE TABLE/VIEW/INDEX/SYN/CLUSTER表 視圖 索引 同義詞 簇DDL操作是隱性提交的!不能rollback
數(shù)據(jù)控制語(yǔ)言DCL數(shù)據(jù)控制語(yǔ)言DCL用來(lái)授予或回收訪問(wèn)數(shù)據(jù)庫(kù)的某種特權(quán),并控制數(shù)據(jù)庫(kù)操縱事務(wù)發(fā)生的時(shí)間及效果,對(duì)數(shù)據(jù)庫(kù)實(shí)行監(jiān)視等。如:1) GRANT:授權(quán)。2) ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一點(diǎn)?;貪L---ROLLBACK;回滾命令使數(shù)據(jù)庫(kù)狀態(tài)回到上次最后提交的狀態(tài)。其格式為:SQL>ROLLBACK;3) COMMIT [WORK]:提交。在數(shù)據(jù)庫(kù)的插入、刪除和修改操作時(shí),只有當(dāng)事務(wù)在提交到數(shù)據(jù)庫(kù)時(shí)才算完成。在事務(wù)提交前,只有操作數(shù)據(jù)庫(kù)的這個(gè)人才能有權(quán)看到所做的事情,別人只有在最后提交完成后才可以看到。提交數(shù)據(jù)有三種類型:顯式提交、隱式提交及自動(dòng)提交。下面分別說(shuō)明這三種類型。(1) 顯式提交用COMMIT命令直接完成的提交為顯式提交。其格式為:SQL>COMMIT;(2) 隱式提交用SQL命令間接完成的提交為隱式提交。這些命令是:ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。(3) 自動(dòng)提交若把AUTOCOMMIT設(shè)置為ON,則在插入、修改、刪除語(yǔ)句執(zhí)行后,系統(tǒng)將自動(dòng)進(jìn)行提交,這就是自動(dòng)提交。其格式為:SQL>SET AUTOCOMMIT ON;
16.說(shuō)說(shuō)like %和-的區(qū)別
通配符的分類%百分號(hào)通配符:表示任何字符出現(xiàn)任意次數(shù)(可以是0次).下劃線通配符:表示只能匹配單個(gè)字符,不能多也不能少,就是一個(gè)字符.like操作符: LIKE作用是指示mysql后面的搜索模式是利用通配符而不是直接相等匹配進(jìn)行比較.注意: 如果在使用like操作符時(shí),后面的沒(méi)有使用通用匹配符效果是和=一致的,SELECT * FROM products WHERE products.prod_name like '1000';只能匹配的結(jié)果為1000,而不能匹配像JetPack 1000這樣的結(jié)果.%通配符使用: 匹配以"yves"開(kāi)頭的記錄:(包括記錄"yves") SELECT FROM products WHERE products.prod_name like 'yves%';匹配包含"yves"的記錄(包括記錄"yves") SELECT FROM products WHERE products.prod_name like '%yves%';匹配以"yves"結(jié)尾的記錄(包括記錄"yves",不包括記錄"yves ",也就是yves后面有空格的記錄,這里需要注意) SELECT * FROM products WHERE products.prod_name like '%yves';通配符使用: SELECT FROM products WHERE products.prod_name like 'yves'; 匹配結(jié)果為: 像"yyves"這樣記錄. SELECT FROM products WHERE products.prodname like 'yves'; 匹配結(jié)果為: 像"yvesHe"這樣的記錄.(一個(gè)下劃線只能匹配一個(gè)字符,不能多也不能少)注意事項(xiàng):注意大小寫(xiě),在使用模糊匹配時(shí),也就是匹配文本時(shí),mysql是可能區(qū)分大小的,也可能是不區(qū)分大小寫(xiě)的,這個(gè)結(jié)果是取決于用戶對(duì)MySQL的配置方式.如果是區(qū)分大小寫(xiě),那么像YvesHe這樣記錄是不能被"yves__"這樣的匹配條件匹配的.注意尾部空格,"%yves"是不能匹配"heyves "這樣的記錄的.注意NULL,%通配符可以匹配任意字符,但是不能匹配NULL,也就是說(shuō)SELECT * FROM products WHERE products.prod_name like '%;是匹配不到products.prod_name為NULL的的記錄.技巧與建議:正如所見(jiàn), MySQL的通配符很有用。但這種功能是有代價(jià)的:通配符搜索的處理一般要比前面討論的其他搜索所花時(shí)間更長(zhǎng)。這里給出一些使用通配符要記住的技巧。不要過(guò)度使用通配符。如果其他操作符能達(dá)到相同的目的,應(yīng)該 使用其他操作符。在確實(shí)需要使用通配符時(shí),除非絕對(duì)有必要,否則不要把它們用 在搜索模式的開(kāi)始處。把通配符置于搜索模式的開(kāi)始處,搜索起 來(lái)是最慢的。仔細(xì)注意通配符的位置。如果放錯(cuò)地方,可能不會(huì)返回想要的數(shù).
17.說(shuō)說(shuō)count(*)、count(1)、count(column)的區(qū)別
count()對(duì)行的數(shù)目進(jìn)行計(jì)算,包含NULLcount(column)對(duì)特定的列的值具有的行數(shù)進(jìn)行計(jì)算,不包含NULL值。count()還有一種使用方式,count(1)這個(gè)用法和count()的結(jié)果是一樣的。性能問(wèn)題:1.任何情況下SELECT COUNT() FROM tablename是最優(yōu)選擇;2.盡量減少SELECT COUNT() FROM tablename WHERE COL = ‘value’ 這種查詢;3.杜絕SELECT COUNT(COL) FROM tablename WHERE COL2 = ‘value’ 的出現(xiàn)。如果表沒(méi)有主鍵,那么count(1)比count()快。如果有主鍵,那么count(主鍵,聯(lián)合主鍵)比count()快。如果表只有一個(gè)字段,count()最快。count(1)跟count(主鍵)一樣,只掃描主鍵。count()跟count(非主鍵)一樣,掃描整個(gè)表。明顯前者更快一些。
18.什么是最左前綴原則?
多列索引:
ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);
為了提高搜索效率,我們需要考慮運(yùn)用多列索引,由于索引文件以B-Tree格式保存,所以我們不用掃描任何記錄,即可得到最終結(jié)果。注:在mysql中執(zhí)行查詢時(shí),只能使用一個(gè)索引,如果我們?cè)趌name,fname,age上分別建索引,執(zhí)行查詢時(shí),只能使用一個(gè)索引,mysql會(huì)選擇一個(gè)最嚴(yán)格(獲得結(jié)果集記錄數(shù)最少)的索引。最左前綴原則:顧名思義,就是最左優(yōu)先,上例中我們創(chuàng)建了lname_fname_age多列索引,相當(dāng)于創(chuàng)建了(lname)單列索引,(lname,fname)組合索引以及(lname,fname,age)組合索引。
19.什么是索引?
何為索引:數(shù)據(jù)庫(kù)索引,是數(shù)據(jù)庫(kù)管理系統(tǒng)中一個(gè)排序的數(shù)據(jù)結(jié)構(gòu),索引的實(shí)現(xiàn)通常使用B樹(shù)及其變種B+樹(shù)。在數(shù)據(jù)之外,數(shù)據(jù)庫(kù)系統(tǒng)還維護(hù)著滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),這些數(shù)據(jù)結(jié)構(gòu)以某種方式引用(指向)數(shù)據(jù),這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)上實(shí)現(xiàn)高級(jí)查找算法。這種數(shù)據(jù)結(jié)構(gòu),就是索引。
20.索引的作用?它的優(yōu)點(diǎn)缺點(diǎn)是什么?
索引作用:協(xié)助快速查詢、更新數(shù)據(jù)庫(kù)表中數(shù)據(jù)。為表設(shè)置索引要付出代價(jià)的:一是增加了數(shù)據(jù)庫(kù)的存儲(chǔ)空間二是在插入和修改數(shù)據(jù)時(shí)要花費(fèi)較多的時(shí)間(因?yàn)樗饕惨S之變動(dòng))。
21.索引的優(yōu)缺點(diǎn)有哪些?
創(chuàng)建索引可以大大提高系統(tǒng)的性能(優(yōu)點(diǎn)):(1)通過(guò)創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性。(2)可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因。(3)可以加速表和表之間的連接,特別是在實(shí)現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。(4)在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢中分組和排序的時(shí)間。(5)通過(guò)使用索引,可以在查詢的過(guò)程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能。增加索引也有許多不利的方面(缺點(diǎn)):(1).創(chuàng)建索引和維護(hù)索引要耗費(fèi)時(shí)間,這種時(shí)間隨著數(shù)據(jù)量的增加而增加。(2).索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個(gè)索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會(huì)更大。(3).當(dāng)對(duì)表中的數(shù)據(jù)進(jìn)行增加、刪除和修改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù),這樣就降低了數(shù)據(jù)的維護(hù)速度。(4).哪些列適合建立索引、哪些不適合建索引?索引是建立在數(shù)據(jù)庫(kù)表中的某些列的上面。在創(chuàng)建索引的時(shí)候,應(yīng)該考慮在哪些列上可以創(chuàng)建索引,在哪些列上不能創(chuàng)建索引。一般來(lái)說(shuō),應(yīng)該在這些列上創(chuàng)建索引:(1)在經(jīng)常需要搜索的列上,可以加快搜索的速度;(2)在作為主鍵的列上,強(qiáng)制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu);(3)在經(jīng)常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;(4)在經(jīng)常需要根據(jù)范圍進(jìn)行搜索的列上創(chuàng)建索引,因?yàn)樗饕呀?jīng)排序,其指定的范圍是連續(xù)的;(5)在經(jīng)常需要排序的列上創(chuàng)建索引,因?yàn)樗饕呀?jīng)排序,這樣查詢可以利用索引的排序,加快排序查詢時(shí)間;(6)在經(jīng)常使用在WHERE子句中的列上面創(chuàng)建索引,加快條件的判斷速度。
對(duì)于有些列不應(yīng)該創(chuàng)建索引:(1)對(duì)于那些在查詢中很少使用或者參考的列不應(yīng)該創(chuàng)建索引。這是因?yàn)?,既然這些列很少使用到,因此有索引或者無(wú)索引,并不能提高查詢速度。相反,由于增加了索引,反而降低了系統(tǒng)的維護(hù)速度和增大了空間需求。(2)對(duì)于那些只有很少數(shù)據(jù)值的列也不應(yīng)該增加索引。這是因?yàn)?,由于這些列的取值很少,例如人事表的性別列,在查詢的結(jié)果中,結(jié)果集的數(shù)據(jù)行占了表中數(shù)據(jù)行的很大比例,即需要在表中搜索的數(shù)據(jù)行的比例很大。增加索引,并不能明顯加快檢索速度。(3)對(duì)于那些定義為text, image和bit數(shù)據(jù)類型的列不應(yīng)該增加索引。這是因?yàn)椋@些列的數(shù)據(jù)量要么相當(dāng)大,要么取值很少。(4)當(dāng)修改性能遠(yuǎn)遠(yuǎn)大于檢索性能時(shí),不應(yīng)該創(chuàng)建索引。這是因?yàn)?,修改性能和檢索性能是互相矛盾的。當(dāng)增加索引時(shí),會(huì)提高檢索性能,但是會(huì)降低修改性能。當(dāng)減少索引時(shí),會(huì)提高修改性能,降低檢索性能。因此,當(dāng)修改性能遠(yuǎn)遠(yuǎn)大于檢索性能時(shí),不應(yīng)該創(chuàng)建索引。索引詳解:帶你從頭到尾捋一遍MySQL索引結(jié)構(gòu)!
22.什么樣的字段適合建索引?
唯一、不為空、經(jīng)常被查詢的字段
23.說(shuō)說(shuō)MySQL B+Tree索引和Hash索引的區(qū)別?
Hash索引和B+樹(shù)索引的特點(diǎn):Hash索引結(jié)構(gòu)的特殊性,其檢索效率非常高,索引的檢索可以一次定位;B+樹(shù)索引需要從根節(jié)點(diǎn)到枝節(jié)點(diǎn),最后才能訪問(wèn)到頁(yè)節(jié)點(diǎn)這樣多次的IO訪問(wèn);為什么不都用Hash索引而使用B+樹(shù)索引?Hash索引僅僅能滿足"=","IN"和""查詢,不能使用范圍查詢,因?yàn)榻?jīng)過(guò)相應(yīng)的Hash算法處理之后的Hash值的大小關(guān)系,并不能保證和Hash運(yùn)算前完全一樣;Hash索引無(wú)法被用來(lái)避免數(shù)據(jù)的排序操作,因?yàn)镠ash值的大小關(guān)系并不一定和Hash運(yùn)算前的鍵值完全一樣;Hash索引不能利用部分索引鍵查詢,對(duì)于組合索引,Hash索引在計(jì)算Hash值的時(shí)候是組合索引鍵合并后再一起計(jì)算Hash值,而不是單獨(dú)計(jì)算Hash值,所以通過(guò)組合索引的前面一個(gè)或幾個(gè)索引鍵進(jìn)行查詢的時(shí)候,Hash索引也無(wú)法被利用;Hash索引在任何時(shí)候都不能避免表掃描,由于不同索引鍵存在相同Hash值,所以即使取滿足某個(gè)Hash鍵值的數(shù)據(jù)的記錄條數(shù),也無(wú)法從Hash索引中直接完成查詢,還是要回表查詢數(shù)據(jù);Hash索引遇到大量Hash值相等的情況后性能并不一定就會(huì)比B+樹(shù)索引高。補(bǔ)充:(1).MySQL中,只有HEAP/MEMORY引擎才顯示支持Hash索引。(2).常用的InnoDB引擎中默認(rèn)使用的是B+樹(shù)索引,它會(huì)實(shí)時(shí)監(jiān)控表上索引的使用情況,如果認(rèn)為建立哈希索引可以提高查詢效率,則自動(dòng)在內(nèi)存中的“自適應(yīng)哈希索引緩沖區(qū)”建立哈希索引(在InnoDB中默認(rèn)開(kāi)啟自適應(yīng)哈希索引),通過(guò)觀察搜索模式,MySQL會(huì)利用index key的前綴建立哈希索引,如果一個(gè)表幾乎大部分都在緩沖池中,那么建立一個(gè)哈希索引能夠加快等值查詢。B+樹(shù)索引和哈希索引的明顯區(qū)別是:(3).如果是等值查詢,那么哈希索引明顯有絕對(duì)優(yōu)勢(shì),因?yàn)橹恍枰?jīng)過(guò)一次算法即可找到相應(yīng)的鍵值;當(dāng)然了,這個(gè)前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然后再根據(jù)鏈表往后掃描,直到找到相應(yīng)的數(shù)據(jù);(4).如果是范圍查詢檢索,這時(shí)候哈希索引就毫無(wú)用武之地了,因?yàn)樵仁怯行虻逆I值,經(jīng)過(guò)哈希算法后,有可能變成不連續(xù)的了,就沒(méi)辦法再利用索引完成范圍查詢檢索;同理,哈希索引沒(méi)辦法利用索引完成排序,以及l(fā)ike ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實(shí)本質(zhì)上也是范圍查詢);(5).哈希索引也不支持多列聯(lián)合索引的最左匹配規(guī)則;(6).B+樹(shù)索引的關(guān)鍵字檢索效率比較平均,不像B樹(shù)那樣波動(dòng)幅度大,在有大量重復(fù)鍵值情況下,哈希索引的效率也是極低的,因?yàn)榇嬖谒^的哈希碰撞問(wèn)題。(7)在大多數(shù)場(chǎng)景下,都會(huì)有范圍查詢、排序、分組等查詢特征,用B+樹(shù)索引就可以了。
24.說(shuō)說(shuō)B樹(shù)和B+樹(shù)的區(qū)別
B樹(shù),每個(gè)節(jié)點(diǎn)都存儲(chǔ)key和data,所有節(jié)點(diǎn)組成這棵樹(shù),并且葉子節(jié)點(diǎn)指針為nul,葉子結(jié)點(diǎn)不包含任何關(guān)鍵字信息。B+樹(shù),所有的葉子結(jié)點(diǎn)中包含了全部關(guān)鍵字的信息,及指向含有這些關(guān)鍵字記錄的指針,且葉子結(jié)點(diǎn)本身依關(guān)鍵字的大小自小而大的順序鏈接,所有的非終端結(jié)點(diǎn)可以看成是索引部分,結(jié)點(diǎn)中僅含有其子樹(shù)根結(jié)點(diǎn)中最大(或最?。╆P(guān)鍵字。(而B(niǎo) 樹(shù)的非終節(jié)點(diǎn)也包含需要查找的有效信息)
25.為什么說(shuō)B+比B樹(shù)更適合實(shí)際應(yīng)用中操作系統(tǒng)的文件索引和數(shù)據(jù)庫(kù)索引?
1.B+的磁盤(pán)讀寫(xiě)代價(jià)更低B+的內(nèi)部結(jié)點(diǎn)并沒(méi)有指向關(guān)鍵字具體信息的指針。因此其內(nèi)部結(jié)點(diǎn)相對(duì)B樹(shù)更小。如果把所有同一內(nèi)部結(jié)點(diǎn)的關(guān)鍵字存放在同一盤(pán)塊中,那么盤(pán)塊所能容納的關(guān)鍵字?jǐn)?shù)量也越多。一次性讀入內(nèi)存中的需要查找的關(guān)鍵字也就越多。相對(duì)來(lái)說(shuō)IO讀寫(xiě)次數(shù)也就降低了。2.B+tree的查詢效率更加穩(wěn)定由于非終結(jié)點(diǎn)并不是最終指向文件內(nèi)容的結(jié)點(diǎn),而只是葉子結(jié)點(diǎn)中關(guān)鍵字的索引。所以任何關(guān)鍵字的查找必須走一條從根結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路。所有關(guān)鍵字查詢的路徑長(zhǎng)度相同,導(dǎo)致每一個(gè)數(shù)據(jù)的查詢效率相當(dāng)。
26.說(shuō)說(shuō)聚集索引和非聚集索引區(qū)別?
聚合索引(clustered index):聚集索引表記錄的排列順序和索引的排列順序一致,所以查詢效率快,只要找到第一個(gè)索引值記錄,其余就連續(xù)性的記錄在物理也一樣連續(xù)存放。聚集索引對(duì)應(yīng)的缺點(diǎn)就是修改慢,因?yàn)闉榱吮WC表中記錄的物理和索引順序一致,在記錄插入的時(shí)候,會(huì)對(duì)數(shù)據(jù)頁(yè)重新排序。聚集索引類似于新華字典中用拼音去查找漢字,拼音檢索表于書(shū)記順序都是按照a~z排列的,就像相同的邏輯順序于物理順序一樣,當(dāng)你需要查找a,ai兩個(gè)讀音的字,或是想一次尋找多個(gè)傻(sha)的同音字時(shí),也許向后翻幾頁(yè),或緊接著下一行就得到結(jié)果了。非聚合索引(nonclustered index):非聚集索引指定了表中記錄的邏輯順序,但是記錄的物理和索引不一定一致,兩種索引都采用B+樹(shù)結(jié)構(gòu),非聚集索引的葉子層并不和實(shí)際數(shù)據(jù)頁(yè)相重疊,而采用葉子層包含一個(gè)指向表中的記錄在數(shù)據(jù)頁(yè)中的指針?lè)绞?。非聚集索引層次多,不?huì)造成數(shù)據(jù)重排。非聚集索引類似在新華字典上通過(guò)偏旁部首來(lái)查詢漢字,檢索表也許是按照橫、豎、撇來(lái)排列的,但是由于正文中是a~z的拼音順序,所以就類似于邏輯地址于物理地址的不對(duì)應(yīng)。同時(shí)適用的情況就在于分組,大數(shù)目的不同值,頻繁更新的列中,這些情況即不適合聚集索引。根本區(qū)別:聚集索引和非聚集索引的根本區(qū)別是表記錄的排列順序和與索引的排列順序是否一致。
二、數(shù)據(jù)庫(kù)MySql基礎(chǔ)篇
1.函數(shù)的分類?經(jīng)常使用的函數(shù)有哪些?
loweruppersubstrlengthtrim(去首尾空格,不會(huì)去除中間的空格)str_to_date(%Y-%m-%d)date_formatformat(保留小數(shù))roundrand()隨機(jī)數(shù)ifnull(如果為空,則替換為0)聚合函數(shù)/分組函數(shù)分組函數(shù)自動(dòng)忽略空值countsumavgminmax
2.分組查詢需要注意條件?
如果使用了order by,order by 必須放到group by后面。在sql語(yǔ)句中,select語(yǔ)句后面只能跟分組函數(shù)+參與分組的字段。如果想要對(duì)分組數(shù)據(jù)再進(jìn)行過(guò)濾需要使用having子句。
3.limit使用方法?
select * from emp limit m,n;
4.mysql常見(jiàn)數(shù)據(jù)類型?
char:定長(zhǎng)字符串,適合做主鍵或者外鍵varchar:可變長(zhǎng)字符串double/floatint/bigintdate
5.如何增加刪除修改表結(jié)構(gòu)
alter table 表名 add 字段名 數(shù)據(jù)類型(長(zhǎng)度) --添加字段
alter table 表名 modify 字段名 數(shù)據(jù)類型(長(zhǎng)度) --修改字段長(zhǎng)度
alter table 表名 change 原字段名 現(xiàn)在字段名 數(shù)據(jù)類型(長(zhǎng)度) --修改字段名稱
alter table 表名 drop 字段名 --刪除字段
6.如何開(kāi)啟MySQL服務(wù),關(guān)閉My服務(wù)
開(kāi)啟服務(wù):
service mysqld start
/init.d/mysqld start
safe_mysql &
關(guān)閉服務(wù):
service mysqld stop
/etc/init.d/mysqld stop
mysqladmin -uroot -p123456 shutdown
7.檢測(cè)端口是否運(yùn)行
lsof -i:3306
netstat -tunlp|grep 3306
ss -tulnp|grep 3306
8.如何為MySQL設(shè)置密碼或者修改密碼。
方法一
mysqladmin -u root -p123456 password 'abc123' ?? #比較常用
方法二(sql語(yǔ)句修改)
update mysql.user set password=password(123456) where user='root' and host='localhost';
flush privileges;
方法三(sql語(yǔ)句修改)
set password=password('abc123');
9.如何登陸MySQL數(shù)據(jù)庫(kù)。
單實(shí)例登陸
mysql -uroot -p123456
多實(shí)例登陸
mysql -uroot -p123456 -S /data/3306/mysql.sock
10.查看當(dāng)前數(shù)據(jù)庫(kù)的字符集
mysql> show variables like "%charac%";
11.如何查看當(dāng)前數(shù)據(jù)庫(kù)版本
# mysql -V
mysql> select version();
12.如何 查看當(dāng)前登錄的用戶。
mysql> select user();
13.查看T1數(shù)據(jù)庫(kù)中有哪兒些表
mysql> use T1;
mysql> show tables;
14.創(chuàng)建GBK字符集的數(shù)據(jù)庫(kù)oldboy,并查看已建庫(kù)完整語(yǔ)句
mysql> create database oldboy default character set gbk;
mysql> show create database oldboy;
15.創(chuàng)建用戶oldboy,使之可以管理數(shù)據(jù)庫(kù)oldboy
mysql> grant select,update,insert,delete,alter on oldboy.* to oldboy@'localhost' identified by '123456';
16.查看創(chuàng)建的用戶oldboy擁有哪些權(quán)限
mysql> show grants for oldboy@'localhost';
17.查看當(dāng)前數(shù)據(jù)庫(kù)里有哪些用戶
mysql> select user,host from mysql.user;
18.如何進(jìn)入oldboy數(shù)據(jù)庫(kù)
mysql> use oldboy();
19.請(qǐng)寫(xiě)一個(gè)腳本:? 創(chuàng)建一個(gè)innodb GBK表test,字段id int(4)和name varchar(16)
mysql> create table test (id int(4),name varchar(16)) engine=InnoDB default charset=gbk;
20.查看建表結(jié)構(gòu)及表結(jié)構(gòu)的SQL語(yǔ)句
mysql> desc test;
mysql> show create table test\G
21.請(qǐng)使用腳本查詢一條數(shù)據(jù):插入一條數(shù)據(jù)“1,oldboy”
mysql> insert into test (id,name) values (1,'oldboy');
22.再批量插入2行數(shù)據(jù) “2,老男孩”,“3,oldboyedu”
mysql> insert into test (id,name) values (2,'老男孩'),(3,'oldboyedu');
23.查詢名字為oldboy的記錄
mysql> select * from test where name='oldboy';
24.把數(shù)據(jù)id等于1的名字oldboy更改為oldgirl
mysql> update test set name='oldgirl' where id=1;
25.在字段name前插入age字段,類型tinyint(2)
mysql> alter table test add age tinyint(2) after id;
26.不退出數(shù)據(jù)庫(kù),完成備份oldboy數(shù)據(jù)庫(kù)
mysql> system mysqldump -uroot -p123456 -B -x -F --events oldboy >/opt/bak.sql
27.刪除test表中的所有數(shù)據(jù),并查看
mysql> delete from test;
三、數(shù)據(jù)庫(kù)MySql篇
1.說(shuō)一下 MySQL 的行鎖和表鎖?
MyISAM 只支持表鎖,InnoDB 支持表鎖和行鎖,默認(rèn)為行鎖。 表級(jí)鎖:開(kāi)銷小,加鎖快,不會(huì)出現(xiàn)死鎖。鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)量最低。 行級(jí)鎖:開(kāi)銷大,加鎖慢,會(huì)出現(xiàn)死鎖。鎖力度小,發(fā)生鎖沖突的概率小,并發(fā)度最高。
2.MySQL的默認(rèn)事務(wù)隔離級(jí)別是?
讀未提交(RU): 一個(gè)事務(wù)還沒(méi)提交時(shí), 它做的變更就能被別的事務(wù)看到.讀提交(RC): 一個(gè)事務(wù)提交之后, 它做的變更才會(huì)被其他事務(wù)看到.可重復(fù)讀(RR): 一個(gè)事務(wù)執(zhí)行過(guò)程中看到的數(shù)據(jù), 總是跟這個(gè)事務(wù)在啟動(dòng)時(shí)看到的數(shù)據(jù)是一致的. 當(dāng)然在可重復(fù)讀隔離級(jí)別下, 未提交變更對(duì)其他事務(wù)也是不可見(jiàn)的.串行化(S): 對(duì)于同一行記錄, 讀寫(xiě)都會(huì)加鎖. 當(dāng)出現(xiàn)讀寫(xiě)鎖沖突的時(shí)候, 后訪問(wèn)的事務(wù)必須等前一個(gè)事務(wù)執(zhí)行完成才能繼續(xù)執(zhí)行.
3.Mysql數(shù)據(jù)庫(kù)表類型有哪些?
MyISAM、InnoDB、HEAP、BOB,ARCHIVE,CSV等。MyISAM:成熟、穩(wěn)定、易于管理,快速讀取。一些功能不支持(事務(wù)等),表級(jí)鎖。InnoDB:支持事務(wù)、外鍵等特性、數(shù)據(jù)行鎖定。空間占用大,不支持全文索引等。
4.MySQL怎么恢復(fù)半個(gè)月前的數(shù)據(jù)?
通過(guò)整庫(kù)備份+binlog進(jìn)行恢復(fù). 前提是要有定期整庫(kù)備份且保存了binlog日志.
5.一張自增表里面總共有 7 條數(shù)據(jù),刪除了最后 2 條數(shù)據(jù),重啟 MySQL 數(shù)據(jù)庫(kù),又插入了一條數(shù)據(jù),此時(shí) id 是幾?
表類型如果是 MyISAM ,那 id 就是 8。表類型如果是 InnoDB,那 id 就是 6。InnoDB 表只會(huì)把自增主鍵的最大 id 記錄在內(nèi)存中,所以重啟之后會(huì)導(dǎo)致最大 id 丟失。
6.MySQL 的內(nèi)連接、左連接、右連接有什么區(qū)別?
內(nèi)連接關(guān)鍵字:inner join;左連接:left join;右連接:right join。 內(nèi)連接是把匹配的關(guān)聯(lián)數(shù)據(jù)顯示出來(lái);左連接是左邊的表全部顯示出來(lái),右邊的表顯示出符合條件的數(shù)據(jù);右連接正好相反。
7.MySQL 問(wèn)題排查都有哪些手段?
使用 show processlist 命令查看當(dāng)前所有連接信息。 使用 explain 命令查詢 SQL 語(yǔ)句執(zhí)行計(jì)劃。 開(kāi)啟慢查詢?nèi)罩荆榭绰樵兊?SQL。
8.如何做 MySQL 的性能優(yōu)化?
為搜索字段創(chuàng)建索引。避免使用 select *,列出需要查詢的字段。垂直分割分表。選擇正確的存儲(chǔ)引擎。
讀寫(xiě)分離
9.MySQL數(shù)據(jù)庫(kù)作發(fā)布系統(tǒng)的存儲(chǔ),一天五萬(wàn)條以上的增量,預(yù)計(jì)運(yùn)維三年,怎么優(yōu)化?
(1)設(shè)計(jì)良好的數(shù)據(jù)庫(kù)結(jié)構(gòu),允許部分?jǐn)?shù)據(jù)冗余,盡量避免join查詢,提高效率。(2) 選擇合適的表字段數(shù)據(jù)類型和存儲(chǔ)引擎,適當(dāng)?shù)奶砑铀饕?。?) 做mysql主從復(fù)制讀寫(xiě)分離。(4)對(duì)數(shù)據(jù)表進(jìn)行分表,減少單表中的數(shù)據(jù)量提高查詢速度。(5)添加緩存機(jī)制,比如redis,memcached等。(6)對(duì)不經(jīng)常改動(dòng)的頁(yè)面,生成靜態(tài)頁(yè)面(比如做ob緩存)。(7)書(shū)寫(xiě)高效率的SQL。比如 SELECT * FROM TABEL 改為 SELECT field_1, field_2, field_3 FROM TABLE.
10.MySQL由哪些部分組成, 分別用來(lái)做什么?
(1)Server(2)連接器: 管理連接, 權(quán)限驗(yàn)證.(3)分析器: 詞法分析, 語(yǔ)法分析.(4)優(yōu)化器: 執(zhí)行計(jì)劃生成, 索引的選擇.(5)執(zhí)行器: 操作存儲(chǔ)引擎, 返回執(zhí)行結(jié)果.(6)存儲(chǔ)引擎: 存儲(chǔ)數(shù)據(jù), 提供讀寫(xiě)接口.
11.怎么驗(yàn)證 MySQL 的索引是否滿足需求?
使用 explain 查看 SQL 是如何執(zhí)行查詢語(yǔ)句的,從而分析你的索引是否滿足需求。 explain 語(yǔ)法:explain select * from table where type=1。
12.請(qǐng)你介紹一下 mysql的主從復(fù)制?
考察點(diǎn):數(shù)據(jù)庫(kù)
MySQL主從復(fù)制是其最重要的功能之一。主從復(fù)制是指一臺(tái)服務(wù)器充當(dāng)主數(shù)據(jù)庫(kù)服務(wù)器,另一臺(tái)或多臺(tái)服務(wù)器充當(dāng)從數(shù)據(jù)庫(kù)服務(wù)器,主服務(wù)器中的數(shù)據(jù)自動(dòng)復(fù)制到從服務(wù)器之中。對(duì)于多級(jí)復(fù)制,數(shù)據(jù)庫(kù)服務(wù)器即可充當(dāng)主機(jī),也可充當(dāng)從機(jī)。MySQL主從復(fù)制的基礎(chǔ)是主服務(wù)器對(duì)數(shù)據(jù)庫(kù)修改記錄二進(jìn)制日志,從服務(wù)器通過(guò)主服務(wù)器的二進(jìn)制日志自動(dòng)執(zhí)行更新。
MySQL主從復(fù)制的兩種情況:同步復(fù)制和異步復(fù)制,實(shí)際復(fù)制架構(gòu)中大部分為異步復(fù)制。
復(fù)制的基本過(guò)程如下:
Slave上面的IO進(jìn)程連接上Master,并請(qǐng)求從指定日志文件的指定位置(或者從最開(kāi)始的日志)之后的日志內(nèi)容。
Master接收到來(lái)自Slave的IO進(jìn)程的請(qǐng)求后,負(fù)責(zé)復(fù)制的IO進(jìn)程會(huì)根據(jù)請(qǐng)求信息讀取日志指定位置之后的日志信息,返回給Slave的IO進(jìn)程。返回信息中除了日志所包含的信息之外,還包括本次返回的信息已經(jīng)到Master端的bin-log文件的名稱以及bin-log的位置。
Slave的IO進(jìn)程接收到信息后,將接收到的日志內(nèi)容依次添加到Slave端的relay-log文件的最末端,并將讀取到的Master端的bin-log的文件名和位置記錄到master-info文件中,以便在下一次讀取的時(shí)候能夠清楚的告訴Master“我需要從某個(gè)bin-log的哪個(gè)位置開(kāi)始往后的日志內(nèi)容,請(qǐng)發(fā)給我”。
Slave的Sql進(jìn)程檢測(cè)到relay-log中新增加了內(nèi)容后,會(huì)馬上解析relay-log的內(nèi)容成為在Master端真實(shí)執(zhí)行時(shí)候的那些可執(zhí)行的內(nèi)容,并在自身執(zhí)行。
13.請(qǐng)你介紹一下mysql的MVCC機(jī)制
MVCC是一種多版本并發(fā)控制機(jī)制,是MySQL的InnoDB存儲(chǔ)引擎實(shí)現(xiàn)隔離級(jí)別的一種具體方式,用于實(shí)現(xiàn)提交讀和可重復(fù)讀這兩種隔離級(jí)別。MVCC是通過(guò)保存數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)的快照來(lái)實(shí)現(xiàn)該機(jī)制,其在每行記錄后面保存兩個(gè)隱藏的列,分別保存這個(gè)行的創(chuàng)建版本號(hào)和刪除版本號(hào),然后Innodb的MVCC使用到的快照存儲(chǔ)在Undo日志中,該日志通過(guò)回滾指針把一個(gè)數(shù)據(jù)行所有快照連接起來(lái)。
14.常用的Mysql復(fù)制架構(gòu)有哪些?
(1)一主多從 在主庫(kù)讀取請(qǐng)求壓力非常大的場(chǎng)景下, 可以通過(guò)配置一主多從復(fù)制架構(gòu)實(shí)現(xiàn)讀寫(xiě)分離, 把大量對(duì)實(shí)時(shí)性要求不是特別高的讀請(qǐng)求通過(guò)負(fù)載均衡分布到多個(gè)從庫(kù)上, 降低主庫(kù)的讀取壓力,在主庫(kù)出現(xiàn)異常宕機(jī)的情況下, 可以把一個(gè)從庫(kù)切換為主庫(kù)繼續(xù)提供服務(wù) 。
(2)多級(jí)復(fù)制 一主多從的架構(gòu)能夠解決大部分讀請(qǐng)求壓力特別大的場(chǎng)景的需求, 考慮到 MysQL的復(fù)制是主庫(kù)“推送” Binlog日志到從庫(kù),主庫(kù)的 I/0壓力和網(wǎng)絡(luò)壓力會(huì)隨著從庫(kù)的增加而增長(zhǎng)(每個(gè)從庫(kù)都會(huì)在主庫(kù)上有一個(gè)獨(dú)立的 Binlog Dump線程來(lái)發(fā)送事件), 而多級(jí)復(fù)制架構(gòu)解決了一主多從場(chǎng)景下,主庫(kù)額外的 I/0和網(wǎng)絡(luò)壓力。
(3)雙主復(fù)制/Dual Master 其實(shí)就是主庫(kù) Master和 Master2互為主從, client客戶端的寫(xiě)請(qǐng)求都訪問(wèn)主庫(kù) Master,而讀請(qǐng)求可以選擇訪問(wèn)主庫(kù) Master或 Master2。
15.Mysql 的存儲(chǔ)引擎,myisam和innodb的區(qū)別?
(1)InnoDB支持事務(wù), MyISAM不支持.
(2)InnoDB支持行級(jí)鎖, MyISAM支持表級(jí)鎖.
(3)InnoDB支持多版本并發(fā)控制(MVVC), MyISAM不支持.
(4)InnoDB支持外鍵, MyISAM不支持.
(5)MyISAM支持全文索引, InnoDB不支持(但可以使用Sphinx插件)
16.請(qǐng)問(wèn)MySQL的端口號(hào)是多少,如何修改這個(gè)端口號(hào)
查看端口號(hào):
使用命令show global variables like 'port';查看端口號(hào) ,mysql的默認(rèn)端口是3306。(補(bǔ)充:sqlserver默認(rèn)端口號(hào)為:1433;oracle默認(rèn)端口號(hào)為:1521;DB2默認(rèn)端口號(hào)為:5000;PostgreSQL默認(rèn)端口號(hào)為:5432)
修改端口號(hào):
修改端口號(hào):編輯/etc/my.cnf文件,早期版本有可能是my.conf文件名,增加端口參數(shù),并且設(shè)定端口,注意該端口未被使用,保存退出。
17.Mysql如何為表字段添加索引?
(1)添加PRIMARY KEY(主鍵索引)
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
(2)添加UNIQUE(唯一索引)
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
(3)添加INDEX(普通索引)
ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
(4)添加FULLTEXT(全文索引)
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
(5)添加多列索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
18.說(shuō)說(shuō)自己對(duì)于 MySQL 常見(jiàn)的兩種存儲(chǔ)引擎:MyISAM與InnoDB的理解?
InnoDB 引擎:InnoDB 引擎提供了對(duì)數(shù)據(jù)庫(kù) acid 事務(wù)的支持,并且還提供了行級(jí)鎖和外鍵的約束,它的設(shè)計(jì)的目標(biāo)就是處理大數(shù)據(jù)容量的數(shù)據(jù)庫(kù)系統(tǒng)。MySQL 運(yùn)行的時(shí)候,InnoDB 會(huì)在內(nèi)存中建立緩沖池,用于緩沖數(shù)據(jù)和索引。但是該引擎是不支持全文搜索,同時(shí)啟動(dòng)也比較的慢,它是不會(huì)保存表的行數(shù)的,所以當(dāng)進(jìn)行 select count() from table 指令的時(shí)候,需要進(jìn)行掃描全表。由于鎖的粒度小,寫(xiě)操作是不會(huì)鎖定全表的,所以在并發(fā)度較高的場(chǎng)景下使用會(huì)提升效率的。
MyIASM 引擎:MySQL 的默認(rèn)引擎,但不提供事務(wù)的支持,也不支持行級(jí)鎖和外鍵。因此當(dāng)執(zhí)行插入和更新語(yǔ)句時(shí),即執(zhí)行寫(xiě)操作的時(shí)候需要鎖定這個(gè)表,所以會(huì)導(dǎo)致效率會(huì)降低。不過(guò)和 InnoDB 不同的是,MyIASM 引擎是保存了表的行數(shù),于是當(dāng)進(jìn)行 select count() from table 語(yǔ)句時(shí),可以直接的讀取已經(jīng)保存的值而不需要進(jìn)行掃描全表。所以,如果表的讀操作遠(yuǎn)遠(yuǎn)多于寫(xiě)操作時(shí),并且不需要事務(wù)的支持的,可以將 MyIASM 作為數(shù)據(jù)庫(kù)引擎的首選。