在關系數據庫這個世界里,所有東西(包括你要記錄的人、物、事,以及它們之間的聯系)都用一種叫做“關系”的結構來表示。而這種“關系”的靈魂,就是“碼”(Key)。
1. 核心思想:萬物皆“關系”
“實體及實體之間的聯系均用單一的數據結構—“關系”來表示。”
- 通俗解釋:
- 實體 (Entity):就是你要描述的獨立事物。比如,“學生”、“課程”、“老師”都是實體。
- 聯系 (Relationship):就是實體之間的關聯。比如,“學生”和“課程”之間有“選課”這個聯系。
- 核心思想:在老式的數據模型里,“實體”和“聯系”可能是用不同的方式來存儲和表示的,很麻煩。關系模型的革命性之處在于,它說:“別搞那么復雜了!不管是‘學生’這種實體,還是‘學生選了什么課’這種聯系,我們全都用一種統一的、規整的二維表格(也就是‘關系’)來表示。”
這就像樂高積木,不管你要搭城堡、飛船還是汽車,你用的都是同一種基本積木塊。這種“單一”和“統一”帶來了極大的簡潔性和理論上的嚴謹性。
2. 基本概念回顧
“關系、域、n目關系、元組、屬性。”
- 關系 (Relation):就是一張二維表。
- 元組 (Tuple):就是表里的一行數據。
- 屬性 (Attribute):就是表里的一列,比如“姓名”列、“學號”列。
- 域 (Domain):屬性的取值范圍,比如“性別”屬性的域是
{男, 女}
。 - n目關系:就是有n列的關系(表)。
3. 靈魂概念:“碼” (Key)
“碼”是用來唯一標識一行數據的,就像你的身份證號,它能把你和全世界幾十億人精確地區分開。沒有“碼”,數據就會亂套。
候選碼 (Candidate Key)
“關系中的某一屬性組,若它的值唯一地標識了一個元組,并具有最小性,則稱該屬性組為候選碼。”
這個定義有兩個關鍵點,我們用一個“學生表”來解釋:
學生表 (學號, 身份證號, 姓名, 性別)
-
關鍵點1:唯一性 (Uniqueness)
學號
在這個表里是不是唯一的?是的,每個學生的學號都不同。身份證號
是不是唯一的?是的,每個人的身份證號也不同。姓名
是不是唯一的?不一定,可能有同名同姓的人。- 所以,
{學號}
和{身份證號}
都滿足唯一性。
-
關鍵點2:最小性 (Minimality)
- 定義:“最小性”指的是,組成這個碼的屬性一個都不能少。如果去掉任何一個屬性,它就不唯一了。
- 我們來看
{學號}
,它本身只有一個屬性,沒法再少了,所以它滿足最小性。 - 同樣,
{身份證號}
也滿足最小性。 - 再看一個組合
{學號, 姓名}
。這個組合肯定是唯一的(因為學號就唯一了)。但是,它滿足最小性嗎?不滿足! 因為你把姓名
去掉,只剩下{學號}
,它照樣是唯一的。所以{學號, 姓名}
這個組合是冗余的,不滿足最小性。
-
結論:在這個學生表中,同時滿足“唯一性”和“最小性”的屬性組有兩個:
{學號}
和{身份證號}
。這兩個都是候選碼。它們都是成為“官方ID”的有力候選人。
主碼 (Primary Key)
“若一個關系有多個候選碼,則選定其中一個為主碼。”
- 通俗解釋:這完全是一個人為選擇的過程。
- 上面我們找到了兩個候選碼:
{學號}
和{身份證號}
。現在,數據庫的設計者需要從中挑選一個作為這張表的“官方指定ID”。 - 比如,我們決定用
{學號}
作為主碼。那么學號
就是這張表的主碼。身份證號
雖然也是候選碼,但它“落選”了,它被稱為備用碼 (Alternate Key)。
為什么要選一個主碼? 為了方便。當別的表需要引用這張表的某一行數據時,大家有一個統一的標準,都知道用 學號
來關聯,避免混亂。
主屬性 (Prime Attribute) 與 非主屬性 (Non-prime Attribute)
“碼中的諸屬性稱為主屬性,不包含在任何候選碼中的屬性稱為非主屬性。”
- 通俗解釋:這是一個對列(屬性)的分類。
- 主屬性:只要一個屬性是任何一個候選碼的一部分,它就是主屬性。
- 在我們的例子中,候選碼是
{學號}
和{身份證號}
。 - 所以,
學號
和身份證號
這兩個屬性都是主屬性。
- 在我們的例子中,候選碼是
- 非主屬性:不包含在任何候選碼中的屬性。
- 在我們的例子中,
姓名
和性別
這兩個屬性,它們既不是{學號}
的一部分,也不是{身份證號}
的一部分。 - 所以,
姓名
和性別
都是非主屬性。
- 在我們的例子中,
這個區分非常重要,它是后續進行數據庫設計規范化(比如判斷是否滿足第二范式、第三范式)的基礎。
總結一下
- 關系:就是一張表,用來統一表示所有數據。
- 候選碼:能唯一標識一行、且不含多余信息的“候選ID”(可能有多個)。
- 主碼:從所有“候選ID”中,人為指定的那個“官方ID”(只有一個)。
- 主屬性/非主屬性:對表里所有列的一個分類,凡是構成“候選ID”的列都是“主屬性”,其余都是“非主屬性”。
核心比喻:關系模式 vs. 關系
- 關系模式 (Schema):這是設計藍圖。它定義了你的“房子”(也就是你的數據表)應該長什么樣:有幾個房間(列)、每個房間叫什么名字(屬性名)、墻壁是什么材質的(數據類型)、承重墻在哪里(主碼和約束)。藍圖是靜態的、穩定的。
- 關系 (Relation):這是建好的房子里實際住進去的人和家具。它是在某個時間點,你的數據表里真實存在的數據行。房子里的內容是動態的、隨時變化的。
這張PPT就是在詳細解釋“設計藍-圖”(關系模式)到底由哪些部分構成。
關系模式的“精裝修”設計藍圖:R(U, D, dom, F)
這個公式看起來嚇人,但它只是把一張表的設計藍圖拆分成了四個組成部分。我們用一個學生表作為例子來解釋:
學生 (學號, 姓名, 專業, 班主任, 班主任電話)
1. R: 關系名 (Relation Name)
- 含義:就是這張表的名字。
- 例子:
學生
2. U: 屬性名集合 (Set of Attributes)
- 含義:這張表里所有列的名字的集合。
- 例子:
U = {學號, 姓名, 專業, 班主任, 班主任電話}
3. D: 域的集合 (Set of Domains)
- 含義:這是所有屬性可能取值的“類型池”的集合。比如,“整數池”、“字符串池”、“日期池”等等。
- 例子:我們的學生表需要整數(用于學號)和字符串(用于其他所有列)。所以
D = {整數域, 字符串域}
。它只是一個原材料倉庫,列出了這張表會用到哪些類型的“原材料”。
重點解釋:dom
和 F
4. dom: 屬性到域的“映象” (Mapping) - 【你的第一個困惑點】
-
學術定義:“映象” (Mapping) 是一個數學術語,意思就是建立“一對一”或“多對一”的對應關系。
-
通俗解釋:
dom
就是一份**“接線圖”或“分配表”。它詳細規定了,U
集合里的每一個屬性(列名),應該從D
集合里的哪一個“類型池”(域)**去取值。 -
例子:
dom
規定了:學號
→整數域
(學號這一列必須是整數)姓名
→字符串域
(姓名這一列必須是字符串)專業
→字符串域
(專業這一列必須是字符串)- …以此類推
-
它在實踐中是什么?
當你在用SQL創建表的時候,dom
就體現在你的數據類型定義中:CREATE TABLE 學生 (學號 INT, -- 這就是一條 dom 規則姓名 VARCHAR(50), -- 這也是一條 dom 規則專業 VARCHAR(50) -- 這還是一條 dom 規則... );
所以,
dom
就是定義每一列數據類型的規則集合。
5. F: 數據依賴關系集合 (Set of Data Dependencies) - 【你的第二個困惑點】
-
學術定義:“數據依賴”描述了屬性之間存在的約束關系。
-
通俗解釋:
F
是這張表的“內在業務邏輯”或“隱藏規則”的集合。它說明了數據之間是如何相互關聯和制約的。最常見的依賴就是函數依賴。 -
例子:在我們的學生表中,存在以下這些“隱藏規則”:
- 只要
學號
確定了,那么姓名
、專業
、班主任
也就唯一確定了。- 這個規則在數學上記為:
學號 -> {姓名, 專業, 班主任}
。 - 這個規則正是“
學號
可以作為主碼”的根本原因!
- 這個規則在數學上記為:
- 只要
班主任
確定了,班主任電話
也就唯一確定了。- 這個規則在數學上記為:
班主任 -> 班主任電話
。 - 這個規則就是我們之前討論的“傳遞依賴”,它違反了第三范式(3NF)。
- 這個規則在數學上記為:
- 只要
-
它在實踐中是什么?
F
是數據庫主碼、外碼約束以及范式理論的數學基礎。我們設計數據庫時,通過分析業務邏輯,找出這些數據依賴(F),然后根據這些依賴來決定如何設置主碼、如何拆分表以滿足2NF、3NF等范式要求,從而設計出結構優良的數據庫。
從“精裝修”藍圖到“簡裝”藍圖
關系模式通常可以簡記作
R(A1, A2, ..., An)
- 解釋:上面那個
R(U, D, dom, F)
是給理論家看的“精裝修”藍圖,太復雜了。在日常工作中,我們用的是“簡裝”藍圖,也就是學生(學號, 姓名, 專業)
這種形式。 - 為什么可以簡化?
因為D
(類型池) 和dom
(接線圖) 的信息,已經包含在我們給每一列定義的數據類型里了(比如INT
,VARCHAR
)。而F
(內在規則) 則體現在我們設置的主碼、外碼和我們遵循的范式里。所以,簡化版已經足夠我們使用了。
總結一下
抽象概念 | 通俗解釋 | 實際對應 |
---|---|---|
關系模式 (Schema) | 數據表的“設計藍圖” | CREATE TABLE 語句 |
關系 (Relation) | 表里某一時刻的真實數據 | SELECT * FROM ... 的結果 |
U | 所有列的名字 | 學號 , 姓名 , … |
D | 用到的所有數據類型“池” | INT , VARCHAR , DATE 等 |
dom | “接線圖”,規定哪一列用哪種數據類型 | 學號 INT; 姓名 VARCHAR(50); |
F | “內在業務規則”,列與列之間的約束 | 主碼、外碼、函數依賴(范式的基礎) |
希望這個“藍圖”的比喻能幫你徹底理解 dom
和 F
的作用!它們一個是規定了“數據的靜態類型”,另一個是規定了“數據的動態約束”。