MySQL - "很多"上的聚集索引"一对多"关系

时间:2014-09-29 15:41:00

标签: mysql sql indexing

我相信这对你们很多人来说很简单,所以我希望你们能够轻松帮助。

如果我在“一对多”关系的“多”方面有一个MySQL表 - 就像这样:

Create Table MyTable(
ThisTableId int auto_increment not null,
ForeignKey int not null,
Information text
)

由于此表总是通过使用ForeignKey的连接来使用,因此将ForeignKey设置为聚簇索引似乎很有用,这样外键将始终相邻地为相同的源记录排序。但是,ForeignKey并不是唯一的,所以我认为将这个聚集索引作为一种不可能或者不好的做法?如果我尝试使用(ForeignKey,ThisTableId)创建复合主键来实现有用的聚类和唯一性,那么就会出现错误“只能有一个自动列,并且必须将其定义为键”。

我想也许我正在接近这个错误,在这种情况下,最好的方法是将上表索引以获得最大速度?

1 个答案:

答案 0 :(得分:0)

InnoDB要求如果您有自动增量列,则它必须是密钥中的第一个列。

所以你不能将主键定义为(ForeignKey,ThisTableId) - 如果ThisTableId是自动增量。

如果ThisTableId只是一个常规列(不是自动增量),你可以这样做,但是你要负责在ForeignKey中指定一个至少与其他行具有相同值的唯一值。

我看过的一个方法是使列BIGINT UNSIGNED,并使用BEFORE INSERT触发器为列赋值函数UUID_SHORT()。


@ypercube正确地指出了另一个解决方案:InnoDB规则是自动增量列应该是某些键的第一列,如果你创建一个普通的二级密钥,那就足够了。这允许您创建如下表:

CREATE TABLE `MyTable` (
  `ForeignKey` int(11) NOT NULL,
  `ThisTableId` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`ForeignKey`,`ThisTableId`),
  KEY (`ThisTableId`)
) ENGINE=InnoDB;

自动增量按预期工作:

mysql> INSERT INTO MyTable (ForeignKey) VALUES (123), (234), (345), (456);

mysql> select * from MyTable;
+------------+-------------+
| ForeignKey | ThisTableId |
+------------+-------------+
|        123 |           1 |
|        234 |           2 |
|        345 |           3 |
|        456 |           4 |
+------------+-------------+