我什么时候应该使用主键或索引?

时间:2010-05-20 22:21:26

标签: sql primary-key indexing

我应该何时使用主键或索引?

他们的差异是什么,哪个是最好的?

6 个答案:

答案 0 :(得分:26)

基本上,主键是(在实现级别)一种特殊的索引。具体做法是:

  • 一个表只能有一个主键,除了极少数例外,每个表都应该有一个。
  • 主键是隐式UNIQUE - 您不能有多个具有相同主键的行,因为它的目的是唯一地标识行。
  • 主键永远不能是NULL,因此它所包含的行必须为NOT NULL

表可以有多个索引,索引不一定是UNIQUE。索引存在有两个原因:

  • 强制执行单一约束(当您声明列UNIQUE时,可以隐式创建这些约束)
  • 改善表现。在具有索引的列上,WHERE子句以及JOIN中的相等或“大于/小于”的比较要快得多。但请注意,每个索引都会降低更新/插入/删除性能,因此您应该只将它们放在实际需要的位置。

答案 1 :(得分:10)

差异

一张表只能有一个主键,但多个索引

主键是唯一的,而索引不必是唯一的。因此,主键的值标识表中的记录,索引的值不一定。

主键通常会自动编入索引 - 如果创建主键,则无需在同一列上创建索引。

何时使用

每个表都应有一个主键。定义一个保证唯一标识每条记录的主键。

如果您经常在联接或条件中使用其他列,索引可能会加快您的查询。但是,索引在创建和删除记录时会产生开销 - 如果您进行大量的插入和删除操作,请记住这一点。

哪个最好?

没有 - 每个人都有自己的目的。并不是说你真的可以选择其中一个。

我建议首先问自己一个表的主键是什么并定义它。

个人体验添加索引,或者效果正在下降。 衡量差异,如果您使用SQL Server,请了解如何阅读执行计划。

答案 2 :(得分:6)

这可能会有助Back to the Basics: Difference between Primary Key and Unique Index

  

两者之间的区别是:

     
      
  1. 创建表的主键的列不能为NULL,因为根据定义,主键不能为NULL,因为它有助于唯一标识表中的记录。构成唯一索引的列可以为空。值得一提的是,不同的RDBMS对此有不同的看法 - >虽然SQL Server和DB2在唯一索引列中不允许多个NULL值,但Oracle允许多个NULL值。在跨RDBMS设计/开发/移植应用程序时,这是需要注意的事项之一。
  2.   
  3. 表中只能定义一个主键,因为您可以在表上定义许多唯一索引(如果需要)。
  4.   
  5. 此外,对于SQL Server,如果使用默认选项,则将主键创建为聚簇索引,而将唯一索引(约束)创建为非聚簇索引。这只是默认行为,如果需要,可以在创建时更改。
  6.   

答案 3 :(得分:6)

键和索引是完全不同的概念,可以实现不同的功能。密钥是一种逻辑约束,它要求元组是唯一的。索引是数据库的性能优化功能,因此是数据库的物理特性而非逻辑特性。

两者之间的区别有时会模糊,因为通常使用类似或相同的语法来指定约束和索引。创建关键约束时,许多DBMS将默认创建索引。密钥和索引之间混淆的可能性是不幸的,因为将逻辑和物理问题分开是数据管理的一个非常重要的方面。

关于“主要”键。它们不是“特殊”类型的键。主键只是表的任何一个候选键。在大多数SQL DBMS中至少有两种创建候选键的方法,即使用PRIMARY KEY约束或在NOT NULL列上使用UNIQUE约束。每个SQL表都有一个PRIMARY KEY约束,这是一个被广泛遵守的约定。使用PRIMARY KEY约束是传统的智慧和完全合理的事情,但它通常没有实际或逻辑上的区别,因为大多数DBMS将所有键视为相等。当然,每个表都应该强制执行至少一个候选键,但这些键是否由PRIMARY KEY或UNIQUE约束强制执行通常并不重要。原则上,候选键是重要的,而不是“主键”。

答案 4 :(得分:4)

主键根据定义唯一:它标识每一行。您总是希望在表上使用主键,因为这是识别行的唯一方法。

索引基本上是字段或字段集的字典。当您要求数据库查找某个字段等于某个特定值的记录时,它可以在字典(索引)中查找以找到正确的行。这非常快,因为就像字典一样,条目在索引中排序,允许二进制搜索。如果没有索引,数据库必须读取表中的每一行并检查值。

您通常希望为需要过滤的每个列添加索引。如果搜索特定的列组合,则可以创建包含所有列的单个索引。如果这样做,可以使用相同的索引来搜索索引中列列表的任何前缀。简单地说(如果有点不准确),字典按照指定的顺序保存由列中使用的值的串联组成的条目,因此数据库可以查找以特定值开头并仍然使用有效二进制搜索的条目此

例如,如果列(A,B,C)上有索引,即使您只对A进行过滤,也可以使用此索引,因为这是索引中的第一列。同样,如果你同时在A和B上进行过滤,也可以使用它。但是,如果你只对B或C进行过滤,则不能使用它,因为它们不是列列表中的前缀 - 你需要另一个索引来容纳

主键也可用作索引,因此您无需添加与主键相同列的索引。

答案 5 :(得分:0)

每个表都应有一个PRIMARY KEY

明智地选择INDEX可以加快许多类型的查询。 可能是最佳索引是主键。我的观点是,查询是是否使用PK作为其索引的主要因素。