T-SQL基礎教程:關係模型

作者:Itzik Ben-Gan

圖書:http://item.jd.com/11362891.html


關係模型是基於集合理論和謂詞邏輯進行數據管理和操作的語義模型。如上所述,它是由Edgar F. Codd博士創建的,後來由Chris DateHugh Darwen等闡釋和發展。關係模型的第一個版本是於1969年由CoddIBM研究報告“Derivability, Redundancy, and Consistency of Relations Stored inLarge Data Banks(大型數據庫中關係模型存儲的可導、冗餘和一致性)”中提出的,修訂版本是由Codd1970年在一篇名爲“A Relational Model of Datafor Large Shared Data Banks(大型共享數據庫的數據關係模型)”的文章中提出的,發表在《美國計算機學會通訊》雜誌上。


關係模型的目標是確保數據的一致性表示,最小化或是沒有冗餘且不犧牲完整性,並將定義數據的完整性(強制數據一致性)作爲模型的一部分。RDBMS應假定實施關係模型並提供方法來存儲、管理、實施完整性和查詢數據。關係模型基於強壯的數學基礎的事實,意味着提供了一個可靠的數據模型實例(在後面將建立一個物理數據庫)。可以肯定地說,當某個設計存在缺陷時不應當是靠直覺。


關係模型涉及命題、謂詞、關係,元組和屬性等概念。對於非數學家,這些概念可能非常嚇人。下面幾節將以一種通俗的、非數學的方式討論模型中的一些關鍵方面,並解釋它們如何與數據庫進行關聯。


1.命題、謂詞和關係


普遍認爲“關係”術語源於表之間的關係,這是不正確的。“關係”實際上是數學術語的關係。在集合理論中,關係是集合的表現形式。在關係模型中,關係是相關的信息的集合,與SQL中相對應的就是一個表——儘管不能完全對應。關係模型中的一個關鍵點是,單個的關係應代表一個單個集合(如客戶)。值得注意的是,對多個關係操作(基於關係代數)的結果會是一個關係(例如,兩個關係之間的聯接)。


注意:關係模型分爲關係和關係變量,但爲了讓事情簡單,我不想引入這種區分;相反,我會使用兩種情況闡述關係。此外,關係是由表頭和主體組成。表頭包含一組屬性(SQL中稱之爲列),其中每個元素由一個屬性名稱和類型名稱標識。主體包含一個元組(SQL中稱之爲行)集合,其中每個元素都由鍵標識。爲了讓事情簡單,我會將表稱之爲行集。


當爲數據庫設計數據模型時,要使用關係(表)來表示所有數據。你首先要確定需要在數據庫中表示的命題。命題應當是一個斷言或必須爲“真”或“假”的語句。例如,語句“僱員Itzik Ben- Gan出生於1971212日,在IT部門工作”是一個命題,如果這是一個真命題,它將表現爲Employees(僱員)表中的一個行,如果是假命題則根本不會出現。這個假設被稱爲“封閉世界假設”(close world assumptionCWA)。


下一步是將命題形式化。爲此,你要取出實際數據(關係的主體)並定義結構(關係的表頭)——例如,創建命題的謂詞。你可以以參數化命題方式思考謂詞,關係的表頭包含一個屬性集合。注意術語“集合”的使用,在關係模型中屬性是無序且互異的。屬性由屬性名稱和類型名稱進行標識,例如,一個Employees(僱員)關係的表頭可能包含下列屬性(屬性名稱和類型名稱以成對方式出現):employeeid 整型、firstname 字符串型、lastname字符串型、birthdate 日期型、departmentid整型。


類型是關係最基本的構造塊,它約束了屬性是一個可能或有效值的確定集合。例如,INT類型是範圍自–2,147,483,6482,147,483,647所有整數的集合。類型是數據庫中謂詞的最簡單形式之一,因爲它限制了該屬性的允許值。例如,數據庫不會接受一個僱員的出生日期爲1971231日的命題(更不用提像“abc”這樣的生日)。 注意,類型不受像整型或字符串型等基本類型的限制,它也可以是可能值的枚舉,例如枚舉可能的工作崗位。類型是非常複雜的,或許最好方法將類型看作是一個類——封裝了支持它的數據和屬性。一個複雜類型的示例是:一個支持多邊形的幾何形狀類型。


