SQLでセカンダリキーを作成する方法はありますか?
列を持つテーブルがあるとしましょうID, SECID1, SECID2
キーは ですが、同じとを持つ 2 つのエントリがないことを保証するために、キーとして機能するID
ことも必要です。SECID1, SECID2
SECID1
SECID1
可能であれば、どうすればこれを行うことができますか?
SQLでセカンダリキーを作成する方法はありますか?
列を持つテーブルがあるとしましょうID, SECID1, SECID2
キーは ですが、同じとを持つ 2 つのエントリがないことを保証するために、キーとして機能するID
ことも必要です。SECID1, SECID2
SECID1
SECID1
可能であれば、どうすればこれを行うことができますか?
可能です。ここにドキュメントと説明があります: http://www.w3schools.com/sql/sql_unique.asp
はい、複合列の一意の制約または一意のインデックスを追加できます (以下では一意の制約を使用します)
CREATE TABLE YourTable
(
ID INT PRIMARY KEY,
SECID1 INT,
SECID2 INT,
UNIQUE(SECID1,SECID2)
)
サロゲートID
列は必ず必要ですか? これが多対多の関係テーブルである場合、通常は 2 列の PK しかありません (そのテーブルにアクセスするクエリに応じて、キーの順序が逆になった一意のインデックス/制約がある場合もあります)。
UNIQUE KEY
このような一意性チェック/制約を実現するために、好きなだけ制約を作成できます。
欲しいのはユニークキー
1)UNIQUENONCLUSTERED制約またはUNIQUENONCLUSTEREDインデックスを使用できます。
CREATE TABLE MyTestTable
(
ID INT NOT NULL,
A INT NOT NULL,
B INT NOT NULL,
C INT NULL,
CONSTRAINT PK_MyTestTable PRIMARY KEY(ID)
);
GO
ALTER TABLE MyTestTable
ADD CONSTRAINT UQ_MyTestTable_A_B UNIQUE NONCLUSTERED (A, B);
GO
CREATE UNIQUE NONCLUSTERED INDEX IUN_MyTestTable_A_B
ON MyTestTable(A, B);
GO
SELECT i.name, i.index_id, i.type, i.type_desc, i.is_unique, i.is_primary_key
FROM sys.indexes i
WHERE i.object_id = OBJECT_ID('dbo.MyTestTable')
GO
結果:
name index_id type type_desc is_unique is_primary_key
------------------- -------- ---- ------------ --------- --------------
PK_MyTestTable 1 1 CLUSTERED 1 1
UQ_MyTestTable_A_B 2 2 NONCLUSTERED 1 0
IUN_MyTestTable_A_B 3 2 NONCLUSTERED 1 0
注1 :がとして作成され、「NONCLUSTEREDINDEX」としてCONSTRAINT PK_MyTestTable
作成されているCLUSTERED UNIQUE INDEX
ことがわかります。CONSTRAINT UQ_MyTestTable_A_B UNIQUE NONCLUSTERED
注2(SQL 2008+)UNIQUE NONCLUSTERED CONSTRAINT
:私にとってSQL Server 2008の場合、anとanの主な違いは、インデックスなしの列をNCインデックス内UNIQUE NONCLUSTERED INDEX
に含めることができることです。
CREATE UNIQUE NONCLUSTERED INDEX IUN_MyTestTable_A_B_#_C
ON MyTestTable(A, B)
INCLUDE (C); --Nonindexed column
GO
SELECT i.name, i.index_id, i.type, i.type_desc, i.is_unique, i.is_primary_key, i.is_disabled
FROM sys.indexes i
WHERE i.object_id = OBJECT_ID('dbo.MyTestTable')
GO
結果:
name index_id type type_desc is_unique is_primary_key is_disabled
----------------------- ----------- ---- ------------ --------- -------------- -----------
PK_MyTestTable 1 1 CLUSTERED 1 1 0
UQ_MyTestTable_A_B 2 2 NONCLUSTERED 1 0 0
IUN_MyTestTable_A_B 3 2 NONCLUSTERED 1 0 0
IUN_MyTestTable_A_B_#_C 4 2 NONCLUSTERED 1 0 0
カバーするインデックスCREATE UNIQUE NONCLUSTERED INDEX ... ... INCLUDE(...)
を作成し、実行プランからKeyLookupまたはRIDルックアップを削除するために使用できます。
注3(SQL 2008+) :また、UNIQUENONCLUSTEREDFILTEREDインデックスがある場合があります。
CREATE TABLE Invoice
(
InvoiceID INT PRIMARY KEY,
InvoiceDate DATE NOT NULL,
Total NUMERIC(8,2) NOT NULL,
--Business rule: one invoice may have only one child invoice
ParentInvoiceID INT NULL REFERENCES Invoice(InvoiceID)
);
GO
INSERT Invoice(InvoiceID, InvoiceDate, Total, ParentInvoiceID)
VALUES (1, '2011-01-01', 1000, NULL), (2, '2011-02-02', 2000, NULL);
GO
SET ANSI_WARNINGS ON;
GO
--Business rule: one invoice may have only one child invoice
CREATE UNIQUE NONCLUSTERED INDEX IUF_Invoice_ParentInvoiceID
ON Invoice(ParentInvoiceID)
WHERE ParentInvoiceID IS NOT NULL;
GO
--OK
INSERT Invoice(InvoiceID, InvoiceDate, Total, ParentInvoiceID)
VALUES (3, '2012-03-03', 1005, 1);
GO
--Error
INSERT Invoice(InvoiceID, InvoiceDate, Total, ParentInvoiceID)
VALUES (4, '2012-04-04', 1005, 1);
GO
結果:
Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.Invoice' with unique index 'IUF_Invoice_ParentInvoiceID'.
The statement has been terminated.
2)UNIQUECLUSTERED制約またはUNIQUECLUSTEREDインデックスを使用できます。
IF OBJECT_ID('dbo.MyTestTable') IS NOT NULL
DROP TABLE MyTestTable;
GO
CREATE TABLE MyTestTable
(
ID INT NOT NULL,
A INT NOT NULL,
B INT NOT NULL,
C INT NULL,
CONSTRAINT PK_MyTestTable PRIMARY KEY NONCLUSTERED(ID)
);
GO
ALTER TABLE MyTestTable
ADD CONSTRAINT UQ_MyTestTable_A_B UNIQUE CLUSTERED (A, B);
GO
SELECT i.name, i.index_id, i.type, i.type_desc, i.is_unique, i.is_primary_key, i.is_disabled
FROM sys.indexes i
WHERE i.object_id = OBJECT_ID('dbo.MyTestTable')
GO
結果:
name index_id type type_desc is_unique is_primary_key is_disabled
------------------ ----------- ---- ------------- --------- -------------- -----------
UQ_MyTestTable_A_B 1 1 CLUSTERED 1 0 0
PK_MyTestTable 2 2 NONCLUSTERED 1 1 0
または
ALTER TABLE MyTesttable
DROP CONSTRAINT UQ_MyTestTable_A_B;
GO
CREATE UNIQUE CLUSTERED INDEX IUN_MyTestTable_A_B2
ON MyTestTable(A, B);
GO
SELECT i.name, i.index_id, i.type, i.type_desc, i.is_unique, i.is_primary_key, i.is_disabled
FROM sys.indexes i
WHERE i.object_id = OBJECT_ID('dbo.MyTestTable')
GO
結果:
name index_id type type_desc is_unique is_primary_key is_disabled
-------------------- ----------- ---- ------------ --------- -------------- -----------
IUN_MyTestTable_A_B2 1 1 CLUSTERED 1 0 0
PK_MyTestTable 2 2 NONCLUSTERED 1 1 0