我想为MySQL表中的一列生成唯一的增量字符串值。此密钥的格式为{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'的值应计算为:
步骤1:找到最后一条记录
Step-1.1
如果有,请获取'item_key'的值并增加它的整数 部分并将其设置为新记录
Step-1.2
否则将FOO-1设置为item_key
根据我的知识,有两种方法可以实现这一目标: 1. MySQL触发器 2.使用PHP-MySQL手动查询最后一条记录并在插入查询中设置新值
我更喜欢第一个选项--MySQL触发器 - 插入之前。我为此创建了一个触发器。
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');
有人可以在这里建议吗?什么是实现这一目标的最佳和最快的解决方案?
如果有人提供除上述两项以外的更好解决方案,请另外建议。
谢谢
答案 0 :(得分:1)
如果未生成正在生成的项目密钥编号之间的间隙,则可以将新生成的主键值用作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
错误之后的下一个插入请求中,将不会使用先前生成的自动递增和丢弃的值。