數(shù)據(jù)庫(kù)概念-引擎&存儲(chǔ)&索引&優(yōu)化

一、引言
一個(gè)應(yīng)用是怎樣調(diào)用數(shù)據(jù)庫(kù)的呢?答案如下圖

圖1

數(shù)據(jù)庫(kù)通常分為: 層次式數(shù)據(jù)庫(kù); 網(wǎng)絡(luò)式數(shù)據(jù)庫(kù); 關(guān)系式數(shù)據(jù)庫(kù)三種類型

可以看出對(duì)數(shù)據(jù)庫(kù)的學(xué)習(xí)關(guān)注點(diǎn)集中在數(shù)據(jù)庫(kù)引擎和數(shù)據(jù)庫(kù)操作(存儲(chǔ)、查找刪除等)上


二、數(shù)據(jù)庫(kù)引擎

?1、作用:

? ? ? ? ? ?數(shù)據(jù)庫(kù)中的存儲(chǔ)引擎其實(shí)是對(duì)使用了該引擎的表進(jìn)行某種設(shè)置,數(shù)據(jù)庫(kù)中的表設(shè)定了什么存儲(chǔ)引擎,那么該表在數(shù)據(jù)存儲(chǔ)方式、數(shù)據(jù)更新方式、數(shù)據(jù)查詢性能以及是否支持索引等方面就會(huì)有不同的“效果”。?

2、MySQL數(shù)據(jù)庫(kù)引擎介紹:

? ? ? ? ? ?(ISAM、MyISAM、HEAP(也稱為MEMORY)、CSV、BLACKHOLE、ARCHIVE、PERFORMANCE_SCHEMA、InnoDB、Berkeley、Merge、Federated和Cluster/NDB等,除此以外我們也可以參照MySQL++ API創(chuàng)建自己的數(shù)據(jù)庫(kù)引擎)

?ISAM:一個(gè)定義明確且歷經(jīng)時(shí)間考驗(yàn)的數(shù)據(jù)表格管理方法,它在設(shè)計(jì)之時(shí)就考慮到 數(shù)據(jù)庫(kù)被查詢的次數(shù)要遠(yuǎn)大于更新的次數(shù)。因此,ISAM執(zhí)行讀取操作的速度很快,而且不占用大量的內(nèi)存和存儲(chǔ)資源。ISAM的兩個(gè)主要不足之處在于,它不 支持事務(wù)處理,也不能夠容錯(cuò)

MyISAM:是為了查和增加,效率高。所有功能都圍繞這這個(gè),如果表的讀操作遠(yuǎn)遠(yuǎn)多于寫操作且不需要數(shù)據(jù)庫(kù)事務(wù)的支持,那么MyIASM也是很好的選擇。

Innodb:引擎功能更強(qiáng)(事務(wù)等)效率低一些。支持事務(wù)和行級(jí)鎖

? ? ? ? ? Innodb引擎提供了對(duì)數(shù)據(jù)庫(kù)ACID事務(wù)的支持,并且實(shí)現(xiàn)了SQL標(biāo)準(zhǔn)的四種隔離級(jí)別,關(guān)于數(shù)據(jù)庫(kù)事務(wù)與其隔離級(jí)別的內(nèi)容請(qǐng)見數(shù)據(jù)庫(kù)事務(wù)與其隔離級(jí)別這篇文章。該引擎還提供了行級(jí)鎖和外鍵約束,它的設(shè)計(jì)目標(biāo)是處理大容量數(shù)據(jù)庫(kù)系統(tǒng),它本身其實(shí)就是基于MySQL后臺(tái)的完整數(shù)據(jù)庫(kù)系統(tǒng),MySQL運(yùn)行時(shí)Innodb會(huì)在內(nèi)存中建立緩沖池,用于緩沖數(shù)據(jù)和索引。但是該引擎不支持FULLTEXT類型的索引,而且它沒(méi)有保存表的行數(shù),當(dāng)SELECT COUNT(*) FROM TABLE時(shí)需要掃描全表。當(dāng)需要使用數(shù)據(jù)庫(kù)事務(wù)時(shí),該引擎當(dāng)然是首選。由于鎖的粒度更小,寫操作不會(huì)鎖定全表,所以在并發(fā)較高時(shí),使用Innodb引擎會(huì)提升效率。但是使用行級(jí)鎖也不是絕對(duì)的,如果在執(zhí)行一個(gè)SQL語(yǔ)句時(shí)MySQL不能確定要掃描的范圍,InnoDB表同樣會(huì)鎖全表。

