4

「テーブルの作成」の文法では、クラスター化された外部キー制約を指定することはできません。言い換えれば、これは違法です:

--keyword CLUSTERED must be removed before this will execute...
CREATE TABLE [Content](
    [ID] [int] NOT NULL CONSTRAINT PK_Content_ID PRIMARY KEY,
    ContentDefID int NOT NULL CONSTRAINT FK_Plugin_ContentDef FOREIGN KEY CLUSTERED REFERENCES ContentDef(ID)
    )
GO

しかし、なぜそれが違法なのか理解できません。外部キーをクラスタリングすると、ページルックアップのパフォーマンスが向上するというISTM。つまり、「親ID20の子アイテム80から140をください」。

これには理由がありますか?

アップデート

OdedとTvanfossonのフィードバックに基づいて、次のことが機能することがわかりました。

CREATE TABLE [Content](
    [ID] [int] NOT NULL CONSTRAINT PK_Content_ID PRIMARY KEY,
    ContentDefID int NOT NULL UNIQUE CLUSTERED CONSTRAINT FK_ContentDefContent FOREIGN KEY REFERENCES ContentDef(ID)
    )
GO

しかし、上記はそれが解決するよりも多くの問題を引き起こします。まず、「UNIQUE」外部キーは、私の関係を私が望まない1対1にすることを強制します。次に、これは、単一のCLUSTERED FOREIGN KEYではなく、2つの別個の制約の作成を表すためにのみ機能します。

しかし、この調査は私を私の答えに近づけています。明らかに、ここでSOに記載されているように、クラスター化インデックスは一意である必要があります。引用:

クラスタ化インデックスが一意のインデックスでない場合、SQL Serverは、一意化子と呼ばれる内部で生成された値を追加することにより、重複するキーを一意にします

特に、この答えはそれをカバーしていると思います。

4

4 に答える 4

4

他の人が説明しているように、クラスター化インデックスは主キーである必要はありませんが、一意であるか、SQL-Serverが(表示されていない)UNIQUIFIER列を追加する必要があります。

これを回避するには、以下のように、主キー列をクラスター化インデックスに明示的に追加することで、クラスター化インデックスを一意にすることができます。その場合、インデックスは、外部キー制約によって(および、2つのテーブルを結合するなどのクエリに)使用されるavaialbelになります。

@Martin Smithが説明したように、との概念CONSTRAINTINDEX異なることに注意してください。そして、さまざまなDBMSがこれらをさまざまな方法で実装します。SQL-Serverは、外部キー制約ではなく、一部の制約のインデックスを自動的に作成します。ただし、制約で使用できるインデックスを用意することをお勧めします(参照されるテーブルで削除または更新する場合)。

CREATE TABLE Content(
    ID int NOT NULL,
    ContentDefID int NOT NULL,
    CONSTRAINT PK_Content_ID 
      PRIMARY KEY NONCLUSTERED (ID),
    CONSTRAINT CI_Content
      UNIQUE CLUSTERED (ContentDefID, ID),
    CONSTRAINT FK_Plugin_ContentDef 
      FOREIGN KEY (ContentDefID) REFERENCES ContentDef(ID)
) ;
于 2012-12-01T22:31:51.890 に答える
4

これには理由がありますか?

CLUSTEREDチェック制約またはCLUSTEREDデフォルト制約を作成できない理由を尋ねた方がよいかもしれません。

外部キーは単に論理制約を定義するだけであり、SQL Server で自動的に作成されるインデックスはありません (これはUNIQUEorPRIMARY KEY制約に対してのみ発生します)。SQL Server では常に、FK 列にインデックスを付けたい場合はCREATE INDEX、関連する列に対して自分で実行する必要があります。

したがって、 a の概念にはCLUSTERED FOREIGN KEY意味がありません。もちろんCLUSTERED INDEX、質問で示したように、FK を構成する列に を作成することもできます。

于 2012-12-02T10:10:52.147 に答える
2

1 つのテーブルにクラスター化インデックスを1 つだけ持つことができます。デフォルトでは、これが主キー列になります。

これを変更する方法があります- と を使用する必要がありPRIMARY KEY NONCLUSTEREDますUNIQUE CLUSTERED FOREIGN KEY

于 2012-12-01T20:44:39.593 に答える
0

クラスター化インデックスのアイデアをキー (プライマリまたは外部) と混同しているようです。テーブルを作成して、後でそのクラスター化インデックスを指定しないのはなぜですか? (コードは最初の例からコピーされ、可能な限り変更されていません)

CREATE TABLE [Content](
    [ID] [int] NOT NULL CONSTRAINT PK_Content_ID PRIMARY KEY NONCLUSTERED,
    ContentDefID int NOT NULL CONSTRAINT FK_Plugin_ContentDef FOREIGN KEY REFERENCES ContentDef(ID)
    )
GO

CREATE CLUSTERED INDEX IX_Content_Clustered on Content(ContentDefID)

クラスター化インデックスを一意にする必要はありません

于 2012-12-02T11:10:43.400 に答える