什么时候应该使用主键或索引?
什么时候应该使用主键或索引?
他们的区别是什么,哪一个是最好的?
基本上,主键是(在实现级别)一种特殊的索引。 特别:
- 一个表只能有一个主键,除了极less数例外,每个表都应该有一个。
- 主键是隐含的
UNIQUE
– 你不能有多个具有相同主键的行,因为它的目的是唯一地标识行。 - 主键不能是
NULL
,所以它所包含的行必须是NOT NULL
一个表可以有多个索引,索引不一定是UNIQUE
。 索引的存在有两个原因:
- 为了强制执行一个唯一约束(当你声明一个列UNIQUE时,可以隐式地创build这些约束)
- 提高性能。 对于具有索引的列,WHERE子句中的相等或“大于/小于”以及JOIN比较快得多。 但是请注意,每个索引都会降低更新/插入/删除性能,所以您应该只将它们放在实际需要的位置。
差异
一个表只能有一个主键 ,但有几个索引 。
主键是唯一的 ,而索引不必是唯一的 。 因此,主键的值在表中标识一条logging,索引的值不一定。
主键通常被自动编入索引 – 如果您创build主键,则无需在同一列上创build索引。
何时使用什么
每个表应该有一个主键 。 定义一个保证唯一标识每个logging的主键。
如果您经常在连接中或在某些情况下使用其他列, 索引可能会加快您的查询速度 。 但是,索引在创build和删除logging时会有一些开销 – 如果您执行大量的插入和删除操作,请记住这一点。
哪个最好?
没有什么 – 每个人都有其目的。 这不是你真的可以select这个或那个。
我build议总是先问自己一个表的主键是什么,并定义它。
根据您的个人经验添加索引,或者如果性能下降。 衡量差异,如果您使用SQL Server学习如何阅读执行计划。
这可能有助于回到基础:主键和唯一索引之间的区别
两者的区别是:
- 创build表的主键的列不能为NULL,因为根据定义,主键不能为NULL,因为它有助于唯一地标识表中的logging。 构成唯一索引的列可以是空的。 值得一提的是,不同的RDBMS以不同的方式处理这个问题 – >虽然SQL Server和DB2在一个唯一的索引列中不允许有多个NULL值,但Oracle允许有多个NULL值。 这是在RDBMS上devise/开发/移植应用程序时要注意的事情之一。
- 只能在表中定义一个主键,因为您可以在表上定义许多唯一索引(如果需要)。
- 另外,就SQL Server而言,如果使用默认选项,则会将主键创build为聚簇索引,而将唯一索引(约束)创build为非聚簇索引。 这只是默认行为,如果需要,可以在创build时进行更改。
键和索引是完全不同的概念,实现不同的事情。 关键是要求元组是唯一的逻辑约束。 索引是数据库的性能优化function,因此是数据库的物理而不是逻辑function。
两者之间的区别有时是模糊的,因为通常使用相似或相同的语法来指定约束和索引。 当创build关键约束时,许多DBMS将默认创build一个索引。 关键和索引之间混淆的可能性是不幸的,因为分离逻辑和物理问题是数据pipe理的一个非常重要的方面。
至于“主要”键。 它们不是“特殊”types的钥匙。 主键只是表中的任何一个候选键。 至less有两种方法可以在大多数SQL DBMS中创build候选键,它们使用PRIMARY KEY约束或在NOT NULL列上使用UNIQUE约束。 这是一个非常广泛的观察约定,每个SQL表都有一个PRIMARY KEY约束。 使用PRIMARY KEY约束是传统智慧和完全合理的事情,但通常不会造成任何实际或逻辑上的差异,因为大多数DBMS将所有密钥视为相等。 当然,每个表应该至less执行一个候选键,但是这些键是否由PRIMARY KEY或UNIQUE约束执行通常不重要。 原则上它是重要的候选键,而不是“主要”键。
主键在定义上是唯一的 :它标识每个单独的行。 您总是需要在表上使用主键,因为这是识别行的唯一方法。
索引基本上是一个字段或一组字段的字典。 当您要求数据库查找某个字段等于某个特定值的logging时,可以在字典(索引)中查找以find正确的行。 这是非常快的,因为就像字典一样,条目在索引中被sorting以允许二进制search。 没有索引,数据库必须读取表中的每一行并检查值。
您通常希望为每个需要过滤的列添加索引。 如果您search特定的列组合,则可以创build包含所有这些列的单个索引。 如果这样做,可以使用相同的索引来search索引中列的列表的任何前缀。 简单地说(如果有点不准确),字典按照指定的顺序保存由在列中使用的值的串联组成的条目,所以数据库可以查找以特定值开始的条目,并仍然使用有效的二进制search这个。
例如,如果对列(A,B,C)有索引,即使只对A进行过滤,也可以使用此索引,因为这是索引中的第一列。 同样,如果您同时过滤A和B,则可以使用它。但是,如果仅对B或C进行过滤,则不能使用它,因为它们不是列列表中的前缀 – 您需要另一个索引来容纳。
主键也可以作为一个索引,所以你不需要添加一个与主键相同的索引。