2.缺失值


關係模型的一個方面是對於“是否謂詞應限制於二值邏輯”的激情辯論。也就是說,在二值謂詞邏輯中謂詞是“真”或“假”。如果謂詞不是“真”,那肯定是“假”。二值謂詞邏輯的使用遵循了一個名爲“排中律”的數學定律。不過,也有人說具有三值(甚至四值)謂詞邏輯空間,思考一下像缺失值的賬號情況。一個謂詞,涉及到缺失值則導致既不是“真”也不是“假”——它是未知的。 例如,一個Employees(僱員)關係的手機屬性,假設某些僱員的手機號碼丟失了,你怎麼把這一事實表示數據庫中?這要使用三值邏輯實現,手機屬性應當允許有一個代表缺失值的特定標記。然後,這種缺失值情況下,將該手機屬性與一些指定數字比較,謂詞也將產生未知。三值謂詞邏輯是指來自謂詞結果的三種可能邏輯值──“真”、“假”和“未知”(truefalseunknown)。


有些人認爲三值謂詞邏輯是非關係的,而有些人認爲這是關係。Codd實際上主張四值謂詞邏輯,提出缺失值有兩種不同情況:缺失但可用(A-Mark)和缺失但不可用(I-Mark)。例如,“缺失但可用”是僱員擁有手機,但是你不知道是什麼號碼;“缺失但不可用”是僱員根本就沒有手機。根據Codd的主張,應當有兩個特定標記來支持這兩種缺失值情況。SQL通過支持NULL標記實現了三值謂詞邏輯,以表示缺失值的通用概念。SQL中對NULL和三值謂詞邏輯的支持是造成極大混亂和複雜性的根源,儘管人們認爲缺少的值是現實的一部分。此外,另一個選擇是僅使用二值謂詞邏輯,這是不會造成問題的。


3.約束


關係模型的最大好處是能夠把定義數據的完整性作爲模型的一部分。數據完整性通過在數據模型中定義的約束規則實現,並由RDBMS實施。實施完整性的最簡單方式是指定屬性類型的nullability(是否支持或不支持NULL標記)標誌。約束也可以通過模型自身實施,例如,關係Orders(orderid, orderdate, duedate,shipdate) 中每筆訂單有3個互異日期,而關係Employees(empid) EmployeeChildren(empid,childname)允許每個僱員有0至可數的無窮個子級。


約束的其他例子還包括提供實體完整性的候選鍵和提供引用完整性的外鍵。候選鍵是定義了一個或多個屬性的鍵,防止關係中出現多個相同的元組(SQL中的行),基於候選鍵的謂詞可以唯一地標識行(如僱員)。你可以在關係中定義多個候選鍵,例如,在Employees關係中,可以在employeeidSSN(社會安全號碼)等屬性上定義候選鍵。通常,你可以任意選擇一個候選鍵作爲主鍵(例如,Employees關係中的employeeid),並作爲標識行的首選方式。所有其他候選鍵稱爲備用鍵。


外鍵用於強制引用完整性。外鍵定義了關係的一個或多個屬性(稱爲引用關係)引用另一個關係(或同一關係)的候選鍵,此約束限定了引用關係的外鍵屬性中的值,應是出現在被引用關係(父表)的候選鍵屬性中的值。例如,假設Employees關係具有一個定義在departmentid屬性上的外鍵,它引用Departments關係中的主鍵屬性departmentid,這意味着Employees.departmentid中的值僅限於出現在Departments.departmentid中的值。


4.規範化


關係模型還定義了規範化規則(也稱爲範式)。規範化是一個常規的數學過程,用於確保每個實體都由單一關係表示。在規範化的數據庫中,要在數據修改過程中避免異常,並不犧牲完整性的情況下保持最低限度冗餘。如果按照實體關係模型(Entity Relationship ModelingERM)來表示每個實體及其屬性,你可能不需要規範化;相反,你應使用規範化來鞏固和確保模型是正確的。以下各節簡要將介紹一下由Codd提出的前三個範式(1NF2NF3NF)。


