Database-Design

第一範式:明確定義

  • June 15, 2021

我正在嘗試獲得第一範式的最終版本。我讀到的所有東西都有一個稍微不同的旋轉。

許多權威,例如 Date,說根據定義,關係總是處於第一範式,而其他權威則給出了要求的列表。這意味著對 1NF 有從零到許多的要求。

我想區別在於表和關係之間的區別:表可能是一團糟,而關係則遵循一定的限制。因此,關係在 SQL 中表示為表的事實造成了一些混亂。

我特別關注與 SQL 數據庫相關的 1NF。問題是:需要哪些屬性來確保表處於第一範式?


許多權威人士建議,如果一個表代表一個關係,那麼它已經在 1NF 中。這將 1NF 的定義推回到關係的定義。

以下是 1NF 中表的一些屬性:

  • 列順序無關緊要$$ 1 $$
  • 行順序無關緊要
  • 所有行的長度相同(即行數據與列標題匹配)
  • 沒有重複的行(這可以使用代理主鍵來保證,但 PK 本身不是必需的)
  • 沒有重複的列
  • 每列包含一個(原子)

$$ 1 $$從技術上講,屬性是無序的,但在表中,行數據必須與列標題的順序相同。但是,實際的順序是微不足道的。 在多個數據上:

原子數據的概念是一個項目不能被進一步分解。這個概念已經得到了限定,儘管從技術上講,一切都可以分解,但實際上不能進一步分解有問題的數據,具體取決於數據的使用方式。

例如,一個完整的地址或全名通常應該被進一步分解,但像給定名稱或城鎮名稱這樣的組成部分可能不應該被進一步分解,儘管它們可以是字元串。

至於重複列,幾乎重複的列,如等phone1,是一個糟糕的設計列phone2。一般來說,重複的數據表明需要額外的相關表。

依賴

行之間不應該有任何關係,除非它們符合相同的標題。

列之間也應該沒有關係,但我相信這是更高範式的主題。

問題是:以上有多少是在 1NF 的定義中?獨立行位是否也包含在內?

初步的

範式的定義(從 1971 年“數據庫關係模型的進一步規範化”的介紹中被稱為第一範式)和關係範式本身定義發表在 1970 年的科學論文中,提供了強有力的數據庫管理實踐的基礎,即“大型共享數據庫的數據關係模型”(簡稱 RM),由圖靈獎獲得者和關係框架方面的權威EF Codd 博士創建。

是的,對Codd博士的文字有很多解釋,解釋,闡述,偏差和意見,但我個人更喜歡堅持原始來源,我強烈建議您自己分析它,以便得出自己的結論。

我當然不完全理解 RM,但我對它的理解使我能夠欣賞它的卓越、遠見、意圖和範圍,儘管幾十年後人們可以注意到它有一些輕微的不精確,但它們並沒有減少,無論如何,它的天才和優雅。在其領域,RM 以獨特的方式經受住了時間的考驗,並且仍然無與倫比。

強調上述不精確的行為將是不公平的——使用慈善術語——因為從相當遠的距離來看,這種開創性的材料需要一些改進和擴展,是的,但作品的主體是堅如磐石的非常概念(事實上,科德博士自己做出了大部分(如果不是全部)這樣的改進和擴展)。

我繼續不斷地重讀 RM,以加強我對這一特殊知識來源的理解(並且我對它的尊重在每次重讀時都在增長);目標是站在巨人的肩膀上。

關係和表格

值得注意的是,由於關係是抽象資源,Codd 博士設想了以表格形式表示它們的效用(他最初使用術語“數組表示”,但後來使用“表”或“r-table”),因此關係數據庫 (RDB) 的使用者、設計人員和管理員可以以更熟悉或更具體的方式接近他們。因此,在 RDB 實現的上下文中,使用table作為關係的簡寫是有效的,只要所述表代表實際關係。這個特性——雖然很明顯——非常重要,因為在評估一個表是否表示一個符合第一範式 (1NF) 的關係之前,它必須準確地表示一個關係。

