2017-04-16 1 views
0

bin 열이있는 테이블이 있습니다. 이 표에 삽입 할 때마다 bin은 고유 한 문자 및 숫자 조합이어야합니다. 이러한 의미에서의 독특한 의미는 이전에 다른 행의 표에 나타나지 않았습니다.SQL에서 고유 한 문자/문자열 만들기

binAA00이며, A은 문자 A-F이고 0은 숫자 0-9입니다.

내가이 테이블에 한 번 넣으면 다음과 같이 표시됩니다. 전에 표시되지 않은 bin 값이 있어야한다고 말합니다. 테이블이 비어 있다고 가정하면 binAA11 일 수 있습니다. 2 삽입에,이 표는 단지 ​​3,600 가능한 행들을 포함 할 수있는 문제가되지 않는다

AA00, AA01, ... AA09, AA10, AA11, ... AA99, AB00, AB01, ... AF99, BA00, BA01, ... FF99

AA12하고 AA13을해야한다. 이 코드를 만들려면 bin이 이미 someTable에없는 것을 찾으려면 어떻게해야합니까? 설명 된대로 순서대로 수행하거나 두 번 나타나지 않는 한 임의의 bin 일 수 있습니다.

CREATE TABLE someTable (
    bin VARCHAR(4), 
    someText VARCHAR(32), 
    PRIMARY KEY(bin) 
); 

INSERT INTO someTable 
    VALUES('?', 'a'); 
INSERT INTO someTable 
    VALUES('?', 'b'); 
INSERT INTO someTable 
    VALUES('?', 'c'); 
INSERT INTO someTable 
    VALUES('?', 'd'); 

또는 내가 대신 삽입 아래의 절차를 사용할 수 있습니다 :

CREATE PROCEDURE insert_someTable(tsomeText VARCHAR(32)) 
    BEGIN 
    DECLARE var (VARCHAR(4) DEFAULT (
     -- some code to find unique bin 
    ); 
    INSERT INTO someTable 
     VALUES(var, tsomeText); 
    END 

가능한 결과는 다음과 같습니다 고든의 말처럼

+------+----------+ 
| bin | someText | 
+------+----------+ 
| AB31 | a  | 
| FC10 | b  | 
| BB22 | c  | 
| AF92 | d  | 
+------+----------+ 
+0

응용 프로그램 수준에서 수행하기로 결정하지 않는 한 트리거가 필요합니다. –

답변

1

, 당신은 때문에 트리거를 사용해야합니다 그것은 디폴트에서 간단한 공식으로하기에는 너무 복잡합니다. 상당히 간단해야합니다. 마지막 값 (내림차순, 제한 1)을 가져 와서 값을 증가시킵니다. 알파 문자 때문에 인크 리 멘타를 쓰는 것은 다소 복잡합니다. 응용 프로그램 언어에서는 훨씬 쉬울 것이지만, 테이블 잠금 문제와 두 명의 사용자가 동일한 값을 작성할 가능성에 대해 이야기합니다.

더 나은 방법은 일반적인 자동 증가 기본 키를 사용하여 이진 값으로 변환하는 것입니다. bin 값을 2 개의 기본 6 개의 문자와 2 개의 기본 10 개의 값으로 간주하십시오. 그런 다음 MySQL이 생성 한 ID를 고유하게 사용하도록 보장하고 특수 번호 시스템으로 변환합니다. bin을 계산하여 bin 열에 저장하십시오. - 당신에게 마지막 두 자리 숫자를 제공합니다 하나는 진수의 낮은 100 값 (모드 100)을 얻을 것

  1. 단계 :

    는 빈을 계산합니다. 선행 0으로 varchar로 변환하십시오.
  2. id에서 빼고 첫 번째 두 자리의 값을 얻기 위해 100으로 나눕니다.
  3. mod 6 값을 가져 와서 오른쪽에서 3 번째 숫자를 결정하십시오. 인덱스로 A-F로 변환하십시오.
  4. ID의 왼쪽부터 빼고 6으로 나누어 네 번째 숫자 (오른쪽부터)를 얻습니다. 인덱스로 A-F로 변환하십시오.
  5. 세 개의 결과를 함께 연결하여 bin 값을 구성하십시오.

테이블 이름과 열 이름을 일치시키기 위해 다음을 편집해야 할 수도 있지만 그렇게해야합니다.한 가지 가능한 개선 사항은 3600 제한을 초과하는 삽입을 취소하는 것입니다. 3600 번째 레코드를 삽입하면 이전 bin 값이 복제됩니다. 또한 AA00 (id = 1 = 'AA01')을 삽입하지 않으므로 완벽하지는 않습니다. 마지막으로 bin에 고유 인덱스를 넣으면 중복을 방지 할 수 있습니다.

DELIMITER $$ 

CREATE TRIGGER `fix_bin` 
BEFORE INSERT ON `so_temp` 
FOR EACH ROW 
BEGIN 
    DECLARE next_id INT; 
    SET next_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='so_temp'); 
    SET @id = next_id; 
    SET @Part1 = MOD(@id,100); 
    SET @Temp1 = FLOOR((@id - @Part1)/100); 
    SET @Part2 = MOD(@Temp1,6); 
    SET @Temp2 = FLOOR((@Temp1 - @Part2)/6); 
    SET @Part3 = MOD(@Temp2,6); 

    SET @DIGIT12 = RIGHT(CONCAT("00",@Part1),2); 
    SET @DIGIT3 = SUBSTR("ABCDEF",@Part2 + 1,1); 
    SET @DIGIT4 = SUBSTR("ABCDEF",@Part3 + 1,1); 
    SET NEW.`bin` = CONCAT(@DIGIT4,@DIGIT3,@DIGIT12); 
END; 
$$ 

DELIMITER ; 
관련 문제