0

在 Microsoft SQL Server 中,创建表时,对列使用唯一约束是否有任何缺点,即使您并不真的需要它是唯一的?

一个例子是对用户管理系统中角色的描述:

CREATE TABLE Role
(
    ID TINYINT PRIMARY KEY NOT NULL IDENTITY(0, 1),
    Title CHARACTER VARYING(32) NOT NULL UNIQUE,
    Description CHARACTER VARYING(MAX) NOT NULL UNIQUE
)

我担心在其他表中频繁插入时验证此约束将是一个非常耗时的过程。我不确定如何验证此约束,但我觉得它可以以非常有效的方式或作为线性比较来完成。

4

4 回答 4

5

您的恐惧变成了现实:UNIQUE 约束被实现为索引,这既费时又费空间。

因此,每当您插入新行时,数据库都必须更新表,并且每个唯一约束也必须更新一个索引。

所以,根据你的说法:

对列使用唯一约束,即使您并不真正需要它是唯一的

答案是否定的,不要使用它。有时间和空间的缺点。

您的示例表需要一个用于 Id 的聚集索引和 2 个额外的索引,每个唯一约束一个。这会占用空间和时间来更新插入的 3 个索引。

仅当您按这些字段进行查询过滤时,这才是合理的。

顺便说一句:原始的帖子样本表有几个缺陷:

  • 该语法不是 SQL Server 语法(并且您将其标记为 SQL Server)

  • 您不能在 varchar(max) 列中创建索引

如果您更正语法并创建此表:

CREATE TABLE Role
(
  ID tinyint PRIMARY KEY NOT NULL IDENTITY(0, 1),
  Title varchar(32) NOT NULL UNIQUE,
  Description varchar(32) NOT NULL UNIQUE
)

然后你可以执行sp_help Role,你会发现 3 个索引。

于 2012-04-10T23:04:25.443 回答
1

数据库会创建一个索引来支持 UNIQUE 约束,因此进行唯一性检查的成本应该非常低。

http://msdn.microsoft.com/en-us/library/ms177420.aspx

数据库引擎会自动创建一个 UNIQUE 索引来强制执行 UNIQUE 约束的唯一性要求。因此,如果尝试插入重复行,数据库引擎会返回一条错误消息,指出违反了 UNIQUE 约束并且不会将该行添加到表中。除非显式指定聚集索引,否则默认情况下会创建唯一的非聚集索引以强制执行 UNIQUE 约束。

于 2012-04-10T22:10:57.823 回答
0

如果您知道数据将始终是唯一的,但它不一定需要是唯一的才能使应用程序正常运行,那么限制它通常是一种好习惯吗?

我的问题是:两个角色有不同的头衔但有相同的描述是否有意义?例如

INSERT INTO Role ( Title , Description )
   VALUES ( 'CEO' , 'Senior manager' ), 
          ( 'CTO' , 'Senior manager' );

对我来说,这似乎贬低了描述的使用;如果有很多重复,那么做更多这样的事情可能更有意义:

INSERT INTO Role ( Title )
   VALUES ( 'CEO' ), 
          ( 'CTO' );

INSERT INTO SeniorManagers ( Title )
   VALUES ( 'CEO' ), 
          ( 'CTO' );

但是话又说回来,您并不期望重复。

我认为这是一个低活动表。你说你害怕在其他表中频繁插入时验证这个约束。好吧,这不会发生(除非有一个我们看不到的触发器可能会在另一个表被更新时更新这个表)。

就个人而言,我会要求设计师(业务分析师,等等)证明不应用唯一约束是合理的。如果他们不能,那么我会根据常识施加 unqiue 约束。对于这样的文本列,通常情况下,我也会应用CHECK约束,例如禁止前导/尾随/双空格、零长度字符串等。

于 2012-04-11T07:50:11.810 回答
-1

在 SQL Server 上,数据类型 tinyint 只为您提供 256 个不同的值。无论您在 id 列之外做什么,您最终都不会得到一个非常大的表。即使有十几个索引列,它也肯定会快速执行。

但是,除了代理键之外,您通常至少需要一个唯一约束。如果你没有,你很可能会得到这样的数据。

1    First title    First description
2    First title    First description
3    First title    First description
...
17   Third title    Third description
18   First title    First description

允许此类数据的表格通常是错误的。任何使用对该表的外键引用的表都无法正确报告,例如,使用的“第一个标题”的数量。

我认为在用户管理系统中允许多个相同的角色标题是一个设计错误。我可能会争辩说,“标题”对于该专栏来说也是一个非常糟糕的名字。

于 2012-04-10T23:13:22.497 回答