【问题标题】:Differences between defining primary key - along with column name, at the end of create table stmt, adding primary key index after create table stmt定义主键的区别——连同列名,在create table stmt的最后,create table stmt之后加上主键索引
【发布时间】:2021-07-31 19:11:50
【问题描述】:

我见过三种定义主键的方法。

  1. 连同其列名定义一起定义:

    CREATE TABLE test (
        id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        -- other fields
    );
    
  2. 在表定义的末尾定义键:

    CREATE TABLE test (
       id INT UNSIGNED NOT NULL AUTO_INCREMENT,
       -- other fields
       PRIMARY KEY (id)
    );
    
  3. 创建表后添加主键索引。通常我在 phpMyAdmin 导出的 .sql 文件中看到了这一点。 (是否取决于使用的存储引擎?)

    CREATE TABLE test (
        id INT UNSIGNED NOT NULL,
        -- other fields
    );
    
    ALTER TABLE test
        ADD PRIMARY KEY (id),
        MODIFY id INT UNSIGNED NOT NULL AUTO_INCREMENT;
    

所有这些方法的内部区别是什么?

大多数情况下,我发现使用第三种方法导入 SQL 文件比使用其他方法需要更长的时间。

编辑(在Bill Karwin告诉“(该)示例显示没有数据导入”之后):

上面的例子不包含INSERT查询,但是如果每个CREATE TABLE查询后面都有INSERT语句插入数据会有什么区别?

【问题讨论】:

  • 它们之间没有区别。
  • 这个(id INT UNSIGNED NOT NULL AUTO_INCREMENT,)是不正确的,因为没有key的时候不能定义AUTO_INCRMENT
  • @Luuk 感谢您的指出。我已相应地对帖子进行了更正。
  • 我真的认为在回答第一个问题后将您的问题编辑为另一个问题是不对的。如果您有新问题,请提出新问题,如果此问题已回答,请将其标记为已回答。

标签: mysql sql mariadb


【解决方案1】:

前两种形式没有区别。如果您的主键是单列,这只是一种语法便利。但是如果你有一个多列的主键,你必须将 PK 定义为一个表约束:

CREATE TABLE test (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    other INT NOT NULL, 
   -- other fields
    PRIMARY KEY (id, other)
);

第三种形式几乎相同,因为您在向表中插入任何数据之前定义了主键。唯一的影响是第二个 DDL 语句更改了元数据。

有人声称导入数据后添加主键更快,但对于 MySQL 的默认存储引擎 InnoDB 来说并非如此。表数据存储为聚集索引。如果您不声明自己的主键,则会隐式创建另一个行 id,这将成为聚集索引的键。因此,您以一种或另一种方式插入索引。

在旧的 MyISAM 存储引擎中,将数据插入到没有主键的表中可能会更快一些。但是插入数据后添加主键需要额外的时间。

无论如何,您的示例显示没有数据导入,因此没有实际意义。

【讨论】:

  • 但是如果转储文件包含id 列的值,则第三种方法在插入时必须检查重复项。隐式集群索引不需要验证,是吗?
  • 欢迎试用!我想如果你在数据导入之后再加上构建 PK 的时间,那就太浪费了。
  • 我的直觉很可能是多年在工作中使用 MyISAM 形成的。当我们在脚本中创建临时表时,我们总是在填充它们之后添加索引。
  • 在我目前的工作中,我们监控每个数据库中的非 InnoDB 表,并在发现表时警告开发人员(系统模式除外)。
  • 我们对所有新表都使用 InnoDB,但我们的大部分架构已经使用了 10-15 年。
猜你喜欢
  • 2019-06-26
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
  • 2015-07-12
  • 1970-01-01
  • 2020-06-11
相关资源
最近更新 更多