MySQL 테이블 기본 키를 일부 접두사로 자동 증가시키는 방법


80

이런 테이블이 있어요

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

'LHPL001','LHPL002','LHPL003'... 등과 같이 내 ID 필드를 늘리고 싶습니다 . 어떻게해야합니까? 가능한 방법을 알려주십시오.


이를 위해 다른 열을 추가하기 만하면됩니다. 데이터베이스에 "다른 종류의"ID 필드가있는 것은 완전히 정상입니다.
Fattie 20.01.29

답변:


135

이것이 정말로 필요하다면 시퀀싱을위한 별도의 테이블과 트리거를 사용하여 목표를 달성 할 수 있습니다.

테이블

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 | Jhon |
| LHPL002 | 마크 |

다음은 SQLFiddle 데모입니다.


트리거 내의 문은 원자 적입니까? 즉, INSERT와 SET 사이에 다른 스레드 / 요청이 table1_seq에 삽입되어 LAST_INSERT_ID ()가 BEGIN / END 내에 삽입 된 요청이 아닌 다른 요청의 ID를 반환 할 수 있습니다.
n00b

@peterm, 의심스러운 트리거 부분이 있습니다. 나는 SET NEW.id = CONCAT ( 'A', LPAD (LAST_INSERT_ID (), 4, '500')); 내 ID가 5001에서 시작해야하므로 500을 설정했습니다. 따라서 올바른 출력 A5001이 표시됩니다. 내 의심은 이드가 5999에 도달하면 다음 이드는 무엇입니까? 6000입니까?
user9437856

데이터베이스에 레코드를 추가 한 후 1000 개 이상의 레코드를 추가하고 5999 개 이후에 내 ID 값이 V1000에서 시작하는 것은 완전히 잘못된 것입니다. 6000,6001,6002 등등 계속되어야합니다. 이것에 대한 어떤 생각?
user9437856

18

일반 숫자 auto_increment ID로 테이블을 생성하지만으로 정의 ZEROFILL하거나 LPAD선택할 때 0을 추가 하는 데 사용 합니다. 그런 다음 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;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.