Jon*_*ood 5 sql-server foreign-keys sql-server-2008
在Alexander Kuznetsov文章中,他提供了以下代码片段:
CREATE TABLE dbo.Vehicles(
ID INT NOT NULL,
[Type] VARCHAR(5) NOT NULL,
CONSTRAINT Vehicles_PK PRIMARY KEY(ID),
CONSTRAINT Vehicles_UNQ_ID_Type UNIQUE(ID, [Type]),
CONSTRAINT Vehicles_CHK_ValidTypes CHECK([Type] IN ('Car', 'Truck'))
);
Run Code Online (Sandbox Code Playgroud)
这个片段为我提出了一些问题.
为什么要包括ID和Type在唯一约束?如果只是ID唯一的,那么两列的组合也将始终是唯一的.
此外,我知道如何设置主键并指定它是否在SSMS中是唯一的.但是,如何在一列上指定主键,并对列组合进行唯一约束?这会创建两个索引吗?
这是因为我试图实现类似的代码,它不会创建复合主键,我得到以下错误.所以我试图更好地理解这些代码.
表'MyTable'中的列与现有主键或UNIQUE约束不匹配.
编辑
我能够通过简单地创建一个复合主键来实现这一点MyTable.实际的表定义如下所示.再次,这是有效的.但它与上面引用的代码不同.而且我不确定如果我以其他方式做到这一点会更好.
CREATE TABLE [dbo].[MessageThread](
[Id] [int] IDENTITY(1,1) NOT NULL,
[MessageThreadType] [int] NOT NULL,
CONSTRAINT [PK_MessageThread_1] PRIMARY KEY CLUSTERED
(
[Id] ASC,
[MessageThreadType] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MessageThread] WITH CHECK ADD CONSTRAINT [CK_MessageThread_ValidType] CHECK (([MessageThreadType]=(2) OR [MessageThreadType]=(1)))
GO
ALTER TABLE [dbo].[MessageThread] CHECK CONSTRAINT [CK_MessageThread_ValidType]
GO
Run Code Online (Sandbox Code Playgroud)
在我的理解中,唯一约束的原因ID,[Type]是让细节表ID,[Type]作为外键引用.通常,父表需要对用于外键的列具有唯一约束.例如,问题中的表可以有2个详细信息表:
CREATE TABLE dbo.CARS(
....
vehicle_id INT NOT NULL,
[Type] VARCHAR(5) NOT NULL,
CONSTRAINT CAR_CHK_TYPE CHECK [Type]='Car',
CONSTRAINT CAR_FK_VEHICLE FOREIGN KEY (vehicle_id,[Type]) REFERENCES Vehincle(id,[Type]));
CREATE TABLE dbo.TRUCKS(
....
vehicle_id INT NOT NULL,
[Type] VARCHAR(5) NOT NULL,
CONSTRAINT CAR_CHK_TYPE CHECK [Type]='Truck',
CONSTRAINT CAR_FK_VEHICLE FOREIGN KEY (vehicle_id,[Type]) REFERENCES Vehincle(id,[Type]));
Run Code Online (Sandbox Code Playgroud)
这种方式Cars只有关于Car类型的细节,而TRUCKS只有约Truck.
例如,这种设计用于避免多态关系
CREATE TABLE dbo.VEHICLE (
...,
ref_id INT NOT NULL,
-- PK of 'master' table
ref_name VARCHAR(20) NOT NULL,
-- here we put 'truck' or 'car', so we virtually have 2 parents;
-- in this case we cannot use FK constraint, the only thing that may
-- somehow enforce the logical constraint is writing a trigger
Run Code Online (Sandbox Code Playgroud)
更新
您更新的表定义对我来说很好.我想样本表最初是为Oracle设计的,然后移植到SQLServer.在Oracle中,该唯一约束和主键可以使用相同的索引,因此同时具有PK和Unique约束不会受到惩罚.
1:我不确定给定模式的具体目的.但请注意,可以出于多种原因应用唯一约束,最常见的原因是:(a)强制执行唯一性;(b)为优化程序提供更多信息以作出基础决策.
2:唯一约束不会创建两个索引.它创建一个索引,其中一列作为前导键列.它强制执行两者的唯一性.因此对a,b的唯一约束可能有:
a b
---- ----
1 1
1 2
2 1
2 2
Run Code Online (Sandbox Code Playgroud)
请注意,这两列都不会单独强制实现唯一性.我不是在SSMS中使用表设计器的忠实粉丝(它有大量的bug并且不支持所有功能)但是这里是如何做到的:
a)右键单击网格并选择 Indexes/Keys...
b)使用Columns网格中的[...]按钮选择多个列
c)Type改为Unique Key
d)Name如果需要,改变

这是一个已经有主键的表的示例.如果我想要,我可以添加一个或多个唯一索引:

| 归档时间: |
|
| 查看次数: |
5673 次 |
| 最近记录: |