【问题标题】:When should I use primary key or index?什么时候应该使用主键或索引?
【发布时间】:2011-02-22 02:59:55
【问题描述】:

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

它们有什么区别,哪个最好?

【问题讨论】:

    标签: sql primary-key indexing


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 主键是约束不是索引。索引可以与主键 相关联,但这不是必需的。除非使用 SQL Server,否则索引并不能确保唯一性。
    • @OMG:从技术上讲,主键约束(就像唯一约束一样)将始终通过索引实现。如果这样声明,索引可以确保唯一性。
    • SQL Server 是唯一具有唯一索引的数据库,SQL Server/Oracle/MySQL/Postgres *自动创建索引除了主键约束,但在所有情况下都可以删除其中任何一个而不影响其他功能。 IE:MySQL & SQL Server 将它们的 PK 索引表示为 CLUSTERED 索引,不必与 pk 关联。 Oracle 对索引没有这种区别,但可以删除 pk 上的索引而不影响引用完整性。所以不 - 主键不是通过索引实现的。
    • @OMG:MySQL 和 PostgreSQL 都有 CREATE UNIQUE INDEX 语法。 Postgres 手册说“当为表定义唯一约束或主键时,PostgreSQL 会自动创建唯一索引。索引 (...) 是强制执行约束的机制。” postgresql.org/docs/8.0/interactive/indexes-unique.html -- 我认为我们的分歧源于我将索引的概念视为实现细节,而您将索引视为 SQL DDL 的抽象部分。
    • @David:斯坦福大学有人不同意 Oracle:“Oracle 自动为每个 UNIQUE 或 PRIMARY KEY 声明创建索引。请注意,您不能删除 UNIQUE 和 PRIMARY KEY 属性的索引。” infolab.stanford.edu/~ullman/fcdb/oracle/… - 是的,键和索引在概念上是不同的,但在实现层面上,索引将用于有效地执行键或唯一约束。
    【解决方案2】:

    区别

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

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

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

    什么时候用什么

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

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

    哪个最好?

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

    我建议始终先问问自己,表的主键是什么并定义它。

    根据您的个人经历添加索引,或者如果表现下降。 衡量差异,如果您使用 SQL Server,请了解如何阅读执行计划。

    【讨论】:

      【解决方案3】:

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

      两者的区别在于:

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          【解决方案5】:

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

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

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

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

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

          【讨论】:

          • “你总是希望你的表上有一个主键,因为它是识别行的唯一方法。”:不,一个 UNIQUE 约束,可选地跨越多个列,所有列都有 NOT NULL 约束,也可以识别一行。
          【解决方案6】:

          每个表都应该有一个PRIMARY KEY

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

          【讨论】:

            猜你喜欢
            • 2011-03-23
            • 2011-03-19
            • 2010-12-21
            • 2010-09-08
            • 1970-01-01
            • 2011-01-16
            • 2023-04-02
            相关资源
            最近更新 更多