我想为 MySQL 表中的一列生成一个唯一的增量字符串值。该 key 的格式为{STRING}-{INT},例如FOO-1、FOO-2等。
下面是我的表结构:
CREATE TABLE IF NOT EXISTS `items` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`item_key` varchar(100) NOT NULL,
`title` tinytext NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `item_key` (`item_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
这里的要求是,当插入一条新记录时,'item_key'的值应该计算为:
Step-1: Find the last record
Step-1.1
If there is, get the value of 'item_key' and increment it's integer part and set it for new record
Step-1.2
Else set FOO-1 as item_key
据我所知,有两种选择可以实现这一点: 1.MySQL触发器 2. 使用PHP-MySQL 手动查询最后一条记录并在插入查询中设置新值
我更喜欢第一个选项 - MySQL 触发器 - Before Insert。我为此创建了一个触发器。
DELIMITER $$
CREATE TRIGGER generate_item_key
BEFORE INSERT
ON items FOR EACH ROW
BEGIN
DECLARE itemKey varchar(10);
DECLARE lastItemKey varchar(100) DEFAULT "";
DECLARE lastItemNum varchar(20) DEFAULT "";
SET itemKey = "FOO";
-- Find the last item
SET lastItemKey = (SELECT item_key FROM items WHERE item_key != "" ORDER BY created DESC LIMIT 1);
IF (lastItemKey <> '') THEN
SET lastItemNum = CONVERT(REPLACE(lastItemKey, CONCAT(itemKey, "-"), ""), UNSIGNED);
ELSE
SET lastItemNum = 0;
END IF;
-- Set new issue key
SET New.item_key = CONCAT(itemKey, "-", lastItemNum + 1);
END; $$
DELIMITER ;
这适用于单记录插入查询。例如,
INSERT INTO `items` (`id`, `item_key`, `title`, `created`, `modified`) VALUES (NULL, 'key', 'First item', '2015-07-14 00:00:00', '2015-07-14 00:00:00');
它为 item_key 列生成 FOO-1。
但是,问题是,它不适用于多插入查询。原因是在该列上应用了一个 UNIQUE 键,并且触发器为所有记录生成了相同的键。例如,
INSERT INTO `items` (`id`, `item_key`, `title`, `created`, `modified`) VALUES (NULL, 'key', 'First item', '2015-07-14 00:00:00', '2015-07-14 00:00:00'),(NULL, 'key2', 'Second item', '2015-07-14 00:00:00', '2015-07-14 00:00:00'),(NULL, 'key3', 'Third item', '2015-07-14 00:00:00', '2015-07-14 00:00:00'),(NULL, 'key', 'First item', '2015-07-14 00:00:00', '2015-07-14 00:00:00');
有人可以在这里提出建议吗?实现这一目标的最佳和快速解决方案是什么?
如果有人有除以上两种之外更好的解决方案,也请提出。
谢谢
最佳答案
如果不关心正在生成的项目键编号之间的差距,您可以使用新生成的主键值作为 item_key
名称的一部分。
示例:
DELIMITER $$
CREATE TRIGGER bi_items -- generate_item_key
BEFORE INSERT ON items
FOR EACH ROW
BEGIN
DECLARE itemKey varchar(10);
DECLARE _key_id INT DEFAULT 0;
SET itemKey = "FOO";
-- Find which new id is being assigned for PK column
SELECT AUTO_INCREMENT INTO _key_id
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'items'
AND TABLE_SCHEMA = DATABASE();
-- Set new issue key
SET New.item_key = CONCAT( itemKey, "-", _key_id );
END;
$$
DELIMITER ;
注意:自动递增字段值不会因错误而回滚。因此,在发生insert
错误后的下一个插入请求中,将不会使用先前生成的自动递增和丢弃的值。
关于php - 为 MySQL 中的列生成一个带有整数的唯一字符串作为后缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31404194/