2010-03-26 53 views
14

使用一對一表關係而不是簡單地將所有數據存儲在一個表中的優點是什麼?我理解並使用一對多,多對一和多對多的方式,但實現一對一關係似乎是一項單調乏味且不必要的任務,特別是如果您使用命名關聯(php)對象到數據庫表的約定。使用一對一表關係的優點是什麼? (MySQL)

我無法在網絡或本網站上找到任何可以提供一對一關係的真實世界示例。起初我認爲將用戶分成兩個表格是合乎邏輯的,例如,將兩個表格分開,其中一個包含像關於我的個人資料頁面的公共信息,另一個包含諸如登錄/密碼等私人信息。但是爲什麼要去通過使用不必要的JOINS的所有麻煩,只要選擇哪個字段可以從該表中選擇呢?如果我顯示用戶的個人資料頁面,顯然我只會選擇ID,用戶名,電子郵件,aboutme等,而不是包含他們的私人信息的字段。

任何人都在意用一些一對一關係的實際例子來啓發我嗎?

回答

6

我已經使用一對一的關係來擴展現有應用程序中的某些功能,而不會影響應用程序數據庫結構。這是擴展現有數據庫表的一種不顯眼的方式。

使用一對一關係的另一個原因是實現類表繼承,其中層次結構中的每個類都有一個表,並且一個對象在其父類中的表類中具有對應的行表,在他的祖父母課堂表等等。

見,例如,學說2 Class Table Inheritance Page

+1

-1表示在關係數據庫中使用裝飾器模式是一個好主意。 – symcbean 2010-03-26 12:21:16

+5

是的,我的意思是在byronh給出的意義上延伸。但是,我沒有說這是一個好主意,我只是說它可能是一個原因。如果一件事情是好的,它也取決於上下文。有時我不想要,我也不能更改第三方數據庫,所以我用一對一的關係「擴展」那個表 – 2010-03-26 22:08:47

+0

是的,還要注意ALTER TABLE在大數據行(數千行)表中添加一列,可能需要很多時間(小時)。與此同時,桌子被鎖定,系統管理員可能在夜間醒來...... – Qlimax 2015-07-21 12:42:13

9

一種可能的用途是部分信息是可選的。這樣,您不需要在一個大表中包含一堆可空的字段,但可以將其邏輯分隔爲強制表和可選表。

其他用途是當某些數據與不同的表共享時。例如,假設您有一個銷售電腦零件的網站。你可以把所有組件共享的細節放到例如。 「零件」表,但將具體細節放在「主板」,「cpus」等中,這些只是使用具有一對一關係的零件表。

1

即使只有一部分字段正在被讀取,數據庫引擎可能不得不將整行加載到內存中以便從中獲取數據。每行更少的字段意味着每頁更多的行,這意味着更少的磁盤訪問。

+0

如果您使用正確的數據庫引擎,並且明智地編寫了sql和索引,則不應該如此。 – Whakkee 2010-03-26 08:11:25

+0

如果您使用MySQL(MyISAM/InnoDB),則除了僅用於鍵的SELECT之外,其他任何性能都會受到影響。表空間越大,獲取請求的數據所需的內存就越多。同時更新性能會受到重創。 – Jacco 2010-03-26 11:41:52

6

這裏的二,我相信其他人會發布更多

  • 要在不實際修改表擴展現有的表。也許它是由第三方供應商提供的,並且您希望通過簡單地擁有共享相同密鑰的第二個表來分隔您的擴展。
  • 也許在表中有固定寬度的列經常被訪問,而可變的列則不是。在這種情況下,對於頻繁的東西,有一個固定行長的表可能會提高效率,其他所有的次表都會有效率提高。

此外,規範數據庫時,說3rd Normal Form (3NF)你可能會發現你有哪些是不是真的「約」的關鍵,需要拉出一個單獨的表列。

0

當我們需要用too many fields(96場!)擴展我們的一個表時,我們使用了「一對一關係」。所以,我們創建了另一個表格並將每個新的字段放在裏面。

無論如何,這種方法我喜歡的是:

Table_Base: 
    ID 
    MANDATORY_FIELD 
Table_Option: 
    ID 
    OPTIONAL_FIELD 
5

專門爲您例如: 你不希望像存儲在同一個表作爲登錄名和密碼信息的姓名和地址的用戶信息,因爲這您可以授予組織中的某人對用戶信息表的權限,而不是登錄數據表中的權限。我不同意其他人關於「一桌一桌」的主題。如果有許多字段,並且在表單或報表中不需要它們,則可以使用sql選擇所需的字段,甚至可以使用視圖來確保不會獲得太多的數據。

+0

您也可以授予對特定列而不是整個表的訪問權限。但是表格(不僅僅是單元格)會帶來性能問題。如果不選擇所有字段,表空間仍然必須加載到內存中;這與意見沒有什麼不同。這條規則的唯一例外是如果可以直接從鍵索引中檢索請求的數據。 – Jacco 2010-03-26 13:59:23

1

在OO中你有繼承。因此,您可以擁有一個包含父對象數據的表格,以及其他包含特定於子項的字段的表格。

4

最常見的原因是,這種關係可以是非強制性的。即存在適用於每個基本實體的一組屬性,但是僅適用於子集的一些屬性。

這樣做的另一個有效原因是控制訪問權限 - 您可能會在整個應用程序中使用一張客戶表,儘管每個客戶都有密碼和信用卡,但您可能希望限制可見性/更新權限。

Marga Keuvelaar對Ignacio Vazquez-Abrams的評論回答是錯誤的。您可以使用更好的DML/DDL緩解影響,但不是在所有情況下。但是,您需要對數據模型的透明度與性能優勢進行權衡 - 這需要經過仔細考慮。

C.

+0

此答案中引用的評論現在已消失。 – Cypher 2014-04-08 00:22:31

0

除了已經取得的說,

一些列可能會比其他人不同的「安全審查」的要求。例如。一名僱員的名字可能比他的薪水「更公開一些」。現在,數據庫管理系統通常不強制使用列級別的安全性,但通常會使用表級別的安全性。

因此,通過在單獨的表格中挑出工資,您只需使用DBMS的安全設施即可爲自己購買實現用戶安全需求的可能性。根據我的經驗

0

一件事還沒有被提及:

分成兩個表也有助於創建模型類。假設你有Customers表和DriverLicense表和它們之間的一對一關係。如果您使用實體框架,我敢打賭,如果您有兩個單獨的表格,應該會更好,因爲您的應用程序中可能有兩個模型類,即Customer類和DriverLicense。通過這種方式,實體框架可以很容易地將一個新的驅動程序許可證信息稍後添加到現有客戶,或刪除和更新它。簡而言之,考慮到Web開發方面,我認爲如果它們是兩個不同的實體,即使它們具有一對一的關係,它們也應該有自己的表。