SQL Server中主键和唯一索引的区别

时间:2013-09-26 06:30:18

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

我的公司目前正在重写我们最近收购的应用程序。我们选择使用ASP.net mvc4来构建这个系统,并使用Entity Framework作为我们的ORM。我们收购的公司的前任所有者非常坚定地认为我们使用他们的旧数据库而不改变它的任何内容,以便客户可以在我们开发不同模块的同时使用我们的产品与旧系统同时使用。

我发现旧的表结构没有主键,而是使用唯一索引作为主键。现在,在使用Entity框架时,我尝试在结构中匹配它们的表,但由于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; }
}

6 个答案:

答案 0 :(得分:5)

来自SQL UNIQUE Constraint

  

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

     

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

     

一个主要的   KEY约束自动在其上定义UNIQUE约束。

     

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

此外,来自Create Unique Indexes

  

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

来自Create Primary Keys

  

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

答案 1 :(得分:4)

他们肯定是不同的。正如其他答案所述:

  • 唯一键仅用于测试唯一性而不是其他任何内容
  • 主键充当记录的标识符。

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

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

总而言之,请务必确保您的桌子上有主键。索引会对性能产生巨大影响,您希望确保索引正确。

答案 2 :(得分:3)

他们肯定不是一回事。

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

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

答案 3 :(得分:2)

嗯,它们非常相似,但这里有不同之处。

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

默认情况下,除非您在create语句中另行指定并且假定聚簇索引尚不存在,否则主键将创建为聚簇索引。但是,默认情况下,唯一索引会创建为非聚簇索引,除非您另行指定并提供聚簇索引尚不存在。

以下链接真的可以帮到你。只需坚持下去

HERE

答案 4 :(得分:1)

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

这在Entity Framework中也是可能的。它会是这样的。

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 :(得分:0)

主键不包含任何空值。

但是如果唯一的空值可以在表中插入。

任何数量的 null 值都可以插入

主键定义 PRIMARY_KEY = UNIQUE + NOT_NULL