场景:
我有一个引用两个外键的表,对于这些外键的每个唯一组合,都有自己的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)
);
当然,我的查询肯定有什么问题,因此抛出的错误是:
错误1075:表定义不正确;只能有一个auto列,并且必须将其定义为键
我想达到的目标:
我有一个应用程序表(以app_id作为主键),每个应用程序都有一组待解决的问题,每个应用程序都有多个测试(因此test_id col)sr_no col应该为唯一的app_id和test_id递增。
即,表中的数据应如下所示:
数据库引擎是InnoDB。我希望尽可能简单地实现这一点(即如有可能,避免触发/程序-这是针对其他问题的类似情况提出的建议)。
7条答案
按热度按时间myzjeezk1#
你不能让MySQL自动为InnoDB表做这件事--你需要使用触发器或过程,或者使用另一个DB引擎,如MyISAM。只能对单个主键执行自动递增。
类似下面的东西应该可以工作
cunj1qz12#
您可以使用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
nkkqxpd93#
我不完全理解你对
test_id
列的增量要求,但是如果你想要一个~autoincrement序列,在每个唯一的(app_id
,test_id
)组合上重新启动,你可以执行INSERT...从同一个表中选择,像这样:这假定表定义没有声明AUTO_INCREMENT列。您实际上是在使用IFNULL(MAX())+ 1子句模拟自动增量行为,但是手动模拟可以在任意列上工作,这与内置的自动增量不同。
请注意,INSERT... SELECT是一个单一的查询,确保了操作的原子性。InnoDB将间隙锁定适当的索引,许多并发进程可以执行这种查询,同时仍然产生不冲突的序列。
guz6ccqo4#
您可以使用unique组合键来表示
sr_no
、app_id
和test_id
。您不能在sr_no
中使用增量,因为它不是唯一的。我已经注解掉了sql fiddle中的unique constraint violation以进行演示(删除schema第22行中的#并重新构建schema)
gj3fmq9x5#
这就是我想要的
我当前的表定义是
我创建了一个表来存储每个租户的当前ID。
然后我创造了这个触发器来解决我的问题
这种方法也将是线程安全的,因为由于触发器中的更新查询,针对相同租户的任何插入将顺序地发生,并且针对不同租户的插入将并行发生。
pgvzfuti6#
只需在自动递增列上添加键(
sr_no
):7vux5j2d7#
为什么不尝试改变声明字段作为主键的位置,因为当你使用“auto_increment”时,它必须作为第一个引用。就像下面的例子