目錄
(一)數據庫基礎
1)主鍵、超鍵、候選鍵、外鍵?
- 超鍵(super key): 在關係中能唯一標識元組的屬性集稱爲關係模式的超鍵
- 候選鍵(candidate key): 不含有多餘屬性的超鍵稱爲候選鍵。也就是在候選鍵中,若再刪除屬性,就不是鍵了!
- 主鍵(primary key): 用戶選作元組標識的一個候選鍵程序主鍵
- 外鍵(foreign key):如果關係模式R中屬性K是其它模式的主鍵,那麼k在模式R中稱爲外鍵。
主鍵爲候選鍵的子集,候選鍵爲超鍵的子集,而外鍵的確定是相對於主鍵的。
2)視圖?
視圖是虛擬的表,與包含數據的表不一樣,視圖只包含使用時動態檢索數據的查詢;不包含任何列或數據。使用視圖可以簡化複雜的sql操作,隱藏具體的細節,保護數據;視圖創建後,可以使用與表相同的方式利用它們。
視圖不能被索引,也不能有關聯的觸發器或默認值,如果視圖本身內有order by 則對視圖再次order by將被覆蓋。
創建視圖?
create view XXX as XXXXXXXXXXXXXX;
視圖可以更改嗎?
對於某些視圖比如未使用聯結子查詢分組聚集函數Distinct Union等,是可以對其更新的,對視圖的更新將對基表進行更新;但是視圖主要用於簡化檢索,保護數據,並不用於更新,而且大部分視圖都不可以更新。
3)數據庫事務的四個特性及含義?
數據庫事務transanction正確執行的四個基本要素:ACID。
原子性(Atomicity)、一致性(Correspondence)、隔離性(Isolation)、持久性(Durability)。
-
原子性:事務作爲一個整體被執行 ,要麼全部執行,要麼全部不執行
-
一致性:保證數據庫狀態從一個一致狀態轉變爲另一個一致狀態
-
隔離性:多個事務併發執行時,一個事務的執行不應影響其他事務的執行
-
持久性:一個事務一旦提交,對數據庫的修改應該永久保存
4)事務的隔離級別?
隔離級別決定了一個session中的事務可能對另一個session中的事務的影響。分別是:
- 讀未提交(READ UNCOMMITTED):最低級別的隔離,通常又稱爲dirty read,它允許一個事務讀取另一個事務還沒 commit 的數據,這樣可能會提高性能,但是會導致髒讀問題;
- 讀已提交(READ COMMITTED):在一個事務中只允許對其它事務已經 commit 的記錄可見,該隔離級別不能避免不可重複讀問題;
- 可重複讀(REPEATABLE READ):在一個事務開始後,其他事務對數據庫的修改在本事務中不可見,直到本事務 commit 或 rollback。但是,其他事務的 insert/delete 操作對該事務是可見的,也就是說,該隔離級別並不能避免幻讀問題。在一個事務中重複 select 的結果一樣,除非本事務中 update 數據庫。
- 序列化(SERIALIZABLE):最高級別的隔離,只允許事務串行執行。
-
丟失更新:一個事務的更新覆蓋了另一個事務的更新;
-
髒讀:一個事務讀取了另一個事務未提交的數據;
-
不可重複讀:不可重複讀的重點是修改,同樣條件下兩次讀取結果不同,也就是說,被讀取的數據可以被其它事務修改;
-
幻讀:幻讀的重點在於新增或者刪除,同樣條件下兩次讀出來的記錄數不一樣。
|
髒讀
|
不可重複讀
|
幻讀
|
讀未提交RU
|
☑️
|
☑️ |
☑️
|
讀已提交RC
|
✖️
|
☑️
|
☑️
|
可重複讀RR
|
✖️
|
✖️
|
☑️
|
可串行化Serializable
|
✖️
|
✖️
|
✖️
|
5)安全性操作?
- 授權:grant 權限(列) on 表名 to 用戶
- 所有權限:all priviliges
- 收回權限:revoke 權限(列) on 表名 from 用戶
6)完整性約束?
- 主鍵約束:primary key
- 外鍵約束:foreign key
- 唯一約束:unique
- 檢查約束:check
- 非空約束:not null
7)數據庫範式?
第一範式(1NF):列不可分
無重複列,每一列都爲不可分割的基本數據項。
第二範式(2NF):消除非主屬性對碼的部分函數依賴
屬性完全依賴於主鍵,指不能存在僅依賴主關鍵字一部分的屬性。
第三範式(3NF):消除非主屬性對碼的傳遞函數依賴
屬性不依賴於其他非主屬性,不能存在非主屬性對於碼的傳遞函數依賴。
第一範式
如果一個關係模式R的所有屬性都是不可分的基本數據項,則R∈1NF(即R符合第一範式)。
一、每個字段都只能存放單一值
課程有兩個值,不符合第一範式,可改爲如下
二、每筆記錄都要能利用一個惟一的主鍵來加以識別
這裏出現了重複組,同樣不滿足第一範式,因爲缺乏唯一標識碼,可改爲
第二範式
若關係模式R∈1NF(即R符合第一範式),並且每一個非主屬性都完全依賴於R的碼,則R∈2NF(即R符合第二範式)。
這裏表的碼爲(學號,課程),即知道這兩項可以確定系名、宿舍、分數,或者是這三項依賴於前兩項,可知:
- 分數完全依賴(學號,課程);
- 系名部分依賴(學號,課程),即知道學號或者課程就能確定系名;
- 宿舍樓部分依賴(學號,課程),即知道學號或者課程就能確定宿舍樓;
由於非主屬性系名,宿舍樓不完全依賴與碼,不符合第二範式,可改爲
第三範式
若關係模式R∈3NF(即R符合第三範式),則每一個非主屬性既不部分依賴於碼也不傳遞依賴於碼。
上面的表2不符合第三範式,這是因爲你知道了系名,同樣也就知道了宿舍樓,稱宿舍樓傳遞依賴於碼(學號),可分解爲
8)數據庫索引?
什麼是索引?
索引是對數據庫表中一個或多個列的值進行排序的數據結構,以協助快速查詢、更新數據庫表中數據。
也可以這樣理解:索引就是加快檢索表中數據的方法。數據庫的索引類似於書籍的索引。在書籍中,索引允許用戶不必翻閱完整個書就能迅速地找到所需要的信息。在數據庫中,索引也允許數據庫程序迅速地找到表中的數據,而不必掃描整個數據庫。
底層數據結構是什麼?
底層數據結構是B+樹。
在數據結構中,我們最爲常見的搜索結構就是二叉搜索樹和AVL樹(高度平衡的二叉搜索樹,爲了提高二叉搜索樹的效率,減少樹的平均搜索長度)了。然而,無論二叉搜索樹還是AVL樹,當數據量比較大時,都會由於樹的深度過大而造成I/O讀寫過於頻繁,進而導致查詢效率低下,因此對於索引而言,多叉樹結構成爲不二選擇。特別地,B-Tree的各種操作能使B樹保持較低的高度,從而保證高效的查找效率。
爲什麼使用B+樹這種數據結構?
查找速度快、效率高,在查找的過程中,每次都能拋棄掉一部分節點,減少遍歷個數。
索引的分類?
- 唯一索引:唯一索引不允許兩行具有相同的索引值
- 主鍵索引:爲表定義一個主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特殊類型。主鍵索引要求主鍵中的每個值是唯一的,並且不能爲空
- 聚集索引(Clustered):表中各行的物理順序與鍵值的邏輯(索引)順序相同,每個表只能有一個
- 非聚集索引(Non-clustered):非聚集索引指定表的邏輯順序。數據存儲在一個位置,索引存儲在另一個位置,索引中包含指向數據存儲位置的指針。可以有多個,小於249個
索引的優缺點?
(1)優點:
- 大大加快數據的檢索速度,這也是創建索引的最主要的原因。
- 加速表和表之間的連接。
- 在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
- 通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
(2)缺點:
- 時間方面:創建索引和維護索引要耗費時間,具體地,當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。
- 空間方面:索引需要佔物理空間。
什麼樣的字段適合創建索引?
- 經常作查詢選擇的字段
- 經常作表連接的字段
- 經常出現在order by, group by, distinct 後面的字段
創建索引時需要注意什麼?
- 非空字段:應該指定列爲NOT NULL,除非你想存儲NULL。在mysql中,含有空值的列很難進行查詢優化,因爲它們使得索引、索引的統計信息以及比較運算更加複雜。你應該用0、一個特殊的值或者一個空串代替空值。
- 取值離散大的字段:(變量各個取值之間的差異程度)的列放到聯合索引的前面,可以通過count()函數查看字段的差異值,返回值越大說明字段的唯一值越多字段的離散程度高。
- 索引字段越小越好:數據庫的數據存儲以頁爲單位一頁存儲的數據越多一次IO操作獲取的數據越大效率越高。
9)drop, delete與truncate的區別?
- drop直接刪掉表
- truncate刪除表中數據,再插入時自增長id又從1開始
- delete刪除表中數據,可以加where字句
具體來講:
DELETE語句執行刪除的過程是每次從表中刪除一行,並且同時將該行的刪除操作作爲事務記錄在日誌中保存以便進行進行回滾操作。TRUNCATE TABLE 則一次性地從表中刪除所有的數據並不把單獨的刪除操作記錄記入日誌保存,刪除行是不能恢復的,並且在刪除的過程中不會激活與表有關的刪除觸發器。執行速度快。
表和索引所佔空間。當表被TRUNCATE 後,這個表和索引所佔用的空間會恢復到初始大小,而DELETE操作不會減少表或索引所佔用的空間。drop語句將表所佔用的空間全釋放掉。
一般而言,drop > truncate > delete。TRUNCATE 和DELETE只刪除數據,而DROP則刪除整個表(結構和數據)。
應用範圍。TRUNCATE 只能對TABLE;DELETE可以是table和view
10)存儲過程、函數、觸發器?
存儲過程就像是編程語言中的函數一樣,封裝了我們的代碼(PLSQL,T-SQL)
-------------創建名爲GetUserAccount的存儲過程----------------
create Procedure GetUserAccount
as
select * from UserAccount
go
-------------執行上面的存儲過程----------------
exec GetUserAccount
存儲過程(procedure)和函數(function)的區別?
本質上它們都是存儲程序。
- 函數只能通過return語句返回單個值或表對象;而存儲過程不允許執行return語句,但是可以通過output參數返回多個值。
- 函數限制比較多,不能用臨時變量,只能用表變量,還有一些函數都不可用等等;而存儲過程的限制相對就比較少。
- 函數可以嵌入在SQL語句中使用,可以在select語句中作爲查詢語句的一個部分調用;而存儲過程一般是作爲一個獨立的部分來執行。
存儲過程(procedure)和觸發器的區別?
觸發器與存儲過程非常相似,觸發器也是SQL語句集,兩者唯一的區別是觸發器不能用EXECUTE語句調用,而是在用戶執行Transact-SQL語句時自動觸發(激活)執行。
觸發器是在一個修改了指定表中的數據時執行的存儲過程。
通常通過創建觸發器來強制實現不同表中的邏輯相關數據的引用完整性和一致性。由於用戶不能繞過觸發器,所以可以用它來強制實施複雜的業務規則,以確保數據的完整性。
- 觸發器主要是通過事件執行觸發而被執行的
- 存儲過程可以通過存儲過程名稱名字直接調用
當對某一表進行諸如UPDATE、INSERT、DELETE這些操作時,SQLSERVER就會自動執行觸發器所定義的SQL語句,從而確保對數據的處理必須符合這些SQL語句所定義的規則。
存儲過程的優點?
- 能夠將代碼封裝起來
- 保存在數據庫之中
- 讓編程語言進行調用
- 存儲過程是一個預編譯的代碼塊,執行效率比較高
- 一個存儲過程替代大量T_SQL語句 ,可以降低網絡通信量,提高通信速率
存儲過程的缺點?
- 每個數據庫的存儲過程語法幾乎都不一樣,難以維護
- 業務邏輯放在數據庫上,難以迭代
(二)MySQL
1)MySQL存儲引擎?
- MyISAM(MySQL5.5版之前的默認引擎)
- InnoDB(MySQL5.5版之後的默認引擎)
MyISAM
- 不支持行鎖(MyISAM只有表鎖),讀取時對需要讀到的所有表加鎖,寫入時則對錶加排他鎖;
- 不支持事務
- 不支持外鍵
- 不支持崩潰後的安全恢復
- 在表有讀取查詢的同時,支持往表中插入新紀錄
- 支持BLOB和TEXT的前500個字符索引,支持全文索引
- 支持延遲更新索引,極大地提升了寫入性能
- 對於不會進行修改的表,支持 壓縮表 ,極大地減少了磁盤空間的佔用
InnoDB
- 支持行鎖,採用MVCC來支持高併發,有可能死鎖
- 支持事務(Transaction)
- 支持外鍵
- 支持崩潰後的安全恢復
- 不支持全文索引
MyISAM與InnoDB常見對比:
- count運算上的區別: 因爲MyISAM緩存有表meta-data(行數等),因此在做COUNT(*)時對於一個結構很好的查詢是不需要消耗多少資源的。而對於InnoDB來說,則沒有這種緩存。
- 是否支持事務和崩潰後的安全恢復: MyISAM 強調的是性能,每次查詢具有原子性,其執行數度比InnoDB類型更快,但是不提供事務支持。但是InnoDB 提供事務支持事務,外部鍵等高級數據庫功能。 具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。
- 是否支持外鍵: MyISAM不支持,而InnoDB支持。
MyISAM更適合讀密集的表,而InnoDB更適合寫密集的的表。
2)表級鎖和行級鎖?
- 表級鎖:每次操作鎖住整張表。開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低;
- 行級鎖:每次操作鎖住一行數據。開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高;
3)B-Tree和B+Tree
B-Tree
B+Tree
B-Tree和B+Tree的區別:
- 非葉子結點的子樹指針與關鍵字個數相同;
- 非葉子結點的子樹指針P[i],指向關鍵字值屬於[K[i], K[i+1])的子樹(B-樹是開區間);
- 爲所有葉子結點增加一個鏈指針;
- 所有關鍵字都在葉子結點出現;
- 內節點不存儲data,只存儲key;
B+的特性:
- 所有關鍵字都出現在葉子結點的鏈表中(稠密索引),且鏈表中的關鍵字恰好是有序的;
- 不可能在非葉子結點命中;
- 非葉子結點相當於是葉子結點的索引(稀疏索引),葉子結點相當於是存儲(關鍵字)數據的數據層;
- 更適合文件索引系統;
參考:
https://www.jianshu.com/p/71927a377dc6
https://www.cnblogs.com/ktao/p/7775100.html
https://juejin.im/post/5b1685bef265da6e5c3c1c34