0

Microsoft SQL Serverでは、テーブルを作成するときに、列に一意性を設定する必要がない場合でも、列に一意性制約を使用することの欠点はありますか?

例としては、ユーザー管理システムでの役割などの説明があります。

CREATE TABLE Role
(
    ID TINYINT PRIMARY KEY NOT NULL IDENTITY(0, 1),
    Title CHARACTER VARYING(32) NOT NULL UNIQUE,
    Description CHARACTER VARYING(MAX) NOT NULL UNIQUE
)

私の恐れは、他のテーブルに頻繁に挿入するときにこの制約を検証することは、非常に時間のかかるプロセスになることです。この制約がどのように検証されるかはわかりませんが、非常に効率的な方法で、または線形比較として実行できると思います。

4

4 に答える 4

5

あなたの恐れは真実になります:UNIQUE制約はインデックスとして実装され、これは時間とスペースを消費します。

したがって、新しい行を挿入するたびに、データベースはテーブルを更新する必要があり、一意の制約ごとに1つのインデックスも更新する必要があります。

だから、あなたによると:

本当に一意である必要はありませんが、列に一意性制約を使用する

答えはノーです、それを使用しないでください。時間とスペースの欠点があります。

サンプルテーブルには、Idのクラスター化インデックスと、一意の制約ごとに1つずつ、2つの追加のインデックスが必要です。これにはスペースと時間がかかり、インサートの3つのインデックスを更新するのに時間がかかります。

これは、これらのフィールドでフィルタリングするクエリを作成した場合にのみ正当化されます。

ちなみに:元の投稿サンプルテーブルにはいくつかの欠陥があります:

  • その構文はSQLServer構文ではありません(これをSQL Serverとしてタグ付けしました)

  • varchar(max)列にインデックスを作成することはできません

構文を修正してこのテーブルを作成すると、次のようになります。

CREATE TABLE Role
(
  ID tinyint PRIMARY KEY NOT NULL IDENTITY(0, 1),
  Title varchar(32) NOT NULL UNIQUE,
  Description varchar(32) NOT NULL UNIQUE
)

その後、実行するsp_help Roleと、3つのインデックスが見つかります。

于 2012-04-10T23:04:25.443 に答える
1

データベースは、UNIQUE制約をバックアップするインデックスを作成するため、一意性チェックを実行するのは非常に低コストである必要があります。

http://msdn.microsoft.com/en-us/library/ms177420.aspx

データベースエンジンは、UNIQUEインデックスを自動的に作成して、UNIQUE制約の一意性要件を適用します。したがって、重複する行を挿入しようとすると、データベースエンジンは、UNIQUE制約に違反していることを示すエラーメッセージを返し、その行をテーブルに追加しません。クラスタ化インデックスが明示的に指定されていない限り、一意の非クラスタ化インデックスがデフォルトで作成され、UNIQUE制約が適用されます。

于 2012-04-10T22:10:57.823 に答える
0

データが常に一意であることがわかっているが、アプリケーションが正しく機能するために必ずしも一意である必要はない場合は、通常、制約することをお勧めしますか?

あなたへの私の質問:2つの役割が異なるタイトルを持つが同じ説明を持つことは理にかなっていますか?例えば

INSERT INTO Role ( Title , Description )
   VALUES ( 'CEO' , 'Senior manager' ), 
          ( 'CTO' , 'Senior manager' );

私には、説明の使用を切り下げているように見えます。重複が多かった場合は、次のようなことを行う方が理にかなっている可能性があります。

INSERT INTO Role ( Title )
   VALUES ( 'CEO' ), 
          ( 'CTO' );

INSERT INTO SeniorManagers ( Title )
   VALUES ( 'CEO' ), 
          ( 'CTO' );

しかし、繰り返しになりますが、重複は期待していません。

これはアクティビティの少ないテーブルだと思います。他のテーブルに頻繁に挿入するときに、この制約を検証することを恐れていると言います。まあ、それは起こりません(別のテーブルが更新されたときにこのテーブルを更新する可能性のあるトリガーがない限り)。

個人的には、デザイナー(ビジネスアナリストなど)に、一意の制約を適用しないことを正当化するように依頼します。それができない場合は、常識に基づいてunqiue制約を課します。このようなテキスト列では通常どおり、CHECKたとえば先頭/末尾/二重スペース、長さゼロの文字列などを禁止するために制約を適用します。

于 2012-04-11T07:50:11.810 に答える
-1

SQL Serverでは、データ型tinyintは256個の異なる値しか提供しません。id列の外で何をしても、テーブルが非常に大きくなることはありません。インデックス付きの列が12個ある場合でも、確実に迅速に実行されます。

ただし、通常、代理キー以外に少なくとも1つの一意の制約が必要です。お持ちでない場合は、このようなデータになってしまう可能性があります。

1    First title    First description
2    First title    First description
3    First title    First description
...
17   Third title    Third description
18   First title    First description

そのようなデータを許可するテーブルは通常間違っています。このテーブルへの外部キー参照を使用するテーブルは、使用された「最初のタイトル」の数など、正しくレポートできません。

ユーザー管理システムの役割に複数の同一のタイトルを許可することは、設計上の誤りであると私は主張します。「タイトル」もそのコラムにとって本当に悪い名前だと私はおそらく主張するでしょう。

于 2012-04-10T23:13:22.497 に答える