无论如何要在 SQL 中创建辅助键吗?
假设我有一个包含列的表ID, SECID1, SECID2
关键是ID
,但我也希望它SECID1, SECID2
作为关键,以保证我没有两个具有相同SECID1
and的条目SECID1
。
如果可能的话,我该怎么做?
无论如何要在 SQL 中创建辅助键吗?
假设我有一个包含列的表ID, SECID1, SECID2
关键是ID
,但我也希望它SECID1, SECID2
作为关键,以保证我没有两个具有相同SECID1
and的条目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)您可以使用UNIQUE NONCLUSTERED 约束或UNIQUE NONCLUSTERED 索引:
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:您可以看到它CONSTRAINT PK_MyTestTable
被创建为一个CLUSTERED UNIQUE INDEX
并且CONSTRAINT UQ_MyTestTable_A_B UNIQUE NONCLUSTERED
被创建为“非集群索引”。
注 2(SQL 2008+)UNIQUE NONCLUSTERED CONSTRAINT
:对我来说,在 SQL Server 2008 中,an和 an之间的主要区别UNIQUE NONCLUSTERED INDEX
是能够在 NC 索引中包含非索引列,因此:
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 Lookup。
注 3 (SQL 2008+):此外,您可能有UNIQUE NONCLUSTERED FILTERED 索引。
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)您可以使用UNIQUE CLUSTERED 约束或UNIQUE CLUSTERED 索引:
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