3、MyISAMInnoDB的選擇 -推薦參考-詳細(xì)

? ? ? ? ?MyISAM:默認(rèn)表類型,它是基于傳統(tǒng)的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序訪問(wèn)方法) 的縮寫,它是存儲(chǔ)記錄和文件的標(biāo)準(zhǔn)方法。不是事務(wù)安全的,而且不支持外鍵,如果執(zhí)行大量的select,insert MyISAM比較適合。

? ? ? ? InnoDB:支持事務(wù)安全的引擎,支持外鍵、行鎖、事務(wù)是他的最大特點(diǎn)。如果有大量的update和insert,建議使用InnoDB,特別是針對(duì)多個(gè)并發(fā)和QPS較高的情況。


三、數(shù)據(jù)庫(kù)存儲(chǔ)

1、存儲(chǔ)過(guò)程:

???? 將常用的或很復(fù)雜的工作,預(yù)先用SQL語(yǔ)句寫好并用一個(gè)指定的名稱存儲(chǔ)起來(lái),?那么以后要叫數(shù)據(jù)庫(kù)提供與已定義好的存儲(chǔ)過(guò)程的功能相同的服務(wù)時(shí),只需調(diào)用execute,即可自動(dòng)完成命令?!獙儆谧远x操作避免反復(fù)操作

2、使用存儲(chǔ)過(guò)程優(yōu)點(diǎn)

? ? ? ? 以后在執(zhí)行不用重編譯,提高執(zhí)行速度——可重復(fù)性

? ? ? ? 進(jìn)行復(fù)雜操作時(shí),可將復(fù)雜操作封裝起來(lái)與數(shù)據(jù)庫(kù)提供的事物處理結(jié)合起來(lái)一起使用——簡(jiǎn)化

? ? ? ? 可設(shè)定某個(gè)用戶對(duì)指定存儲(chǔ)過(guò)程的使用權(quán)——安全性高

具體存儲(chǔ)過(guò)程語(yǔ)法,參看以下兩個(gè)鏈接:

鏈接1

鏈接2


四、數(shù)據(jù)庫(kù)索引(參考鏈接)

?1、簡(jiǎn)介:

? ? ? ? ? 索引是對(duì)記錄按照多個(gè)字段進(jìn)行排序的一種方式。對(duì)表中的某個(gè)字段建立索引會(huì)創(chuàng)建另一種數(shù)據(jù)結(jié)構(gòu),其中保存著字段的值,每個(gè)值又指向與它相關(guān)的記錄。這種索引的數(shù)據(jù)結(jié)構(gòu)是經(jīng)過(guò)排序的,因而可以對(duì)其執(zhí)行二分查找。

缺點(diǎn)是占用額外的磁盤空間

2、數(shù)據(jù)結(jié)構(gòu):

? ? ? ? ? ? 假如有一億條數(shù)據(jù),常規(guī)查找算法復(fù)雜度是O(n),且一億次的匹配大量消耗磁盤的IO和CPU

如果把表轉(zhuǎn)換成平衡樹結(jié)構(gòu),假設(shè)數(shù)有10層,只需10次就可以找到所需數(shù)據(jù),算法的復(fù)雜度就是O(log n)

復(fù)雜度算法公式

常用的數(shù)據(jù)機(jī)構(gòu)有:b tree或者 b+ tree(平衡樹)、哈希桶建立索引

