資料庫
: 資料庫(DataBase 簡稱 DB)就是資訊的集合或者說資料庫是由資料庫管理系統管理的資料的集合。
資料庫管理系統
: 資料庫管理系統(Database Management System 簡稱 DBMS)是一種操縱和管理資料庫的大型軟體,通常用於建立、使用和維護資料庫。
資料庫系統
: 資料庫系統(Data Base System,簡稱 DBS)通常由軟體、資料庫和資料管理員(DBA)組成。
資料庫管理員
: 資料庫管理員(Database Administrator, 簡稱 DBA)負責全面管理和控制資料庫系統。
資料庫系統基本構成如下圖所示:
什麼是元組, 碼, 候選碼, 主碼, 外碼, 主屬性, 非主屬性?
元組
: 元組(tuple)是關係資料庫中的基本概念,關係是一張表,表中的每行(即資料庫中的每條記錄)就是一個元組,每列就是一個屬性。 在二維表裡,元組也稱為行。
碼
:碼就是能唯一標識實體的屬性,對應表中的列。
候選碼
: 若關係中的某一屬性或屬性組的值能唯一的標識一個元組,而其任何、子集都不能再標識,則稱該屬性組為候選碼。例如:在學生實體中,“學號”是能唯一的區分學生實體的,同時又假設“姓名”、“班級”的屬性組合足以區分學生實體,那麼{學號}和{姓名,班級}都是候選碼。
主碼
: 主碼也叫主鍵。主碼是從候選碼中選出來的。 一個實體集中只能有一個主碼,但可以有多個候選碼。
外碼
: 外碼也叫外來鍵。如果一個關係中的一個屬性是另外一個關係中的主碼則這個屬性為外碼。
主屬性
: 候選碼中出現過的屬性稱為主屬性。比如關係 工人(工號,身份證號,姓名,性別,部門)。 顯然工號和身份證號都能夠唯一標示這個關係,所以都是候選碼。工號、身份證號這兩個屬性就是主屬性。如果主碼是一個屬性組,那麼屬性組中的屬性都是主屬性。
非主屬性:
不包含在任何一個候選碼中的屬性稱為非主屬性。比如在關係——學生(學號,姓名,年齡,性別,班級)中,主碼是“學號”,那麼其他的“姓名”、“年齡”、“性別”、“班級”就都可以稱為非主屬性。
主鍵和外來鍵有什麼區別?
主鍵(主碼)
:主鍵用於唯一標識一個元組,不能有重複,不允許為空。一個表只能有一個主鍵。
外來鍵(外碼)
:外來鍵用來和其他表建立聯絡用,外來鍵是另一表的主鍵,外來鍵是可以有重複的,可以是空值。一個表可以有多個外來鍵。
為什麼不推薦使用外來鍵與級聯?
對於外來鍵和級聯,阿里巴巴開發手冊這樣說到:
【強制】不得使用外來鍵與級聯,一切外來鍵概念必須在應用層解決。
說明: 以學生和成績的關係為例,學生表中的 student_id 是主鍵,那麼成績表中的 student_id 則為外來鍵。如果更新學生表中的 student_id,同時觸發成績表中的 student_id 更新,即為級聯更新。外來鍵與級聯更新適用於單機低併發,不適合分散式、高併發叢集; 級聯更新是強阻塞,存在資料庫更新風暴的風 險; 外來鍵影響資料庫的插入速度
為什麼不要用外來鍵呢?大部分人可能會這樣回答:
增加了複雜性:
a。 每次做DELETE 或者UPDATE都必須考慮外來鍵約束,會導致開發的時候很痛苦, 測試資料極為不方便; b。 外來鍵的主從關係是定的,假如那天需求有變化,資料庫中的這個欄位根本不需要和其他表有關聯的話就會增加很多麻煩。
增加了額外工作
: 資料庫需要增加維護外來鍵的工作,比如當我們做一些涉及外來鍵欄位的增,刪,更新操作之後,需要觸發相關操作去檢查,保證資料的的一致性和正確性,這樣會不得不消耗資源;(個人覺得這個不是不用外來鍵的原因,因為即使你不使用外來鍵,你在應用層面也還是要保證的。所以,我覺得這個影響可以忽略不計。)
外來鍵還會因為需要請求對其他表內部加鎖而容易出現死鎖情況;
對分庫分表不友好
:因為分庫分表下外來鍵是無法生效的。
……
我個人覺得上面這種回答不是特別的全面,只是說了外來鍵存在的一個常見的問題。實際上,我們知道外來鍵也是有很多好處的,比如:
保證了資料庫資料的一致性和完整性;
級聯操作方便,減輕了程式程式碼量;
……
所以說,不要一股腦的就拋棄了外來鍵這個概念,既然它存在就有它存在的道理,如果系統不涉及分庫分表,併發量不是很高的情況還是可以考慮使用外來鍵的。
# 什麼是 ER 圖?
我們做一個專案的時候一定要試著畫 ER 圖來捋清資料庫設計,這個也是面試官問你專案的時候經常會被問道的。
E-R 圖
也稱實體-聯絡圖(Entity Relationship Diagram),提供了表示實體型別、屬性和聯絡的方法,用來描述現實世界的概念模型。 它是描述現實世界關係概念模型的有效方法。 是表示概念關係模型的一種方式。
下圖是一個學生選課的 ER 圖,每個學生可以選若干門課程,同一門課程也可以被若干人選擇,所以它們之間的關係是多對多(M: N)。另外,還有其他兩種關係是:1 對 1(1:1)、1 對多(1: N)。
我們試著將上面的 ER 圖轉換成資料庫實際的關係模型(實際設計中,我們通常會將任課教師也作為一個實體來處理):
資料庫正規化瞭解嗎?
1NF(第一正規化)
屬性(對應於表中的欄位)不能再被分割,也就是這個欄位只能是一個值,不能再分為多個其他的欄位了。
1NF 是所有關係型資料庫的最基本要求
,也就是說關係型資料庫中建立的表一定滿足第一正規化。
2NF(第二正規化)
2NF 在 1NF 的基礎之上,消除了非主屬性對於碼的部分函式依賴。如下圖所示,展示了第一正規化到第二正規化的過渡。第二正規化在第一正規化的基礎上增加了一個列,這個列稱為主鍵,非主屬性都依賴於主鍵。
一些重要的概念:
函式依賴(functional dependency)
:若在一張表中,在屬性(或屬性組)X 的值確定的情況下,必定能確定屬性 Y 的值,那麼就可以說 Y 函式依賴於 X,寫作 X → Y。
部分函式依賴(partial functional dependency)
:如果 X→Y,並且存在 X 的一個真子集 X0,使得 X0→Y,則稱 Y 對 X 部分函式依賴。比如學生基本資訊表 R 中(學號,身份證號,姓名)當然學號屬性取值是唯一的,在 R 關係中,(學號,身份證號)->(姓名),(學號)->(姓名),(身份證號)->(姓名);所以姓名部分函式依賴與(學號,身份證號);
完全函式依賴(Full functional dependency)
:在一個關係中,若某個非主屬性資料項依賴於全部關鍵字稱之為完全函式依賴。比如學生基本資訊表 R(學號,班級,姓名)假設不同的班級學號有相同的,班級內學號不能相同,在 R 關係中,(學號,班級)->(姓名),但是(學號)->(姓名)不成立,(班級)->(姓名)不成立,所以姓名完全函式依賴與(學號,班級);
傳遞函式依賴
: 在關係模式 R(U)中,設 X,Y,Z 是 U 的不同的屬性子集,如果 X 確定 Y、Y 確定 Z,且有 X 不包含 Y,Y 不確定 X,(X∪Y)∩Z=空集合,則稱 Z 傳遞函式依賴(transitive functional dependency) 於 X。傳遞函式依賴會導致資料冗餘和異常。傳遞函式依賴的 Y 和 Z 子集往往同屬於某一個事物,因此可將其合併放到一個表中。比如在關係 R(學號 , 姓名, 系名,系主任)中,學號 → 系名,系名 → 系主任,所以存在非主屬性系主任對於學號的傳遞函式依賴。。
3NF(第三正規化)
3NF 在 2NF 的基礎之上,消除了非主屬性對於碼的傳遞函式依賴 。符合 3NF 要求的資料庫設計,
基本
上解決了資料冗餘過大,插入異常,修改異常,刪除異常的問題。比如在關係 R(學號 , 姓名, 系名,系主任)中,學號 → 系名,系名 → 系主任,所以存在非主屬性系主任對於學號的傳遞函式依賴,所以該表的設計,不符合 3NF 的要求。
總結
1NF:屬性不可再分。
2NF:1NF 的基礎之上,消除了非主屬性對於碼的部分函式依賴。
3NF:3NF 在 2NF 的基礎之上,消除了非主屬性對於碼的傳遞函式依賴 。
# 什麼是儲存過程?
我們可以把儲存過程看成是一些 SQL 語句的集合,中間加了點邏輯控制語句。儲存過程在業務比較複雜的時候是非常實用的,比如很多時候我們完成一個操作可能需要寫一大串 SQL 語句,這時候我們就可以寫有一個儲存過程,這樣也方便了我們下一次的呼叫。儲存過程一旦除錯完成通過後就能穩定執行,另外,使用儲存過程比單純 SQL 語句執行要快,因為儲存過程是預編譯過的。
儲存過程在網際網路公司應用不多,因為儲存過程難以除錯和擴充套件,而且沒有移植性,還會消耗資料庫資源。
阿里巴巴 Java 開發手冊裡要求禁止使用儲存過程。
drop、delete 與 truncate 區別?
用法不同
drop(丟棄資料): drop table 表名 ,直接將表都刪除掉,在刪除表的時候使用。
truncate (清空資料) : truncate table 表名 ,只刪除表中的資料,再插入資料的時候自增長 id 又從 1 開始,在清空表中資料的時候使用。
delete(刪除資料) : delete from 表名 where 列名=值,刪除某一列的資料,如果不加 where 子句和truncate table 表名作用類似。
truncate 和不帶 where 子句的 delete、以及 drop 都會刪除表內的資料,但是
truncate 和 delete 只刪除資料不刪除表的結構(定義),執行 drop 語句,此表的結構也會刪除,也就是執行 drop 之後對應的表不復存在。
# 屬於不同的資料庫語言
truncate 和 drop 屬於 DDL(資料定義語言)語句,操作立即生效,原資料不放到 rollback segment 中,不能回滾,操作不觸發 trigger。而 delete 語句是 DML (資料庫操作語言)語句,這個操作會放到 rollback segement 中,事務提交之後才生效。
DML 語句和 DDL 語句區別:
DML 是資料庫操作語言(Data Manipulation Language)的縮寫,是指對資料庫中表記錄的操作,主要包括表記錄的插入(insert)、更新(update)、刪除(delete)和查詢(select),是開發人員日常使用最頻繁的操作。
DDL (Data Definition Language)是資料定義語言的縮寫,簡單來說,就是對資料庫內部的物件進行建立、刪除、修改的操作語言。它和 DML 語言的最大區別是 DML 只是對錶內部資料的操作,而不涉及到表的定義、結構的修改,更不會涉及到其他物件。DDL 語句更多的被資料庫管理員(DBA)所使用,一般的開發人員很少使用。
# 執行速度不同
一般來說:drop>truncate>delete(這個我沒有設計測試過)。
# 資料庫設計通常分為哪幾步?
需求分析
: 分析使用者的需求,包括資料、功能和效能需求。
概念結構設計
: 主要採用 E-R 模型進行設計,包括畫 E-R 圖。
邏輯結構設計
: 透過將 E-R 圖轉換成表,實現從 E-R 模型到關係模型的轉換。
物理結構設計
: 主要是為所設計的資料庫選擇合適的儲存結構和存取路徑。
資料庫實施
: 包括程式設計、測試和試執行
資料庫的執行和維護
: 系統的執行與資料庫的日常維護。