【发布时间】:2016-11-10 09:28:04
【问题描述】:
上下文:我正在创建一个多线程应用程序,它将非常频繁地插入/更新行。
最初我有下表:
#TABLE 1
CREATE TABLE `example` (
`id` BIGINT(20) NOT NULL,
`state` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`, `state`))
ENGINE = MyISAM;
然而,在做了一些研究之后,我发现 MySQL 对 MyISAM 表使用表级锁定,允许一次只允许一个会话更新这些表 (source)。不适合频繁更改表的多线程应用程序。
因此,建议我从复合主键切换到自动生成的主键,该主键具有唯一的 id/state 索引。这将允许快速插入,同时仍然强制执行 id/state 的唯一组合。
#TABLE 2
CREATE TABLE `example` (
`key` BIGINT(20) NOT NULL,
`id` BIGINT(20) NOT NULL,
`state` VARCHAR(45) NOT NULL,
PRIMARY KEY (`key`),
UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC))
ENGINE = MyISAM;
然而,InnoDB 避免了表锁定,而是使用行级锁定 (source),所以我想切换到以下内容:
#TABLE 3
CREATE TABLE `example` (
`key` BIGINT(20) NOT NULL,
`id` BIGINT(20) NOT NULL,
`state` VARCHAR(45) NOT NULL,
PRIMARY KEY (`key`),
UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC))
ENGINE = InnoDB;
但是在阅读了 InnoDB 之后,我发现 InnoDB 使用聚集索引来组织数据,而二级索引需要多次查找。一个用于二级索引,另一个用于主键 (source)。因此,我正在讨论切换到以下内容:
#TABLE 4
CREATE TABLE `example` (
`id` BIGINT(20) NOT NULL,
`state` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`, `state`))
ENGINE = InnoDB;
我想知道我的所有假设是否正确:
- MyISAM 表为 INSERTS、UPDATES 和 DELETES 锁定整个表,只允许一个会话一次更新这些表
- InnoDB 处理带有复合主键的 INSERTS 比 MyISAM 更快。这是因为 InnoDB 与 MyISAM 不同,它不会锁定整个表来扫描和保留新的主键。
- 使用 InnoDB 时,我应该创建复合主键而不是复合唯一索引,因为二级索引需要多次查找。
- 我应该使用表 4
【问题讨论】:
-
(2) 是一个不合逻辑的。
-
你说得对,我已经更新它以更好地阐明我的意思。
标签: mysql innodb myisam composite-primary-key