如何使MySQL表主键自动增加一些前缀


80

我有这样的桌子

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

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


只需添加另一列即可。在数据库中具有“不同种类”的ID字段是完全正常的。
Fattie

Answers:


133

如果您确实需要此功能,则可以借助单独的表进行排序(如果您不介意的话)和触发器来实现您的目标。

桌子

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');

然后你会

| ID | NAME |
------------------
| LHPL001 | 俊|
| LHPL002 | 马克|

这是SQLFiddle演示


触发器内的语句是原子的吗?也就是说,在INSERT和SET之间可能有另一个线程/请求插入到table1_seq中,从而导致LAST_INSERT_ID()返回另一个请求的ID,而不是在BEGIN / END中插入的请求。
n00b

@peterm,我怀疑触发部分。我更改了SET NEW.id = CONCAT('A',LPAD(LAST_INSERT_ID(),4,'500')); 因为我需要我的id从5001开始,所以我设置了500。所以我得到了正确的输出A5001。我的疑问是,一旦ID达到5999,那么下一个ID是什么?是6000吗?
user9437856 '18

在数据库中添加记录后,我尝试了自我,添加了1000条以上的记录,在5999之后,我的id值从V1000开始,这是完全错误的。我需要将其继续为6000,6001,6002,依此类推。有什么想法吗?
user9437856 '18

17

创建具有正常数字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带来麻烦。因此,我想我将在程序服务器端进行此操作。
4

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');

结果将与其他答案相同,但不同之处在于,您将不需要创建另一个表或触发器。我希望我可以帮助与我有相同案件的人。


0

如果有人在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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.