RM 自然包含一個表必須具備的品質,以確定它是否真的描繪了一種關係,但我將在這裡提供一個非正式且樸實無華的解釋(另一個,是的!):

  • 它必須有一個名稱(數據庫結構中的每個特定關係都必須與其他關係區分開來)。
  • 它的每一必須準確地描述相關關係的一個元組。
  • 它的行順序根本不重要。
  • 它的每一列必須有一個名稱,該名稱代表相關關係的一個****域的含義,並且該名稱必須與表的其餘列的名稱不同(列必須唯一區分並且必須攜帶一個獨特的意義,是的,數據庫建模師和業務專家在準確定義每個重要領域所扮演的角色是最重要的)
  • 其列的順序沒有意義。
  • 它的所有行必須具有相同的列數。
  • 它必須具有至少一列或一列組合,以唯一標識通過行描述的每一個元組;這樣,所有的行都必須不同(是的,這強調了聲明至少一個 KEY 的重要性,並且當有兩個或多個 KEY 時,應根據實際原因將一個定義為 PRIMARY,而其餘的可以被視為 ALTERNATE;但是是的,在做出決定之前,每個 KEY 都是定義為 PRIMARY 的“候選者”)。

擁有一個實際上代表關係的表是至關重要的,因為當它經歷關係類型的操作操作時,結果又是一個代表關係的表。以這種方式,所述表的行為是可預測的。

原子域(列)

在 RM 的第一部分,Codd 博士展示了幾個關係範例,以介紹一些概念;因此,為了理解atomic domain的含義,讓我們從 RM 的以下摘錄開始,其中詳細介紹了一些相關點:

到目前為止,我們已經討論了在簡單域(其元素是原子(不可分解)值的域)上定義的關係範例。可以在關係框架內討論非原子值。因此,某些域可能具有作為元素的關係。反過來,這些關係可以在非簡單域上定義,等等。

這樣,可以說上述每個說明性關係都適合兩種類型中的一種,即類型 A類型 B

  • A類僅對由域(列)構成的關係(表)進行分組,這些域(列)在其每個元組(行)中僅包含簡單值,即,此類域(列)不包含作為值的關係(表),在這個上下文意味著這些值是原子的,因為它們不能連續分解成新的關係(表)。因此,這個類的關係是正規化的,即它們符合1NF,它們的形式是可取的。
  • 類型 B完全由具有一個或多個域(列)的關係(表)集成,這些域(列)將關係保存為每個相應元組(行)中的值,這表示所述值是非原子的,因為它們隨後可以分解為新的關係(表),即它們是可分解的。因此,這種關係是非規範化的,即它們違反了 1NF,它們是一種不受歡迎的形式。

正常化

Codd 博士通過以下段落介紹了 RM 中關於標準化的部分:

域都是簡單的關係可以在儲存中由上述類型的二維列齊次數組表示。與一個或多個非簡單域的關係需要一些更複雜的資料結構。出於這個原因(以及下面引用的其他原因),消除非簡單域的可能性似乎值得研究!事實上,有一個非常簡單的消除過程,我們稱之為正規化。

然後他繼續展示:

  1. 一組關係,其中一個是非規範化的(它具有包含作為值的關係的域,即它們是非原子的;即它們是非簡單的)
  2. 一組正規化的關係(即,已分解的關係;即,關係重視域的關係被分解為簡單的關係,這表示它們是原子的)

然後他描述了從非規範化關係中獲得規範化關係的過程。

在這方面,他用來說明規範化練習的關係和練習描述本身非常清楚,我再次建議你自己分析它們(我也希望這能鼓勵一些讀者參與到文本中)。

隨後,他指出:

正規化類型的進一步操作是可能的。這些不在本文中討論。

而上述操作,即第二範式和第三範式(2NF和3NF)其實在《數據庫關係模型的進一步規範化》中有詳細介紹,如前所述,在本文​​介紹(以及後來的印刷出版)之後,原來的範式被稱為第一範式。

正如從業者可以觀察到的,具有非規範化的關係(表)會在 RDB 實現中引入(幾乎總是不必要的)卷積。

正如 Codd 博士在以下幾行中指出的那樣,滿足 1NF 的關係簡化了約束和數據操作操作的定義,這些操作可以通過比非規範化關係(表)所需的數據子語言更簡單的數據子語言來實現:

如上所述,採用數據的關係模型允許開發基於應用謂詞演算的通用數據子語言。如果關係的集合是范式的,則一階謂詞演算就足夠了。這種語言將為所有其他提議的數據語言提供語言能力的衡量標準,並且本身將成為嵌入(通過適當的句法修改)到各種宿主語言(程式、命令或問題導向)中的有力候選者。

$$ … $$ $$ … $$ 數據子語言的普遍性在於它的描述能力(而不是它的計算能力)。

困惑

