【问题标题】:Why MySQL creates an auto "only one" index for composite key?为什么 MySQL 为复合键创建一个自动“唯一”索引?
【发布时间】:2017-04-28 11:21:24
【问题描述】:

在这段代码中:

CREATE TABLE institution (
    iid INT(6) AUTO_INCREMENT,
    name VARCHAR(40) NOT NULL,
    PRIMARY KEY (iid))
ENGINE = INNODB;

CREATE TABLE plan (
    pid INT(2) AUTO_INCREMENT,
    name VARCHAR(40) NOT NULL,
    PRIMARY KEY (pid))
ENGINE = INNODB;

CREATE TABLE subscription (
    iid INT(6),
    pid INT(2),
    PRIMARY KEY (iid, pid),
    CONSTRAINT iid_FOREIGN_KEY FOREIGN KEY (iid) REFERENCES institution (iid),
    CONSTRAINT pid_FOREIGN_KEY FOREIGN KEY (pid) REFERENCES plan (pid))
ENGINE = INNODB;
  • 为什么 MySQL 只为“pid_FOREIGN_KEY”约束创建自动索引?为什么不给“iid_FOREIGN_KEY”呢?
  • 如果我将“PRIMARY KEY (iid, pid)”更改为“PRIMARY KEY (pid, iid)" 是否会为 "iid_FOREIGN_KEY" 创建一个自动索引 而不是“pid_FOREIGN_KEY”的另一个?

MySQL creates an auto index for "pid_FOREIGN_KEY" CONSTRAINT only

【问题讨论】:

    标签: mysql database


    【解决方案1】:

    根据 FOREIGN KEY Constraints 上的documentation

    index_name 表示外键 ID。如果子表上已经有明确定义的可以支持外键的索引,则忽略 index_name 值。否则,MySQL 会隐式创建外键索引...

    MySQL 确定主键可以支持列上的外键引用。如果您删除主键,则会隐式创建两个索引。

    在没有 FOREIGN KEY 约束的表上使用 ALTER TABLE 时会发生相同的行为。

    ALTER TABLE `subscription`
        ADD CONSTRAINT `iid_FOREIGN_KEY` FOREIGN KEY (`iid`) REFERENCES `institution` (`iid`),
        ADD CONSTRAINT `pid_FOREIGN_KEY` FOREIGN KEY (`pid`) REFERENCES `plan` (`pid`);
    

    您也可以在CREATE TABLE 语句中显式定义索引。

    CREATE TABLE `subscription` (
        `iid` INT(6),
        `pid` INT(2),
        PRIMARY KEY (`iid`, `pid`),
        INDEX `iid_FOREIGN_KEY` (`iid`),
        INDEX `pid_FOREIGN_KEY` (`pid`),
        CONSTRAINT FOREIGN KEY (`iid`) REFERENCES `institution` (`iid`),
        CONSTRAINT FOREIGN KEY (`pid`) REFERENCES `plan` (`pid`)
    )
    ENGINE = INNODB;
    

    列顺序会影响具有多个列索引的值的索引,因此 MySQL 确定主键中的第一个(最左侧)列可以支持外键约束索引。见:Multiple Column Indexes

    MySQL 可以使用多列索引来测试所有 索引中的列,或只测试第一列的查询, 前两列,前三列,依此类推。如果您指定 索引定义中按正确顺序排列的列,单个 复合索引可以加速同一个查询的多种查询 表。

    为了进一步澄清,primary key does have an associated index

    因此在主键多列索引的第一列(最左侧)上指定单个索引将是多余的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多