如何使用某些前缀使 MySQL 表主键自动递增

Posted

技术标签:

【中文标题】如何使用某些前缀使 MySQL 表主键自动递增【英文标题】:How to make MySQL table primary key auto increment with some prefix 【发布时间】:2013-07-27 11:15:47 【问题描述】:

我有这样的桌子

table
id Varchar(45) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name CHAR(30) NOT NULL,

我想增加我的 id 字段,例如 'LHPL001','LHPL002','LHPL003'... 等。 我应该为此做些什么?请让我知道任何可能的方式。

【问题讨论】:

只需添加另一列即可。在数据库中有“不同种类”的 ID 字段是完全正常的。 【参考方案1】:

如果您真的需要这个,您可以借助单独的排序表(如果您不介意的话)和触发器来实现您的目标。

表格

CREATE TABLE table1_seq
(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE table1
(
  id VARCHAR(7) NOT NULL PRIMARY KEY DEFAULT '0', name VARCHAR(30)
);

现在触发

DELIMITER $$
CREATE TRIGGER tg_table1_insert
BEFORE INSERT ON table1
FOR EACH ROW
BEGIN
  INSERT INTO table1_seq VALUES (NULL);
  SET NEW.id = CONCAT('LHPL', LPAD(LAST_INSERT_ID(), 3, '0'));
END$$
DELIMITER ;

然后你只需在 table1 中插入行

INSERT INTO Table1 (name) 
VALUES ('Jhon'), ('Mark');

你将拥有

|身份证 |姓名 | ------------------ | LHPL001 |约翰 | | LHPL002 |马克 |

这里是SQLFiddle演示

【讨论】:

触发器中的语句是原子的吗? IE。是否有可能在 INSERT 和 SET 之间另一个线程/请求插入 table1_seq 导致 LAST_INSERT_ID() 返回另一个请求的 id,而不是在 BEGIN/END 中插入的那个。 @peterm,我对触发部分有疑问。我改变了 SET NEW.id = CONCAT('A', LPAD(LAST_INSERT_ID(), 4, '500'));因为我需要我的 id 从 5001 开始,所以我设置了 500。所以我得到了正确的输出 A5001。我的疑问是一旦 id 达到 5999 那么下一个 id 会是什么?是6000吗? 我在数据库中添加记录后尝试了自己,我添加了 1000 多条记录,在 5999 之后我的 id 值从 V1000 开始,这是完全错误的。我需要的应该是续6000、6001、6002等等。有什么想法吗?【参考方案2】:

使用普通数字 auto_increment ID 创建一个表,但要么使用ZEROFILL 定义它,要么使用LPAD 在选择时添加零。然后CONCAT 值来获得您的预期行为。示例 #1:

create table so (
 id int(3) unsigned zerofill not null auto_increment primary key,
 name varchar(30) not null
);

insert into so set name = 'John';
insert into so set name = 'Mark';

select concat('LHPL', id) as id, name from so;
+---------+------+
| id      | name |
+---------+------+
| LHPL001 | John |
| LHPL002 | Mark |
+---------+------+

示例 #2:

create table so (
 id int unsigned not null auto_increment primary key,
 name varchar(30) not null
);

insert into so set name = 'John';
insert into so set name = 'Mark';

select concat('LHPL', LPAD(id, 3, 0)) as id, name from so;
+---------+------+
| id      | name |
+---------+------+
| LHPL001 | John |
| LHPL002 | Mark |
+---------+------+

【讨论】:

最初我想将 LHPL 存储为一个单独的列,然后通过 concat(col1,col2) 连接它,但是当有一天我需要更改 LHPL 时,它会在 S 中变得很痛苦。所以我想我会在程序服务器端做。【参考方案3】:

我知道已经晚了,但我只是想分享一下我为此做了什么。我不允许添加另一个表或触发器,因此我需要在插入时在单个查询中生成它。对于你的情况,你可以试试这个查询吗?

CREATE TABLE YOURTABLE(
IDNUMBER VARCHAR(7) NOT NULL PRIMARY KEY,
ENAME VARCHAR(30) not null
);

执行选择并使用此选择查询并保存到参数@IDNUMBER

(SELECT IFNULL
     (CONCAT('LHPL',LPAD(
       (SUBSTRING_INDEX
        (MAX(`IDNUMBER`), 'LHPL',-1) + 1), 5, '0')), 'LHPL001')
    AS 'IDNUMBER' FROM YOURTABLE ORDER BY `IDNUMBER` ASC)

然后插入查询将是:

INSERT INTO YOURTABLE(IDNUMBER, ENAME) VALUES 
(@IDNUMBER, 'EMPLOYEE NAME');

结果将与其他答案相同,但不同之处在于,您不需要创建另一个表或触发器。希望能帮到和我有同样情况的人。

【讨论】:

【参考方案4】:

如果有人在 PostgreSQL 上需要它,这里是没有触发器的 PostgreSQL 示例:

CREATE SEQUENCE messages_seq;

 CREATE TABLE IF NOT EXISTS messages (
    id CHAR(20) NOT NULL DEFAULT ('message_' || nextval('messages_seq')),
    name CHAR(30) NOT NULL,
);

ALTER SEQUENCE messages_seq OWNED BY messages.id;

【讨论】:

以上是关于如何使用某些前缀使 MySQL 表主键自动递增的主要内容,如果未能解决你的问题,请参考以下文章

mysql表主键从给定值开始自动增长是怎么回事?

为啥我的 MySQL 表主键不会自动增加?

如何将数据插入具有自动递增主键的 MySQL?

mysql 如何修改 删除 添加 表主键

Android Room - 如何在每个应用程序运行时重置自动生成的表主键

如何使主键以特定字母开头?