在我看來,困惑已經出現,原因是(a)前面提到的關於 1NF 和 RM 本身的過度解釋、解釋等,以及因為(b)進一步嘗試重新定義1NF 狀態,即存在關係域的值反過來,只要它們是每個對應元組的一個值,關係就符合1NF。

我對你的其他觀點的看法

行之間不應該有任何關係,除非它們符合相同的標題。

我不確定我是否正確理解了該語句的意圖,但是除了符合相同的標題之外,關係(表)的(元組)行之間必須存在連接,因為它們中的每一個都應該是關於關係(表)應該表示的特定實體類型(根據感興趣的業務上下文定義)的特定出現。

列之間也應該沒有關係,但我相信這是更高範式的主題。

我也不知道我是否正確解釋了該語句的含義,但事實上,根據我對前一個方面的回答,關係(表)的域(列)之間也必須存在關係,這正是它是關係的原因(****關係模型和具體 RDB 實現的基本結構)。

舉例來說,關於假設關係(表)

  • Salary (*PersonNumber*, *EffectiveDate*, Amount)

元組(行)

  • Salary (x, y, z)

會傳達意思

  • The Salary payed to the Person identified by PersonNumber *x*, on EffectiveDate *y* corresponds to the Amount of *z*

因此,關係(表)的每個元組(行)都Salary必須符合上述斷言的結構,不同之處在於相關域(列)值的替換,但(a)之間必須存在關係所有Salary域(列)以及(b)關於每個元組(行)的所有對應值;這樣的關係是不可缺少的。

更高的範式(2NF 和 3NF)對於擺脫關係(表)的域(列)之間的函式依賴關係很有用,它們有助於避免域(列)之間的不需要的 連接,因為所述不需要的連接允許引入更新異常. 2NF 和 3NF 都有助於測試某個 RDB 實現中關係(表)結構的健全性。

插圖。取一個包含典型美國地址的文本字元串:

"123 Cornhusk Rd., South Succotash, NY 12345"

編寫查詢以查找 Cornhusk Road 的所有居民或 South Succotash 鎮或紐約州的特定居民將是一項艱鉅的任務。特別是當您在數據中有以下字元串時:

"123 Cornhusk Road, South Succotash, NY 12345"
"123 Cornhusk Rd., South Succotash, New York 12345"
"123 Cornhusk, South Succotash, NY 12345"
"123 Cornhusk Rd., SOUTH SUCCOTASH, NY 12345"

這些中的每一個都指定了相同的實際地址(這甚至不考慮可能的拼寫錯誤,例如“Succatash”),但編寫算法來成功比較它們是我不想將我在地球上的最後幾年奉獻給做的事情。

輸入第一範式。我不會詳細介紹它是如何完成的,只考慮在大多數數據庫中看到的常見形式:

create table Addresses(
 ...
 Street  varchar,
 City    int        references Cities( ID ),
 State   char( 2 )  references States( ID ),
 Zip     int
 ...
);

這不是一個完整的規範化。例如,您可以將 Street 進一步劃分為 StreetNum 和 StreetName,但這對於一個簡單的說明來說已經足夠了,它實際上與現實生活中的規範化過程差不多。找到 Cornhusk Road 的所有居民仍然存在一個小問題,但是如果您在 Street 中搜尋子字元串“Cornhusk”,並且恰好在某個地方有一個名為 Cornhusk 的城鎮,至少不會引起混淆。

Date 等人提供的定義的問題在於,他們未能查看一段數據並考慮該數據的含義。並不是我特別責怪他們,這可能非常困難。

所以我們必須把一個“字元串”變成一個“地址”。但想出一個包羅萬象的地址定義並不像看起來那麼簡單。尤其是在處理多個國家/地區的地址時。

首先,我們修復上下文。沒有上下文,任何事情都沒有意義。我們這裡的上下文是address。在這種情況下,我們可以看到具有特定含義的部分數據,例如StreetCity等。我們為每個含義分配一個單獨的欄位。

困難的部分是數據,就像單詞一樣,對不同的人可能有不同的含義,或者有些人可以看到其他人看不到的含義。它可以是一個單獨的項目,需要大量的合作努力。但它是良好數據庫設計的關鍵要素。

正規化的目的是消除或至少最小化異常數據。考慮一個事實,在上表中,可能輸入的城鎮或郵政編碼在所選州中不存在。或者輸入的街道實際上並不存在於所選城鎮中。啊,但是現在我們進入第二和第三範式,這是另一個話題。

引用自:https://dba.stackexchange.com/questions/161119