【问题标题】:Difference between Primary Key and Unique Index in SQL Server [duplicate]SQL Server中主键和唯一索引之间的区别[重复]
【发布时间】:2013-10-01 23:46:11
【问题描述】:

我的公司目前正在重写我们最近收购的应用程序。我们选择使用 ASP.net mvc4 来构建这个系统以及使用实体框架作为我们的 ORM。我们收购的公司的前任所有者非常坚持我们使用他们的旧数据库并且不会对其进行任何更改,以便客户可以在我们开发不同模块的同时同时使用我们的产品和旧系统。

我发现旧的表结构没有主键,而是使用唯一索引作为它们的主键。现在,当使用实体框架时,我尝试在结构上匹配他们的表,但由于 EF 生成主键而不是唯一索引而无法这样做。

当我联系了前任老板并解释时,他告诉我“每个表中的唯一键是主键。它们是彼此的同义词。”

我对数据库系统还比较陌生,所以我不确定这是否正确。谁能澄清一下?

他的表在转储到 SQL 时生成:

-- ----------------------------
-- Indexes structure for table AT_APSRANCD
-- ----------------------------
CREATE UNIQUE INDEX [ac_key] ON [dbo].[AT_APSRANCD]
([AC_Analysis_category] ASC, [AC_ANALYSI_CODE] ASC) 
WITH (IGNORE_DUP_KEY = ON)
GO

但是我的系统生成:

-- ----------------------------
-- Primary Key structure for table AT_APSRANCD
-- ----------------------------
ALTER TABLE [dbo].[AT_APSRANCD] ADD PRIMARY KEY ([AC_Analysis_category])
GO

编辑: 对此的后续问题是我将如何为此设计模型?我只习惯使用将其定义为主键的 [Key] 注释,没有它,EF 将不会生成该表。 所以是这样的:

[Table("AT_APSRANCD")]
public class Analysis
{
    [Key]
    public string AnalysisCode { get; set; }
    public string AnalysisCategory { get; set; }
    public string ShortName { get; set; }
    public string LongName { get; set; }
}

【问题讨论】:

  • 查看我的答案以获取 EF 中的示例复合键。
  • 注意其他区别:原始超过两列,原始忽略重复值。
  • 如果数据库已经存在,为什么不让 EF 生成所有实体?
  • 因为当前版本的 EF 不支持对我更熟悉的注释模型进行逆向工程。
  • 我已经安装了,我相信注释模型支持即将推出。 entityframework.codeplex.com/workitem/508

标签: c# sql sql-server asp.net-mvc entity-framework


【解决方案1】:

它们绝对不同。如其他答案所述:

  • 唯一键仅用于测试唯一性,没有其他用途
  • 主键充当记录的标识符。

另外,重要的是主键通常是聚集索引。这意味着记录按主键定义的顺序物理存储。这对性能有很大影响。

此外,聚集索引键(通常也是主键)会自动包含在所有其他索引中,因此获取它不需要记录查找,只需读取索引就足够了。

总而言之,请始终确保您的表上有一个主键。索引对性能有巨大影响,您需要确保索引正确。

【讨论】:

  • 这并不完全正确。它是用于所有其他非聚集索引的聚集索引键。通常,聚集索引也是 PK,但不一定总是如此。
  • @SilasHansen 没错。我更新了我的答案,谢谢。
【解决方案2】:

主键不包含任何空值。

但在唯一的空值的情况下可以插入到表中。

可以插入任意数量的null

主键定义PRIMARY_KEY=UNIQUE+NOT_NULL

【讨论】:

  • 对不起,这比那更复杂。
【解决方案3】:

它们肯定不是一回事。

主键必须是唯一的,但这只是其要求之一。另一个是它不能为空,这不是唯一约束所必需的。

此外,虽然在某种程度上,唯一约束可以用作穷人的主键,但将它们与 IGNORE_DUP_KEY = ON 一起使用显然是错误的。该设置意味着如果您尝试插入重复项,则插入将静默失败。

【讨论】:

    【解决方案4】:

    是的,一个复合且唯一的键,就像你在这里一样,会给你一个非常像主键的索引。其中一个优点是数据包含在索引中,因此如果您只查询键中的字段,则不必在表中进行查找。

    这在实体框架中也是可能的。它会是这样的。

    public class AT_APSRANCD
    {
        [Column(Order = 0), Key, ForeignKey("AC_Analysis_category")]
        public int AC_Analysis_category{ get; set; }
    
        [Column(Order = 1), Key, ForeignKey("AC_ANALYSI_CODE")]
        public int AC_ANALYSI_CODE{ get; set; }
    }
    

    【讨论】:

    • 不就是创建一个复合主键吗?
    【解决方案5】:

    嗯,它们非常相似,但这里有一些区别。

    一个表只允许一个主键,但可以添加多个唯一索引,直到表允许的最大索引数(SQL Server = 250(1 x 集群,249 x 非集群)和 SQL 2008 和 SQL 2012 = 1000(1 x 集群,999 x 非集群))。 主键不能包含可为空的列,但唯一索引可以。请注意,只允许使用一个 NULL。如果索引是跨多个列创建的,则值和 NULL 的每个组合都必须是唯一的。

    默认情况下,除非您在 create 语句中另外指定并且如果聚集索引不存在,否则主键将创建为聚集索引。但是,唯一索引默认情况下会创建为非聚集索引,除非您另外指定并假设聚集索引不存在。

    下面的链接真的会对你有帮助。去吧

    HERE

    【讨论】:

      【解决方案6】:

      来自SQL UNIQUE Constraint

      UNIQUE 约束唯一标识数据库中的每条记录 桌子。

      UNIQUE 和 PRIMARY KEY 约束都提供了一个 保证一列或一组列的唯一性。

      初级 KEY 约束自动定义了一个 UNIQUE 约束。

      请注意,每个表可以有许多 UNIQUE 约束,但只有一个 每个表的 PRIMARY KEY 约束。

      另外,来自Create Unique Indexes

      如果该列不能创建唯一索引 在多行中包含 NULL。同样,您不能创建 如果列组合,则多列上的唯一索引 在多行中包含 NULL。这些被视为重复 用于索引目的的值。

      而来自Create Primary Keys

      在 PRIMARY KEY 约束中定义的所有列都必须定义为 非空。如果未指定可空性,则所有列都参与 在 PRIMARY KEY 约束中将它们的可空性设置为 NOT NULL。

      【讨论】:

      • 那么我该如何去设计它的模型呢,我使用注解,到目前为止只使用 [Key] 来定义主键,如果我不这样做,我还能做什么做什么?
      猜你喜欢
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-22
      • 2011-09-16
      • 2014-03-28
      • 2018-12-21
      • 2016-09-20
      相关资源
      最近更新 更多