關系模型介紹
《數據庫系統概念》第二章
關系數據庫的結構
如上是教師表和課程表,教師表通過ID列標識一個教師信息,而課程表通過course_id
列標識一個課程信息。
第三個表是先修課程信息,course_id
和prereq_id
唯一標識了一條兩門課之間的聯系,代表prereq_id
所代表的課程是course_id
所代表課程的先修課。
而instructor
表中的一行也可以看作是ID
到(name, dept_name, salary)
之間的聯系。
所以表中的一行就代表一個聯系,表和數學中的關系密切相關,而數學中的元組代表具有n個組值的序列,可以看作數據庫中的一行。
所以在關系模型的術語中,關系(relation)用來指代表,元組(tuple)用來指代行,屬性(attribute)用來指定列。
關系實例是一個關系的特定實例,包含一組特定行,如instructor
中的十二行就是instructor
關系的一個實例。
域是屬性的可取值的集合,salary
屬性的域就是所有可能取值的工資的集合。
要求對於關系r,域中所有屬性都是原子的,即不能再分。比如教師表中通過phone_number
屬性存儲教師的一組手機號,那么就不是原子的。這和你如何使用數據庫中的數據有關,假設你把電話號碼拆分為國家編號+地區編號+本地號碼,那么即使你只存儲一個手機號,那么也不是原子的。
數據庫模式
關系模式是由一組關系中的屬性和對應的域組成。注意關系模式不會經常更改,而上面提到的關系實例則會經常更改。
如下是department
關系,它的關系模式如下
department (dept_name, building, budget)
department
中的第一個列dept_name
在instructor
中也出現過,關系模式中使用相同屬性來將不同關系中的元組聯系起來。比如你想找在Watson
樓辦公的所有教師,那么需要先在department
表中找到Watson
樓的所有部門名稱,然后再去instructor
中按照剛剛找到的dept_name
搜索所有屬於這個部門的教師。
下面的一個關系用來描述大學中一門課上課的時間段,教室等信息。大學中的一門課可能跨越不同的學期和時間段。
關系如下:
section (course_id, sec_id, semester, year, building, room_number, time_slot_id)
下面是老師和它教授的課程之間的關系
關系如下:
teaches (ID, course_id, sec_id, semester, year)
碼
一些屬性,如果能區分關系中不同的元組,那么就稱作這些屬性為“超碼”(super key),關系中存在完全相同的兩個屬性沒有意義。
例如instructor
中的ID
屬性可以作為一個超碼,而name屬性不能,因為教師可能重名。
考慮一個問題,ID
屬性可以作為唯一標識一個instructor
中的元組的超碼,那么ID
+NAME
的組合也可以作為超碼。我們通常感興趣的超碼是它的任何真子集都不能作為一個獨立超碼的超碼,也就是不能夠再分了,這樣的超碼叫做候選碼(candidate key)。
主碼是候選碼中的一個,被數據庫設計者選中,用來區分關系中不同元組的碼。
如果一個關系\(r_1\)中有一個屬性\(a\)存儲了\(r_2\)的主碼,這個屬性\(a\)稱為關系\(r_1\)的外碼(foreign key),\(r_1\)是外碼\(a\)的參照關系(referencing relation),\(r_2\)是外碼\(a\)的被參照關系(referenced relation)。
比如instructor
表中的dept_name
屬性就是關系department
的一個外碼。無論何時,instructor
中的一個元組\(t_1\)必定能在department
中找到一個元組\(t_2\),使得它們的dept_name
屬性相同。
對於之前的section
和teaches
,如果我們通過外碼聯系兩個關系,那么要保證,如果一個特定的(course_id, sec_id, semester, year)
存在於section
,那么它必定存在於teaches
,這組值並不能構成teaches
的主碼,因為可能一個課程段不只有一個老師進行授課,所以不能聲明從section
到teaches
的外碼約束,但可以聲明從teaches
到section
的外碼約束。