代码之家  ›  专栏  ›  技术社区  ›  joseph

如果我创建一个没有主键的表,然后添加主键,那么主键是聚集索引吗?

  •  0
  • joseph  · 技术社区  · 4 年前

    从…起 Getting Started with Indexes: Primary Key 上面写着:

    在InnoDB表中,所有索引都包含主键作为后缀。因此,在使用此存储引擎时,保持主键尽可能小尤为重要。如果主键不存在并且没有UNIQUE索引,InnoDB会创建一个6字节的聚集索引,该索引对用户来说是不可见的。

    因此,如果没有主键,我们将创建一个具有隐藏聚集索引的表。然后在同一节的后面几段中说:

    不能使用create INDEX命令创建主键。如果确实要在创建表后添加一个,请使用ALTER table,例如:

    但没有说明新主键是否会成为聚集索引。

    而且 ALTER TABLE: ADD PRIMARY KEY 只说:

    对于PRIMARY KEY索引,可以为索引指定一个名称,但该名称将被忽略,并且索引的名称始终为PRIMARY。

    但不对聚集索引进行评论。

    我的困惑导致了以下问题:

    1. 如果稍后添加主键,该主键会被聚集吗?
    2. 如果是,存储布局会发生什么变化?它是否必须将所有数据复制到新的聚集索引,然后删除以前隐藏的聚集索引?
    3. 主键总是集群的吗?

    最小再现示例:

    create database test
    use test
    create table test_table ( id bigint(20) NULL );
    
    describe test_table;
    +-------+------------+------+-----+---------+-------+
    | Field | Type       | Null | Key | Default | Extra |
    +-------+------------+------+-----+---------+-------+
    | id    | bigint(20) | YES  |     | NULL    |       |
    +-------+------------+------+-----+---------+-------+
    1 row in set (0.003 sec)
    
    show index from test_table;
    Empty set (0.000 sec)
    
    
    alter table test_table add primary key(id);
    Query OK, 0 rows affected (0.067 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    describe test_table;
    +-------+------------+------+-----+---------+-------+
    | Field | Type       | Null | Key | Default | Extra |
    +-------+------------+------+-----+---------+-------+
    | id    | bigint(20) | NO   | PRI | NULL    |       |
    +-------+------------+------+-----+---------+-------+
    1 row in set (0.007 sec)
    
    show index from test_table;
    +------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table      | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | test_table |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
    +------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    1 row in set (0.001 sec)
    
    1 回复  |  直到 4 年前
        1
  •  3
  •   Bill Karwin    4 年前

    如果表有一个主键,那么它总是集群索引(假设它在InnoDB引擎中)。

    如果更改表以添加主键,则该主键将成为聚集索引。

    添加(或更改)主键确实需要重新构造表,因为布局将完全更改。