閱讀本文大約須要 8 分鐘。
數據庫打算只寫 MySQL,Redis 兩部分,不會很細,主要以面試題爲主。此次寫的是 MySQL 篇。面試
這裏先介紹一下數據庫的概念,數據庫是一種數據結構,內含多種算法,幫助咱們將數據以最優化的方式存儲在計算機中,也能夠幫助咱們快速找到存儲的數據。算法
數據最終存儲在計算機中都是以「二進制」的方式存儲。好比 4,存儲在計算機中實際上是以 0100 的方式存儲。好比 A,存儲在計算中是以 0100 0001 的方式存儲。數據庫
char
:定長字符型,最大可存儲 255 (2 的 8 次方)個字節長度,能夠理解成最大能夠存儲 255 個字符。在計算機中以 8 位二進制的方式存儲。安全
使用char
類型存儲數據時,假設存儲的數據是 4,4 在計算機中存儲的結果是 0000 0100,意味着使用定長字符型char
,無論你存儲的值是多少位,最終在計算機裏都是以 8 位二進制的方式存儲,不滿 8 位,前面補 0。超過 8 位,超出的部分會被去除。服務器
也就是說當使用char
字符型存儲數據後,該數據轉換爲二進制時的長度超過了 8 位,那麼該數據將不會完整存儲,會「丟失」一部分數據。數據結構
varchar
:不定長字符型,最大可存儲 65535(2 的 16 次方) 個字節長度,在計算機中以 16位 二進制的方式存儲。併發
它與char
不一樣的地方在於,當字符長度在 0-255 之內時,會在後面添加一個字節,超過 255 時,添加兩個字節。一樣的,當超過最大存儲長度後,也會丟失一部分數據。函數
text
:長文本數據類型,最大可存儲 65555 個字節長度,不能指定長度,也就是說不支持text(num)
。高併發
可是該類型儘可能不要使用,由於text
類型數據在檢索中,不會使用索引,而是使用全局搜索,這會產生臨時表,使得檢索時間變長,不推薦使用。性能
因爲char
和varchar
的特性,在實際使用當中,若是該數據是常常會發生變化、常用的,那麼推薦使用char
類型,由於 MySQL 在對數據進行排序時,會根據該數據的長度來排,固定長度的char
類型會提供更高的性能。可是因爲固定長度的特性,在存儲短數據時,必定程度上也會形成資源浪費,算是一個雙刃劍。
100 只是在呈現角度上定義的,好比該數據有 120 個字符,那麼你在查詢該數據時,看到的只有 100 個。可是若是在定義時,添加了UNSIGNED ZEROFILL
屬性,那麼這將改變該類型的最大存儲長度。
一樣的,在實際使用當中,varchar(num)
裏的值不須要定義的特別長,只要夠用就行,具體緣由上面有提,這裏再也不贅述。
DORP
:非事務操做,完全刪除一張表,沒法反悔恢復。
DELETE
:事務操做,刪除表裏的一行或多行數據,若是反悔或是誤刪,能夠經過「事務回滾」恢復該表。不會影響該表下的view
或索引。
TRUNCATE
:非事務操做,刪除表裏的某行數據,或是刪除整張表的數據(表依然存在,只是成了一張空表)。沒法反悔恢復,而且會將該表下的view
或索引重置。
執行速度:DROP > TRUNCATE > DELETE。
第一範式:表中的字段只能表達一種意思,不能模棱兩可。
第二範式:表必須含有一個惟一主鍵來標識這張表。
第三範式:表中的字段不能互相依賴。
Scale Out(垂直切分)
Scale Up(橫向拆分)
這裏有篇文章值得看一看。MySQL 分區、分表
若是把數據庫當作一本書的話, 那麼索引就是書的「目錄頁」,經過目錄,咱們能夠快速定位查找內容,一樣的,目錄頁在書中也佔了一頁紙,因此索引是一個數據結構,也要佔據數據庫物理內存。
索引分爲 4 種類型:普通索引、惟一索引、主鍵索引和全文索引(MyISAM 專有)。
索引的建立規則:常用的字段名,和出如今 where 後面的字段名,建議爲它們建立索引,索引要遵循最左前綴原則(最能體現該索引特徵,也就是經常使用的字段放最左邊)。
索引的原理:能夠看看這篇文章。索引
索引的使用場景:中等、大量數據時,使用索引效率會很是高,小型數據不建議使用索引,沒有全局搜索來的快。
索引的做用:索引能夠提升查詢速度。可是索引會增長數據庫存儲額外開銷。索引會將數據庫查詢時的隨機 I/O 變成順序 I/O,減小服務器排序操做,和臨時表的開銷。
EXPLAIN
查看 SQL 執行計劃,幫助本身查看哪些地方能夠優化。SELECT * FROM xxx
這種查詢語句,須要什麼就查什麼。text
這種類型,這會使得數據查詢該字段時,建立臨時表。LIMIT
,爲查詢結果限制顯示頁數。EXISTS
和BETWEEN
代替IN
。WHERE
中使用表達式操做,這會使得 MySQL 放棄使用索引查詢。INNER JOIN
而不是LEFT JOIN
,由於前者默認使用小表驅動大表。LIKE
。NULL
屬性,在對NULL
進行判斷時,會使得 MySQL 放棄使用索引。COUNT(*)
時,速度遠高於 InnoDB。InnoDB 引擎下,MySQL 支持事務操做,事務擁有如下幾個特色:
使用事務的操做,要麼執行,要麼不執行,只有一個結果,可是事務能夠回滾,也就是撤回操做。
InnoDB 引擎下的 MySQL 在處理高併發時,會對 MySQL 數據庫添加鎖機制,以此完成併發的要求,並保證數據的完整性,可靠性。
悲觀鎖是 MySQL 爲數據庫添加行鎖,強行爲多個事務排序,阻塞事務運行,解決事務之間的衝突問題,可是事務之間有可能出現長時間等待,且開鎖、解鎖須要額外的數據庫資源消耗。因此要謹慎使用。
樂觀鎖沒有鎖機制,可是引入了版本號控制,在高併發時,數據庫在事務提交以前會進行版本號校驗,若是版本後先後不一致,說明此刻有其餘事務正在操做,那麼本次事務從新操做。
版本號的好處在於沒有鎖的開銷,而且只在事務最後提交更改時進行判斷,可是也要考慮從新執行的代價是否過大。
總的來講,高併發下,讀操做多的時候,使用樂觀鎖,寫的操做時,使用悲觀鎖。
未更完,下次更新補上。