5

まず、MySQL(トランザクションではない)を使用していて、これを変更できないとしましょう。また、簡潔さと明確さのために、ここでは表を簡略化しました。

この例では、「レッスン」は、その内部属性と、それ自体の属性「読み取り値」を持つ外部属性で構成されています。「リーディング」には、独自のキー依存属性と3つの異なる外部属性(リーディングソース)があります。

ここに到着するポリモーフィックな関連性を避けたいのですが、頭を包み込むことができません。この例では、テーブル「Reading」の「sourceId」には、「ExternalURL」、「InternalURL」、「Book」の3つのテーブルのいずれかからの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     |
                       ------------ 
4

1 に答える 1

8

RIを維持するためのオプションが少なくとも2つあります。

  1. Reading読み取りタイプごとに1つずつ、いくつかのnull許容FK列をに追加します。これらのうちの1つだけがnull以外である必要があります。

    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)
    );
    

    外部キー列の1つだけがnull以外であることを強制することは、トリガーのタスクです。そうでない場合は、アプリケーションコードで実行する必要があります。ただし、少なくとも外部キーを定義することはできます。

  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...
    

    次に、ReadingもReadableを参照するようにします。

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

    このソリューションについては、ポリモーフィックな関連付けで外部キーを使用できない理由についての回答で詳しく説明します。。

于 2013-03-05T00:21:45.923 に答える