php - 为 MySQL 中的列生成一个带有整数的唯一字符串作为后缀

标签 php mysql

我想为 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/

相关文章:

javascript - 使用javascript上传图片

php - 我的查询中存在语法错误

mysql - 如何使用mysql在给定日期中按另一列查找列组

mysql STR_TO_DATE 不工作

php - 无法使用 php 从数据库中删除特定行

javascript - 自动完成中的数组不显示任何内容

phpmyadmin sql删除帮助表中的所有表

php - Mysql从多个表中选择,每个月创建一个新表

mysql - 在 MySQL 中,我如何通过不同的列和公用键按日期获取最新记录?

php - 使用 MySQLi 将行插入 MySQL 数据库