5

SQL Serverデータベースで、主キーの整数を持つ2つのテーブル間に多対多の関係を導入する必要があります。これはT-SQLでどのように最適に実行されますか?

多対多の関係が必要な次の2つのテーブル定義の例を検討してください。

CREATE TABLE [dbo].[Authors] (
    [Id]        INT            IDENTITY (1, 1) NOT NULL,
    CONSTRAINT [PK_Versions] PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[Books] (
    [Id]      INT           NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);
4

1 に答える 1

8

従来の方法は、many:many両方のテーブルにリンクする追加の(ジャンクション)テーブルを使用することです。

CREATE TABLE [dbo].[AuthorsBooks] (
    -- Optionally, we can give the table its own surrogate PK
    [Id]      INT IDENTITY(1,1) NOT NULL,
    AuthorId INT NOT NULL,
    BookId INT NOT NULL,

    -- Referential Integrity
    FOREIGN KEY(AuthorId) REFERENCES Authors(Id),
    FOREIGN KEY(BookId) REFERENCES Books(Id),

    -- PK is either the surrogate ...
    PRIMARY KEY CLUSTERED ([Id] ASC)
    -- ... Or the compound key
    -- PRIMARY KEY CLUSTERED (AuthorId, BookId)
);

重要な点の1つは、複合キーAuthorId, BookIdを主キーにするか、独自の新しいサロゲートを追加するかです。これは通常、主観的な好みです。

ジャンクションテーブルの複合主キーまたは新しい代理キーのどちらを使用するかを検討するためのいくつかのポイント:

  • サロゲートがない場合、ジャンクションテーブルにリンクする外部テーブルは両方の複合キーを格納する必要があります(つまり、両方AuthorIdBookId外部キーを保持する必要があります)。
  • したがって、新しいサロゲートは、より狭い主キーの潜在的な利点を提供します。これは、このジャンクションテーブルにリンクするすべてのテーブルが単一のより狭い外部キーを持つことを意味します。
  • ただし、複合キーを使用すると、最初にジャンクションテーブルに結合しなくても、テーブルを基になるテーブルBooksまたはテーブルに直接結合できるという最適化の利点があります。Authors

次の図は、複合キーの場合をより明確にすることを願っています(中央のテーブルNationalityはのジャンクションテーブルですPersonCountry)。

複合外部キー

編集

使用法は簡単です。リンクがmany:manyテーブルに存在する場合、関係は存在すると見なされます。存在をテストするには、リンクテーブルを介して「参加」します。

-- Find all books written by AuthorId 1234
SELECT b.* 
  FROM Books b 
  INNER JOIN AuthorsBooks ab
     ON b.Id = ab.BookId
  WHERE ab.AuthorId = 1234;
于 2012-12-20T11:00:12.690 に答える