sql >> データベース >  >> RDS >> Sqlserver

SQLServerの固有の制約に関する洞察

    一意キー制約とは何ですか?

    一意性制約は、列エントリを一意性に制限するルールです。つまり、このタイプの制約は、列に重複を挿入することを防ぎます。一意の制約は、SQLServerデータベースでデータの整合性を強化するための手段の1つです。テーブルには主キーを1つしか含めることができないため、一意性制約を使用して、主キーを構成しない列または列の組み合わせの一意性を適用できます。

    列に一意の制約を作成すると、一意のインデックスが自動的に作成されます。このようにして、SQLServerは一意の制約の整合性要件を実装します。したがって、一意の制約が定義されている列に重複する値を挿入しようとすると、データベースエンジンは一意の制約違反を検出し、対応するエラーを発行します。その結果、値が重複している行はテーブルに追加されません。

    一意の制約の作成

    次のサンプルクエリは、学生を作成します テーブルとログインの一意性制約 同じログインの学生がいないように列を作成します。

    CREATE TABLE Students (
    Login CHAR NOT NULL
    ,CONSTRAINT AK_Student_Login UNIQUE (Login)
    );
    GO

    学生の場合 テーブルがすでに存在する場合は、次のサンプルクエリを使用して一意の制約を作成できます。

    ALTER TABLE Students
    ADD CONSTRAINT AK_Student_Login UNIQUE (Login);
    GO

    既存のテーブルに一意の制約を追加すると、データベースエンジンは、制約が追加された列に重複した値が含まれているかどうかを確認することに注意してください。そのような値がある場合、制約は追加されず、エラーが返されます。

    ここで、一意の制約が実際に追加されたことを確認するには、次のステートメントを実行します。

    EXEC sp_helpindex Students
    
    EXEC sp_helpconstraint Students

    作成した制約は次のとおりです。

    SQL ServerManagementStudioでの一意の制約の作成

    ログインに一意の制約を定義する必要があるとします。 学生に列を作成します テーブル。

    1。 オブジェクトエクスプローラー学生を右クリックします 表をクリックし、[デザイン]をクリックします 。

    2。 テーブルデザイナを右クリックします インデックス/キー…を選択します

    3。 インデックス/キー ウィンドウで、追加をクリックします 。

    4。 一般の下 セクションで、[]をクリックします 次に、省略記号ボタンをクリックします。 インデックス列 ウィンドウで、一意の制約に含める列を選択します。

    5。 一般の下 セクションで、[タイプ]をクリックします 一意のキーを選択します ドロップダウンリストから。

    6。 アイデンティティの下 セクションで、制約の名前を指定します(この場合、 AK_Student_Login )、[閉じる]をクリックします 新しく作成した制約を保存します。

    さて、学生に行くと オブジェクトエクスプローラーのテーブル インデックスをクリックします フォルダには、テーブルに主キーと一意の制約が含まれていることがわかります AK_Student_Login

    一意の制約は主キーとどのように異なりますか?

    一意性制約と同様に、主キーもテーブルのデータ整合性を強制するために使用されます。ただし、主キーの主な目的は、テーブル内の各レコードを一意に識別し、データベース内のテーブル間に適切な関係を実装することです。テーブルの行に適切にアクセスするには、99%のテーブルで主キーが必要です。 1つまたは複数の列で定義されるテーブルごとに1つの主キーのみが存在できます。

    一意の制約は、重複する値が列に挿入されるのを防ぐために特に使用されます。一意の制約を持つ複数の列が存在する場合や、テーブルに一意の制約がまったく定義されていない場合があります。主キーとは対照的に、これらはテーブルに必須ではありません。

    たとえば、学生がいるとします。 大学の各学生の個人情報を含むテーブル。このテーブルには、 StudentIDが含まれています 主キーであり、特定の各学生の一意のIDを格納する列。この主キー列は、大学の各学生を一意に識別するために使用されます。

    同時に、学生 テーブルにはEmailなどの列があります 、社会保障番号 、およびログイン これらの各列には、一意の値を格納する必要があります。テーブルにはすでに1つの主キーがあるため、代わりに一意の制約を使用して、これらの列に一意性を課します。したがって、テーブルには多くの一意の制約と1つの主キーのみを持つことができます。

    一意性制約が主キーと異なるもう1つの点は、主キーが NULLを許可しないことです。 列の値。一方、一意性制約のある列には NULLを含めることができます。 SQL Serverは2つのNULL値を同じ値として解釈するため、値は1つだけです。

    Emailに一意の制約が作成されたとします。 学生の列 テーブル。両方ともNULLで2つの行を挿入してみましょう s Email フィールド:

    INSERT INTO Students (Student_ID, Name, Age, Email, SSN, Login)
    
    VALUES (1, 'John White', 19, NULL, 123-45-6789, 'John555')
    
    GO
    INSERT INTO Students (Student_ID, Name, Age, Email, SSN, Login)
    
    VALUES (2, 'James Marvin', 21, NULL, 987-65-4321, 'Marvin_J17')
    
    GO

    次のエラーメッセージが表示されます:

    重複する値は、たとえNULLであっても、一意性制約によって許可されないため、これは予測可能な動作です。

    一意性制約と一意性インデックス

    一意の制約と一意のインデックスはどちらも完全に異なる2つの無関係なデータベースエンティティですが、同じ目標を持ち、SQLServerのパフォーマンスに同じ影響を与えます。どちらも、列内のデータの一意性を保証します。

    ただし、一意のインデックスとは対照的に、ALTER TABLEステートメントの一意の制約にIGNORE_DUP_KEY、DROP_EXISTING、PAD_INDEX、およびSTATISTICS_NORECOMPUTEオプションを指定することはできません。

    列に一意の制約を作成すると、SQL Serverは列に一意のインデックスを自動的に作成します。これは、この機能がSQLServerに実装される方法です。

    一意のインデックスを削除するには、最初に対応する一意の制約を削除する必要があります。これにより、基になる一意のインデックスが自動的に削除されます。

    次のステートメントは、 AK_Student_Loginを削除します 制約:

    ALTER TABLE Students 
    DROP CONSTRAINT AK_Student_Login; 
    GO

    AK_Student_Loginを削除するとわかります 一意の制約により、対応するインデックスが削除されます。

    それは簡単でした。今では、同じ値をログインに挿入できます。 列。

    一意の制約を無効にする

    一意性制約を無効にするオプションがあります。次のクエリは、すべてのテーブル制約を無効にすることになっています。

    ALTER TABLE Students
    NOCHECK CONSTRAINT ALL
    GO

    クエリを実行したら、複製レコードを挿入してみましょう。

    INSERT INTO Students (Student_ID, Name, Age, Email, SSN, Login)
    VALUES (3, 'John White', 19, NULL, 123-45-6789, 'John555')
    GO

    取得するのは、固有の制約違反メッセージです:

    したがって、ALTERTABLE<テーブル名>NOCHECKCONSTRAINT ALL GOは、SQLServerの一意の制約に対しては機能しないようです。

    ただし、各一意性制約の内部には一意性インデックスがあり、一意性インデックスを無効にできるはずです。この場合、 AK_Student_Email 一意の制約により、対応する AK_Student_Emailが作成されました メールの一意のインデックス 桁。次のクエリを使用して、 AK_Student_Emailを無効にしましょう。 最初に一意のインデックス。

    ALTER INDEX AK_Student_Email ON Students
    DISABLE;

    クエリは正常に完了したので、重複したメールを含む2つのレコードを挿入しましょう。 学生へのフィールド テーブル。

    INSERT INTO Students (Student_ID, Name, Age, Email, SSN, Login)
    VALUES (3, 'John White', 19, '[email protected]', 123-45-6789, 'John555')
    GO
    INSERT INTO Students (Student_ID, Name, Age, Email, SSN, Login)
    VALUES (4, 'James Marvin', 21, '[email protected]', 987-65-4321, 'Marvin_J17')
    GO

    できます!レコードがテーブルに挿入されました!これで、この「無効化」の問題を一意の制約で回避する方法がわかりました。

    インデックスを有効にするには、次のクエリを使用します。

    ALTER INDEX AK_Student_Email ON Students
    REBUILD;

    結論

    一意キー制約により、DBAおよびSQL開発者は、テーブル列のデータの一意性を適用および保持し、データの整合性に関する特定のビジネス要件を適用できます。基本的に、一意性制約を直接無効にすることはできず、ALTER TABLEステートメントの一意性制約に対して特定のインデックス作成オプションを使用できないという事実を除いて、一意性制約と一意性インデックスの動作に実質的な違いはありません。

    この記事がおもしろかったと思います。この記事について質問したり、コメントや提案を残したりできます。

    関連項目: SQLServerのチェック制約


    1. OracleRACの観点から見たSQLServerクラスタリング

    2. MariaDBの日付形式の文字列

    3. テーブルの列の順序について心配する理由はありますか?

    4. MariaDBJavaコネクタドライバーのパフォーマンス