上下文:我正在创建一个多线程应用程序,它将非常频繁地插入/更新行。
最初我有下表:
#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;
我想知道我的所有假设是否正确:
答案 0 :(得分:3)
1-yes,2-yes,3-yes,4-yes。
也...
BIGINT
吗? INT UNSIGNED
中不会有40亿个值吗? (并节省一半的空间。)据推测id
是其他桌子的PK?如果是这样,那个表也需要改变。state
可以正常化吗?或者变成ENUM
?再次节省空间。项目3比提到的更糟糕,因为需要锁定两个唯一的密钥。