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

Sei*_*aft 41 sql indexing primary-key

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

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

Mic*_*rdt 27

基本上,主键是(在实现级别)一种特殊的索引.特别:

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

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

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

  • 主键是*约束*,**而不是索引**.索引可以与*主键*关联,但不是必需的.除非使用SQL Server,否则索引不能确保唯一性. (10认同)
  • @OMG:MySQL和PostgreSQL都有一个CREATE UNIQUE INDEX语法.Postgres手册说:"当为表定义唯一约束或主键时,PostgreSQL会自动创建一个唯一索引.索引(...)是强制执行约束的机制." http://www.postgresql.org/docs/8.0/interactive/indexes-unique.html - 我认为我们的分歧源于我将索引作为实现细节的概念,而你专注于索引作为一个抽象的一部分. SQL DDL. (3认同)

mar*_*pet 12

差异

一个表只能有一个主键,但有几个索引.

一个主键是唯一的,而一个指数并不一定是唯一的.因此,主键的值标识表中的记录,索引的值不一定.

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

什么时候用

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

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

哪个最好?

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

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

根据您的个人经验添加索引,或者性能是否下降.衡量差异,如果您使用SQL Server,请学习如何阅读执行计划.


ale*_*bog 6

这可能有助于回归基础:主键和唯一索引之间的差异

两者之间的差异是:

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


Mic*_*sen 6

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

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

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

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

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

  • “你总是希望表上有一个主键,因为它是标识行的唯一方法。”:不,UNIQUE 约束(可选择跨越多个列,所有列都具有 NOT NULL 约束)也可以标识行。 (3认同)

nvo*_*gel 6

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

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

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