1

无论如何要在 SQL 中创建辅助键吗?

假设我有一个包含列的表ID, SECID1, SECID2

关键是ID,但我也希望它SECID1, SECID2作为关键,以保证我没有两个具有相同SECID1and的条目SECID1

如果可能的话,我该怎么做?

4

5 回答 5

4

有可能,这里有文档和解释: http ://www.w3schools.com/sql/sql_unique.asp

于 2012-04-09T10:51:49.383 回答
3

是的,可以添加复合列唯一约束或唯一索引(下面我使用唯一约束)

CREATE TABLE YourTable
(
ID INT PRIMARY KEY, 
SECID1 INT, 
SECID2 INT,
UNIQUE(SECID1,SECID2)
)

一定需要代理ID列吗?如果这是一个多对多关系表,我通常只有一个 2 列 PK(有时根据访问该表的查询,反向键顺序的唯一索引/约束)

于 2012-04-09T10:50:50.600 回答
3

您可以创建任意数量的UNIQUE KEY约束来实现此类唯一性检查/约束。

于 2012-04-09T10:51:33.417 回答
2

你想要的是一个唯一的钥匙

于 2012-04-09T10:54:21.220 回答
0

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
于 2012-04-09T12:48:07.150 回答