2013-03-05 63 views
5

首先讓我說我正在使用MySQL(不是事務),並且這是不能改變的。此外,爲簡潔明瞭起見,我在此簡化了表格。如何解決三向多態關聯?

在本例中,「課程」由它的內部屬性和外部屬性組成,並帶有屬性'Readings'。 「閱讀」有它自己的關鍵依賴屬性和三個不同的外部屬性(閱讀來源)。

我想避免在這裏出現的多態關聯,但我無法將其包裹在它周圍。在此示例中,'Reading'表中的'sourceId'將包含來自三個表「ExternalURL」,「InternalURL」和「Book」之一的ID。此外,字段「polytable」將包含上述「id」來自的表名稱。

有人可以花一點時間來解釋如何解決這個維護RI還是有可能爲了效率的利益,它應該留下?

謝謝您的時間和考慮,

     ------------- 
         | ExternalURL | 
         ------------- 
         | id   | 
         | badlink  | 
         | url   | 
         |    | 
         |    | 
         ------------- 
          | 
          | 
          | 
         /\ 
------------   -------------   ------------- 
| Lesson  |-------<| Reading  |>-------| InternalURL | 
------------   -------------   ------------- 
| id   |  | id   |  | id   | 
| label  |  | lessonId |  | url   | 
| summary |  | sourceId |  |    | 
| lessonOrder|  | polytable |  |    | 
| active  |  | label  |  |    | 
------------   -------------   ------------- 
          \/
          | 
          | 
         ------------ 
         | Book  | 
         ------------ 
         | id   | 
         | label  | 
         | summary | 
         | lessonOrder| 
         | active  | 
         ------------ 

回答

7

您至少有幾個選項來保存RI:

  1. 添加幾個可爲空FK列Reading ,每種閱讀類型一個。其中只有一個應該是非空的。

    CREATE TABLE Reading (
        id INT AUTO_INCREMENT PRIMARY KEY, 
        lessonId INT NOT NULL, 
        bookId INT NULL, 
        externalUrlId INT NULL, 
        internalUrlId INT NULL, 
        FOREIGN KEY (bookId) REFERENCES Book(id), 
        FOREIGN KEY (externalUrlId) REFERENCES ExternalUrl(id), 
        FOREIGN KEY (internalUrlId) REFERENCES InternalUrl(id) 
    ); 
    

    強制執行外鍵列的恰好是一個非空是一個trigger任務,否則你就必須這樣做,在應用程序代碼。但至少你可以定義外鍵。

  2. 添加一個超類型Readable,它是每個其他特定可讀類型的父親。

    CREATE TABLE Readable (
        id INT AUTO_INCREMENT PRIMARY KEY, 
        readable_type CHAR(1) NOT NULL, 
        UNIQUE KEY (id, readable_type) 
    ); 
    
    CREATE TABLE Book (
        id INT PRIMARY KEY, -- not AUTO_INCREMENT 
        readable_type CHAR(1) NOT NULL, -- must be 'B' 
        FOREIGN KEY (id, readable_type) REFERENCES Readable(id, readable_type) 
    ); 
    
    ... similar tables for ExternalUrl and InternalUrl... 
    

    然後使閱讀也引用可讀。

    CREATE TABLE Reading (
        id INT AUTO_INCREMENT PRIMARY KEY, 
        lessonId INT NOT NULL, 
        sourceId INT NOT NULL, 
        FOREIGN KEY (sourceId) REFERENCES Readable(id) 
    ); 
    

    我在我對Why can you not have a foreign key in a polymorphic association?的回答中更詳細地描述了這個解決方案。

+0

嗨比爾,首先讓我感謝您的及時回覆。其次,我不明白選項二,但它看起來像自我強制RI不同於第一種,我認爲你需要用程序邏輯來支持它,以確保只有一個不爲空。給我打電話吧。 'Readable'表中的'readable_type'是否包含書'B','I'是內部,'E'是否包含外部?爲什麼Book的主鍵不能自動增量?如何添加特定類型的新閱讀?我知道你很忙,但如果你可以提供進一步的解釋,我將如何以及爲什麼我會非常感激。謝謝。 – mpactMEDIA 2013-03-05 00:42:39

+0

我已經添加了一個鏈接到我寫的過去的答案,其中我詳細介紹瞭解決方案#2。 – 2013-03-05 02:46:03

+0

謝謝比爾非常感謝。 – mpactMEDIA 2013-03-05 03:47:17