11NF


第一範式是說關係(表)中的元組(行)必須是唯一的,並且屬性是原子化的。這是一個關係的冗長定義,換句話說,如果表正確地表示了關係,它已經符合了第一範式。


通過爲表定義一個唯一鍵就可以實現唯一行。


你僅能執行屬性類型所定義部分的操作,屬性的原子性是主觀的,這與集合的定義是主觀的一樣。例如,Employees關係中僱員姓名應當使用一個(fullname)、兩個(firstnamelastname)還是三個(firstnamemiddlenamelastname)屬性表示呢?答案取決於應用程序。如果應用程序需要分別處理僱員的姓名部分(如處於搜索目的),則有必要把它們分開,否則,則不需要。


同樣的,基於應用程序需求,屬性可能不被完全原子化,也有可能被亞原子化。例如,如果地址屬性被作爲一個特定應用程序的原子,不將“城市”作爲地址的一部分會違反第一範式。


這個範式經常被誤解,有人認爲試圖模仿數組會違反第一範式。例如,定義的YearlySales關係具有以下屬性:salespersonqty2010qty2011qty2012。但在本示例中,你不會真的違反第一範式,你只需施加一個約束──將數據限制爲特定的三年:201020112012


22NF


第二範式涉及兩個規則。一個規則是數據必須滿足第一範式,另一個規則提及非鍵屬性和候選鍵屬性之間的關係。對於每個候選鍵,每個非鍵屬性必須是對整個候選鍵的完全函數依賴。換言之,非鍵屬性不能是對候選鍵某部分的完全函數依賴。更加口語化的,如果你要獲取任何非鍵屬性值,你需要提供相同元組中候選鍵的所有屬性的值;如果你知道候選鍵的所有屬性的值,你就可以檢索到任何元組的任何屬性的任何值。


下面是一個違反第二範式的例子,假設你定義了一個名爲Orders的關係,表示訂單和訂單行的信息,如圖1-1所示。Orders關係包含下列屬性:orderidproductid orderdateqtycustomeridcompanyname。主鍵定義爲orderidproductid


1-1 符合2NF之前的數據模型


1-1中違反了第二範式,因爲有非鍵屬性僅依賴於候選鍵(即該示例的主鍵)的一部分。例如,你可以僅通過orderid找到訂單的orderdate,以及customeridcompanyname。要符合第二範式,你需要將原來的關係拆分爲兩個關係:OrdersOrderDetails,如圖1-2所示。Orders關係將包括orderidorderdatecustomeridcompanyname屬性,主鍵定義爲orderidOrderDetails關係將包括orderidproductidqty,主鍵定義爲orderidproductid


1-2 3NF之前符合2NF的數據模型


33NF


第三範式也有兩個規則。數據必須滿足第二範式,同時,所有非鍵屬性必須依賴於非傳遞的候選鍵。通俗的講,該規則的意思是所有非鍵屬性必須相互獨立。換句話說,一個非鍵屬性不能依賴於另一個非鍵屬性。


先前所述的OrdersOrderDetails關係現在已經符合第二範式。請記住,此時的Orders關係包含orderidorderdatecustomeridcompanyname屬性,主鍵定義爲orderidcustomeridcompanyname均依賴於整個主鍵──orderid。例如,你需要整個主鍵來查找代表訂單中客戶的customerid,同樣,你需要整個主鍵查找訂單中客戶的公司名稱。然而,customeridcompanyname也是互相依靠的。爲滿足第三範式,你需要添加包含customerid(作爲主鍵)和companynameCustomers關係,如圖1-3所示,然後你就可以從Orders關係中刪除companyname屬性。


1-3 符合3NF後的數據模型


通俗的講,2NF3NF通常以這句話概括:“每個非鍵屬性依賴於鍵,依賴於整個鍵,並且除了鍵別無他物──Codd幫助作證此話”。


還有比Codd首創的前三個範式更高的範式,涉及複雜的主鍵和瞬時數據庫,但這些超出了本書的範圍。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章