Nir*_*eri 22 mysql innodb composite-key auto-increment
场景:
我有一个引用两个外键的表,并且对于这些外键的每个唯一组合,都有自己的auto_increment列.我需要实现一个复合键,它将使用这三个组合(一个外键和一个auto_increment列,另一个列具有非唯一值)帮助将行标识为唯一
表:
CREATE TABLE `issue_log` (
`sr_no` INT NOT NULL AUTO_INCREMENT ,
`app_id` INT NOT NULL ,
`test_id` INT NOT NULL ,
`issue_name` VARCHAR(255) NOT NULL ,
primary key (app_id, test_id,sr_no)
);
Run Code Online (Sandbox Code Playgroud)
当然,我的查询必定有问题,因为抛出的错误是:
错误1075:表定义不正确; 只能有一个自动列,必须将其定义为键
我想要实现的目标:
我有一个Application Table(以app_id作为主键),每个Application都有一组要解决的问题,每个Application都有多个测试(所以test_id col)sr_no col应该为唯一的app_id和test_id递增.
即表中的数据应如下所示:

数据库引擎是InnoDB.我希望尽可能简单地实现这一点(即如果可能的话,避免使用触发器/程序 - 这是针对其他问题的类似情况而建议的).
noz*_*noz 29
您无法让MySQL为InnoDB表自动执行此操作 - 您需要使用触发器或过程,或者使用其他数据库引擎(如MyISAM).只能对单个主键执行自动递增.
像下面这样的东西应该工作
DELIMITER $$
CREATE TRIGGER xxx BEFORE INSERT ON issue_log
FOR EACH ROW BEGIN
SET NEW.sr_no = (
SELECT IFNULL(MAX(sr_no), 0) + 1
FROM issue_log
WHERE app_id = NEW.app_id
AND test_id = NEW.test_id
);
END $$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
您可以使用myISAM和BDB引擎执行此操作.InnoDB不支持此功能.引自MySQL 5.0参考手册.
对于MyISAM和BDB表,您可以在多列索引中的辅助列上指定AUTO_INCREMENT.在这种情况下,AUTO_INCREMENT列的生成值计算为MAX(auto_increment_column)+ 1 WHERE prefix = given-prefix.
http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
我不完全理解您对列的增量要求test_id,但如果您想要一个在 ( app_id, test_id) 的每个唯一组合上重新启动的 ~autoincrement 序列,您可以执行 INSERT ... SELECT FROM 同一个表,如下所示:
mysql> INSERT INTO `issue_log` (`sr_no`, `app_id`, `test_id`, `issue_name`) SELECT
IFNULL(MAX(`sr_no`), 0) + 1 /* next sequence number */,
3 /* desired app_id */,
1 /* desired test_id */,
'Name of new row'
FROM `issue_log` /* specify the table name as well */
WHERE `app_id` = 3 AND `test_id` = 1 /* same values as in inserted columns */
Run Code Online (Sandbox Code Playgroud)
这假定表定义没有声明 AUTO_INCREMENT 列。您本质上是使用 IFNULL(MAX()) + 1 子句模拟自动增量行为,但手动模拟适用于任意列,这与内置自动增量不同。
请注意,INSERT ... SELECT 是单个查询,可确保操作的原子性。InnoDB将对适当的索引进行间隙锁定,并且许多并发进程可以执行这种查询,同时仍然产生不冲突的序列。