Sql server SQL-唯一键而不是主键

Sql server SQL-唯一键而不是主键,sql-server,Sql Server,我在表示一行标识符的5个可空列上有唯一的CONTAint。 可以创建唯一键并在其上创建聚集索引而不是主键吗?我不能在这些列上使用主键,因为它们是可空的,我也不能创建标识列,因为有大量的删除和插入操作,这会使标识列溢出。是的,有一个论点认为这实际上比主键“更好”,因为主键列不可为null的规则在许多方面都是人为的约束 如果将其设置为唯一聚集索引,则可以获得主键给表带来的几乎所有内容,但不需要的规则除外,即列必须不可为空。但是,它们必须仍然是唯一的,因此您只能有一行,其中索引中的所有五列都为空 因此

我在表示一行标识符的5个可空列上有唯一的CONTAint。
可以创建唯一键并在其上创建聚集索引而不是主键吗?我不能在这些列上使用主键,因为它们是可空的,我也不能创建标识列,因为有大量的删除和插入操作,这会使标识列溢出。

是的,有一个论点认为这实际上比主键“更好”,因为主键列不可为null的规则在许多方面都是人为的约束

如果将其设置为
唯一聚集索引
,则可以获得主键给表带来的几乎所有内容,但不需要的规则除外,即列必须不可为空。但是,它们必须仍然是唯一的,因此您只能有一行,其中索引中的所有五列都为空

因此,您可以在创建外键约束时使用索引,从而保证存储订单数据,并且每一行都必须是唯一的。然而,索引对于查询可能不会有太大的用处,而且,因为它的范围很广,而且你说有很多删除/插入操作,所以它会倾向于分割你的数据

就我个人而言,我很想把它变成一个独特的约束,但不是集群约束。然后它将执行防止创建非唯一数据的任务

然后,您可以添加一个代理项并将其作为主键。我怀疑你会不会“用完”(或“溢出”?)这样做的数字


那么我为什么要使用代理密钥呢

您的代理密钥将更窄,因此由于插入/更新/删除的次数太多,所以碎片的影响会更小

如果您需要扩展数据库,它将非常有用。假设您只有一个表,而这始终是整个数据库中唯一的表。在这一场景中,不使用代理键是有意义的。它不会给你任何价值;这只是不必要的开销

但是,让我们假设有其他表挂在“main”表上(有5列组成唯一键的表)。通过在此处添加代理键,可以创建任何具有单个id的子表,该id链接回父表。另一种方法是在每次创建子表时强制添加构成唯一(候选)键的所有五列


现在,您有了一个真正起作用的狭窄聚集索引,并且碎片不会像五列那样糟糕。

是吗?不什么?请创建一个。目的是什么?你得给我们点东西,你用的是哪种产品?“SQL”只是一种查询语言,而不是特定数据库产品的名称(不同的产品在空值和唯一约束下表现不同),请为您正在使用的数据库产品添加一个查询语言,
postgresql
oracle
SQL server
db2
,…我甚至不建议创建超过5列的键。为什么不使用ID列?这些列可以为空,因此不能作为主键的一部分
有大量的删除和插入操作,这会使此标识列溢出。
-标识列可以是
bigint
甚至
十进制(38,0)
,因此这不是一个好的理由。此表上是否有任何非聚集索引?您将对此表执行何种查询?他们会从这个索引中受益吗?那么,添加代理键的好处是什么?如果没有其他表引用这个表,并且每隔30分钟删除表中的所有数据并插入新数据,情况会怎样?那么,为什么要强制执行唯一性呢?当然,在数据填充步骤中处理这一点会更容易吗?如果您没有其他方法可以做到这一点,那么请确定,在您的表上创建一个
唯一索引
(我不会麻烦将其
聚集起来
),并接受这样一个事实:如果源数据中存在重复项,则填充步骤将失败。我强制执行唯一性以防止插入两个相同的数据行。我应该添加唯一约束+唯一索引吗?或者只有一个就足够了?五列上的一个唯一约束应该足够了(在你的句子中,约束=索引-在这个上下文中它们是相同的)。我的观点是,如果您在尝试将数据加载到表中之前能够在数据中发现2个重复行,那么这可能比尝试将其加载到表中更有效,那么它会失败,因为它发现了一个重复行。