如何使用某些前缀使 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 表主键自动递增的主要内容,如果未能解决你的问题,请参考以下文章