我想为我的用户表生成一个ID号。 id号是唯一索引。
这是我的触发器
USE `schema_epolling`;
DELIMITER $$
CREATE DEFINER=`root`@`localhost` TRIGGER `tbl_user_BINS` BEFORE INSERT ON `tbl_user`
FOR EACH ROW
BEGIN
SET NEW.id_number = CONCAT(DATE_FORMAT(NOW(),'%y'),LPAD((SELECT auto_increment FROM
information_schema.tables WHERE table_schema = 'schema_epolling' AND table_name =
'tbl_user'),6,0));
END
如果我一个接一个地插入它,或者一次可以插入5行。 但如果我插入批量行..发生错误。
id number
下面是用于从另一个模式/表中插入批量行的代码:
INSERT INTO schema_epolling.tbl_user (last_name, first_name)
SELECT last_name, first_name
FROM schema_nc.tbl_person
发生错误:
Error Code: 1062. Duplicate entry '14000004' for key 'id_number_UNIQUE'
Error Code: 1062. Duplicate entry '14000011' for key 'id_number_UNIQUE'
Error Code: 1062. Duplicate entry '14000018' for key 'id_number_UNIQUE'
Error Code: 1062. Duplicate entry '14000025' for key 'id_number_UNIQUE'
Error Code: 1062. Duplicate entry '14000032' for key 'id_number_UNIQUE'
如果我使用uuid()函数,它可以正常工作。但是我不想要uuid()太久了。
答案 0 :(得分:1)
您不希望以这种方式生成id值。
当BEFORE INSERT触发器执行时,尚未生成当前INSERT的自动递增值。
即使它是,但是INFORMATION_SCHEMA将包含由任何线程生成的最大自动增量值,而不仅仅是执行触发器的线程。所以你会遇到一个竞争条件,很容易与其他并发插入冲突,并得到错误的值。
此外,在每个INSERT上查询INFORMATION_SCHEMA可能是您性能的瓶颈。
在这种情况下,要获得前缀为两位数年份格式的自动增量值,您可以将表格的自动增量值提升至%y
百万,然后在2015年1月1日到达时你会用ALTER TABLE再次推进它。
重新评论:
我上面给出的答案适用于MySQL的自动增量的工作原理。如果您不依赖于自动增量,则可以通过其他方式生成值。
但是,按照您显示的方式将触发器与自动增量组合起来将无效。
答案 1 :(得分:0)
我想加上我的两分钱来阐述Bill Karwin的观点。 最好不要通过尝试手动拼凑一个来生成唯一ID。
您的学校以这种方式生成ID这一事实并不意味着这是最好的方式(假设这是他们使用的生成价值,我不能更多地知道信息)。
如果您接受ID字段(或键)的目的是保证每行数据的唯一性,而不是作为存储某些人类可读数据的参考点,那么您的数据库工作将更简单且更不容易出错在一个中心位置。 这种类型的ID /密钥称为代理密钥。 如果您想在这里阅读更多相关内容,那么这篇文章很好:http://en.wikipedia.org/wiki/Surrogate_key 代理键也常见于表的主键(当它以这种方式使用时,它可以极大地简化表之间的关系创建)。
如果您想添加连接日期值和其他信息的辅助列,因为它对您正在编写的应用程序或您认为合适的任何其他目的有价值,那么请将其创建为您的单独列表
在此考虑ID列/键,火&忘记,方式可以简化概念,使您在数据库创建过程中体验到许多好处。 例如,如果您在非关联数据库之间需要唯一性,您将更容易忍受UUID的使用。 (因为您知道它的目的仅仅是为了确保唯一性不会对您有任何其他方式。) 此外,正如您所发现的那样,对自己负责而不是依赖数据库来产生独特的价值会增加耗时的复杂性,否则可以避免。
希望这会有所帮助。