57

と呼ばれるテーブルがあり、SQL Server 2008 R2で「一意のキー」タイプの「インデックス/キー」を作成することによりcountries、列を一意に定義します。country_name

しかし、私は次の質問があります:

  1. タイプ「UniqueKey」の「Index/Key」を作成すると、この列に非クラスター化インデックスが自動的に作成されますか?
  2. タイプを「一意のキー」から「インデックス」に変更し、IsUnique値を「はい」のままにした場合、違いはありますか?
  3. では、なぜ「一意キー」と「インデックス」の2つのオプションがあるのでしょうか。2つは同じだと思いますか。
4

7 に答える 7

78

一意の制約は、一意のインデックスとしてバックグラウンドで実装されるため、どのように指定するかは重要ではありません。私はそれを単純に次のように実装する傾向があります:

ALTER TABLE dbo.foo ADD CONSTRAINT UQ_bar UNIQUE(bar);

代わりに一意のインデックスを作成する人もいます。

CREATE UNIQUE INDEX IX_UQ_Bar ON dbo.foo(bar);

違いは意図にあります。一意性/ビジネスルールを適用するために制約を作成する場合は制約を作成し、クエリのパフォーマンスを支援するためにそうする場合は、一意のインデックスを作成する方が論理的である可能性があります。繰り返しになりますが、これは同じ実装ですが、そこにたどり着くまでの道のりは、意図を文書化するのに役立つ場合があります。

以前のSybase機能とANSI標準の両方に準拠するための複数のオプションがあると思います(一意の制約は1つのNULL値(一意のインデックス)のみを許可するため、標準の100%に準拠していませんが、一方、SQL Server 2008以降ではWHERE句( )を追加することでこれを回避できます)。WHERE col IS NOT NULL

于 2012-04-21T23:00:08.943 に答える
14

もう1つ言及すべきことは、インデックスを作成する場合、含まれる列を指定できることです。これにより、country_nameによる検索がある場合に、SQLコードがより高速に機能するようになります。

CREATE UNIQUE NONCLUSTERED INDEX IX_UQ_Bar
ON dbo.foo (
    bar
)
INCLUDE (foo_other_column)
GO

SELECT foo_other_column FROM Foo WHERE bar = 'test'

SQLサーバーは、「foo_other_column」をインデックス自体に格納します。一意性制約の場合、最初に「test」のインデックスを検索し、次にfooテーブルの行を検索し、そこでのみ「foo_other_column」を取得します。

于 2013-10-28T09:25:21.380 に答える
2

上記の優れた回答以外に、ここに2セントを追加します。

一意キーは制約であり、一意インデックスを使用してそれ自体を適用します。主キーが通常、クラスター化された一意のインデックスによって適用されるのと同じように。論理的に言えば、制約とインデックスは2つの異なるものです。ただし、RDBMSでは、インデックスを介して制約を物理的に実装できます。

SQL Serverで一意の制約を使用してテーブルを作成すると、制約オブジェクト一意のインデックスの両方が表示されます

create table dbo.t (id  int constraint my_unique_constraint unique (id));

select [Constraint]=name from sys.key_constraints 
where parent_object_id = object_id('dbo.t');

select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t')
and index_id > 0;

以下を取得します(制約とインデックス)

ここに画像の説明を入力してください

ただし、制約を作成せず、次のような一意のインデックスのみを作成する場合

create table dbo.t2 (id int );
create unique index my_unique_constraint on dbo.t2 (id);

select [Constraint]=name from sys.key_constraints 
where parent_object_id = object_id('dbo.t2');

select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t2')
and index_id > 0

制約オブジェクトが作成されていないことがわかります(インデックスのみが作成されています)。

ここに画像の説明を入力してください

「理論的」な観点から、SQL Serverでは、制約はobject_id値を持つオブジェクトであり、スキーマにバインドされていますが、インデックスはオブジェクトではなく、object_id値もスキーマ関連もありません。

于 2018-05-29T18:05:42.480 に答える
1

一意のインデックスと一意の制約の間に違いはなく、パフォーマンスの違いもありません。ただし、一部のインデックス作成オプションが一意の制約に使用できない場合、作成にはいくつかの違いがあります。

于 2019-01-30T06:42:59.547 に答える
0

SqlMetal.exeを使用してDBMLまたはLinqToSqlエンティティを出力する場合:

  • 外部キーが一意のキーを使用している場合は、期待どおりに関連付けが行われます。
  • 外部キーが一意のインデックスを使用している場合、それは表示されません。

その理由は、SqlMetalの実装にあります。データベース情報スキーマ、特にキー列の使用法を照会します。一意のキーはそこに表示されますが、一意のインデックスは表示されません。

SELECT TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
于 2018-04-18T09:12:49.697 に答える
0

一意性を強制するための3番目のオプションは、Filtered Unique-Indexを使用して、NullableUniqueIndexを許可することです。
これは、Unique-Constraintsでは機能しません。
たとえば、一意の値のみを許可したいが、存在しない場合
   でも複数の値をサポートしたい列があるとします。フィルタされた一意のインデックス のみが機能します。NULL

CREATE UNIQUE NONCLUSTERED INDEX [UF_Employee_UserID] ON [dbo].[Employee]
(
    [UserID] ASC--Not all Employees have a UserID to log into the System.
)
WHERE ([UserID] IS NOT NULL)--Enforce Uniqueness when not null.

現在のところ、GUIを使用してテーブルを編集している間は、SSMSでFiltered-Indexを作成することはできません。
ただし、(上記のように)手動でインデックスを作成する代わりにGUIを使用する場合は、開いているすべてのテーブルデザイナーを閉じてから、オブジェクトエクスプローラーでインデックス自体のプロパティを開くことができます。

于 2019-03-05T09:01:45.187 に答える
0

最も重要なポイントの1つは、一意性キー制約では実行できない一意性を維持しながら列値をnullに保ちたいが、一意性キーインデックスuを使用すると、一意性を維持しながら列値をnullに保つことができると仮定します。したがって、Null可能タイプの一意の列が必要な場合は一意のインデックスが必要です。それ以外の場合は、null可能でない列が必要な場合は、一意のキー制約が必要です。

于 2019-05-22T09:41:24.500 に答える