以下是兩種索引聚焦索引和非聚焦索引查找過(guò)程:

聚類索引
非聚焦索引


通過(guò)聚集索引可以查到需要查找的數(shù)據(jù), 而通過(guò)非聚集索引可以查到記錄對(duì)應(yīng)的主鍵值 , 再使用主鍵的值通過(guò)聚集索引查找到需要的數(shù)據(jù)

例子:

//建立索引

create indexindex_birthdayonuser_info(birthday);

//查詢生日在1991年11月1日出生用戶的用戶名

select user_name from

user_info where birthday = '1991-11-1'

這句SQL語(yǔ)句的執(zhí)行過(guò)程如下

首先,通過(guò)非聚集索引index_birthday查找birthday等于1991-11-1的所有記錄的主鍵ID值

然后,通過(guò)得到的主鍵ID值執(zhí)行聚集索引查找,找到主鍵ID值對(duì)就的真實(shí)數(shù)據(jù)(數(shù)據(jù)行)存儲(chǔ)的位置

最后, 從得到的真實(shí)數(shù)據(jù)中取得user_name字段的值返回, 也就是取得最終的結(jié)果

我們把birthday字段上的索引改成雙字段的覆蓋索引

create index

index_birthday_and_user_name on user_info(birthday, user_name);

這句SQL語(yǔ)句的執(zhí)行過(guò)程就會(huì)變?yōu)?/p>

????? 通過(guò)非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的葉節(jié)點(diǎn)的內(nèi)容,然而, 葉節(jié)點(diǎn)中除了有user_name表主鍵ID的值以外, user_name字段的值也在里面, 因此不需要通過(guò)主鍵ID值的查找數(shù)據(jù)行的真實(shí)所在, 直接取得葉節(jié)點(diǎn)中user_name的值返回即可。


五、數(shù)據(jù)庫(kù)優(yōu)化

????? 對(duì)于mysql數(shù)據(jù)庫(kù)來(lái)說(shuō),索引的使用是很巧妙的。它設(shè)置的好可以提高速度,設(shè)置的不好不光無(wú)法提高速度,還會(huì)造成浪費(fèi)內(nèi)存空間。在優(yōu)化方面

1、分區(qū)-硬件上除了本身性能

??? 分區(qū)將數(shù)據(jù)在物理上分隔開,不同分區(qū)的數(shù)據(jù)可以制定保存在處于不同磁盤上的數(shù)據(jù)文件里。這樣,當(dāng)對(duì)這個(gè)表進(jìn)行查詢時(shí),只需要在表分區(qū)中進(jìn)行掃描,而不必進(jìn)行全表掃描,明顯縮短了查詢時(shí)間,另外處于不同磁盤的分區(qū)也將對(duì)這個(gè)表的數(shù)據(jù)傳輸分散在不同的磁盤I/O,做到硬盤之間I/O負(fù)載均衡

2、索引-數(shù)據(jù)庫(kù)設(shè)計(jì)

??? 對(duì)一個(gè)大型表進(jìn)行分區(qū)之后,可以根據(jù)相應(yīng)的分區(qū)建立分區(qū)索引。但是個(gè)人覺得不是所有的表都需要建立索引,只針對(duì)大數(shù)據(jù)量的表建立索引。應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by ,group by 涉及的列上建立索引。

3、別名的使用-小的優(yōu)化

??? 別名是大型數(shù)據(jù)庫(kù)的應(yīng)用技巧,就是表名、列名在查詢中以一個(gè)字母為別名,查詢速度要比建連接表快1.5倍。

4、優(yōu)化語(yǔ)句-自身

???? 查詢盡可能使用 limit 減少返回的行數(shù),減少數(shù)據(jù)傳輸時(shí)間和帶寬浪費(fèi);任何地方都不要使用 select * from table ,用具體的字段列表代替“*”,不要返回用不到的任何字段。

PS:一個(gè)DBA面經(jīng),感覺不錯(cuò)推薦

?

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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