MySQL에서 고유 ID를 생성하는 방법은?
PHP MySQL ID(됨: 를) 와 같은 .gHYtUUi5b
할 수 PHP에서 그런 숫자를 생성할 수 있는 기능들을 많이 찾았는데 ID가 고유한지 어떻게 해야 할지 두렵습니다!
업데이트: uuid는 깁니다. 즉, (P5Dc) 11자의 영숫자를 의미합니다.
편집: 이 답변은 데이터베이스를 파괴하는 상황에서 위험하다는 플래그가 지정되었습니다.데이터베이스에서 고유 ID를 생성할 때 이 코드를 사용하지 마십시오!
UUID()를 사용하여 고유 값을 만듭니다.
예:
insert into Companies (CompanyID, CompanyName) Values(UUID(), "TestUUID");
당신은 우리가 하는 방식을 좋아할 것입니다.저는 꽤 흔한 문제인 "무작위"로 보이는 가역적인 고유 코드를 원했습니다.
- 우리는 1,942와 같은 입력 번호를 받습니다.
- 왼쪽 패드를 문자열로 "0000001942".
- 마지막 두 자리를 앞으로 내세요: "4200000019"
- 숫자로 변환: 4,200,000,019
우리는 이제 통화마다 엄청난 차이가 있고 100,000,000,000 미만이 보장되는 숫자를 갖게 되었습니다.나쁘지 않은 시작입니다.
- 이 숫자를 기본 34 문자열로 변환합니다. "2oevc0b"
- 임의의 0을 'y'로 바꾸고 임의의 0을 'z'로 바꿉니다: "2oevcyb"
- 업시프트: "2OEVCYB"
base 34를 선택한 이유는 0/O 및 1/l 충돌을 걱정하지 않기 위해서입니다.이제 긴 데이터베이스 식별자를 조회하는 데 사용할 수 있는 짧은 임의로 보이는 키가 있습니다.
프로그래밍 방식은 다음과 같습니다.
- 필드에 유니크 인덱스 추가
- PHP에서 랜덤 문자열을 생성합니다.
- 루프 인 PHP (while(! DO_THE_INSERT ))
- 다른 문자열을 생성합니다.
참고:
- 이는 더러울 수 있지만 DBMS와 무관하다는 장점이 있습니다.
- DBMS 고유 ID 생성기 함수(UUID 등)를 사용하도록 선택한 경우에도 인덱스를 사용하여 필드가 고유해야 함을 보장하는 것이 좋습니다.
- 루프는 통계적으로 전혀 실행되지 않으며 삽입 실패 시에만 입력됩니다.
버전이 5.7.4보다 높은 MySQL을 사용하는 경우 새로 추가된 RANDOM_BYTES 함수를 사용할 수 있습니다.
SELECT TO_BASE64(RANDOM_BYTES(16));
됩니다와 됩니다.GgwEvafNLWQ3+ockEST00A==
.
unique_ids를 생성하는 방법은 유용한 질문이지만 생성 시기에 대한 생산적인 가정을 하고 있는 것 같습니다.
제 요점은 행을 생성할 때 이러한 고유 ID를 생성할 필요가 없다는 것입니다. 왜냐하면 이 ID들은 삽입되는 데이터와 본질적으로 독립적이기 때문입니다.
제가 하는 일은 미래에 사용할 수 있도록 고유 ID를 미리 생성하는 것입니다. 그렇게 하면 저만의 달콤한 시간을 가질 수 있고 고유하다는 것을 절대적으로 보장할 수 있고, 삽입할 때 수행해야 할 처리가 없습니다.
예를 들어 order_id가 포함된 주문 테이블이 있습니다.이 ID는 사용자가 주문을 입력하면 즉시 생성됩니다. 증분으로 1,2,3 등.사용자는 이 내부 ID를 볼 필요가 없습니다.
그러면 unique_ids 와 (order_id, unique_id)가 있는 다른 테이블이 있습니다.저는 매일 밤 이 테이블에 unique_id 행을 미리 로드하여 향후 24시간 안에 삽입될 수 있는 주문을 처리하는 루틴이 있습니다. (하루에 100,000개의 주문이 들어오면 문제가 발생하지만, 이는 좋은 문제입니다!)
이 접근 방식은 고유성을 보장하며, 사용자에게 영향을 미치지 않는 배치 루틴 및 삽입 트랜잭션에서 모든 처리 부하를 제거합니다.
UUID 함수를 사용합니다.
저는 당신의 프로시저가 고유한 값을 생성하는 PHP의 출처를 모릅니다.만약 그것이 도서관 기능이라면 그들은 당신의 가치가 정말로 독특하다는 것을 보장해야 합니다.문서를 체크인합니다.당신은 이 기능을 항상 사용해야 합니다.예를 들어 PHP 함수를 사용하여 고유 값을 생성한 다음 MySQL 함수를 사용하기로 결정하면 이미 존재하는 값을 생성할 수 있습니다.이 경우 열에 UNIQUE INDEX를 넣는 것도 좋습니다.
DELIMITER $$
USE `temp` $$
DROP PROCEDURE IF EXISTS `GenerateUniqueValue`$$
CREATE PROCEDURE `GenerateUniqueValue`(IN tableName VARCHAR(255),IN columnName VARCHAR(255))
BEGIN
DECLARE uniqueValue VARCHAR(8) DEFAULT "";
DECLARE newUniqueValue VARCHAR(8) DEFAULT "";
WHILE LENGTH(uniqueValue) = 0 DO
SELECT CONCAT(SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1)
) INTO @newUniqueValue;
SET @rcount = -1;
SET @query=CONCAT('SELECT COUNT(*) INTO @rcount FROM ',tableName,' WHERE ',columnName,' like ''',newUniqueValue,'''');
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
IF @rcount = 0 THEN
SET uniqueValue = @newUniqueValue ;
END IF ;
END WHILE ;
SELECT uniqueValue;
END$$
DELIMITER ;
그리고 저장 프로시저를 GenerateUniqueValue('tableName', 'columnName')라고 부릅니다.이렇게 하면 매번 8자리 고유의 캐릭터가 나옵니다.
고유하고 무작위하게 보이는 토큰을 얻으려면 기본 키를 암호화하면 됩니다.
SELECT HEX(AES_ENCRYPT(your_pk,'your_password')) AS 'token' FROM your_table;
이 정도면 충분하고 가역적이기 때문에 테이블에 토큰을 저장할 필요가 없고 대신 생성해야 합니다.
또 다른 장점은 토큰에서 PK를 해독하면 테이블 위에서 많은 양의 전체 텍스트 검색을 수행할 필요가 없고 단순하고 빠른 PK 검색을 수행할 수 있다는 것입니다.
하지만 한가지 작은 문제가 있습니다.MySql은 다른 블록 암호화 모드를 지원하므로 변경하면 토큰 공간이 완전히 변경되어 오래된 토큰을 사용할 수 없게 됩니다.
이를 극복하기 위해 토큰을 생성하기 전에 변수를 설정할 수 있습니다.
SET block_encryption_mode = 'aes-256-cbc';
하지만 그건 좀 아까운데...이를 위한 해결책은 토큰에 마커를 사용한 암호화 모드를 부착하는 것입니다.
SELECT CONCAT(CONV(CRC32(@@GLOBAL.block_encryption_mode),10,35),'Z',HEX(AES_ENCRYPT(your_pk,'your_password'))) AS 'token' FROM your_table;
테이블에서 토큰을 계속 사용하려면 다른 문제가 발생할 수 있습니다.INSERT
생성하려면 아직 삽입되지 않은 레코드에 대해 primary_key를 알아야 하기 때문에...물론 당신은 그냥INSERT
그리고 나서.UPDATE
와 함께LAST_INSERT_ID()
다시 말하지만 - 더 나은 해결책이 있습니다.
INSERT INTO your_table ( token )
SELECT CONCAT(CONV(CRC32(@@GLOBAL.block_encryption_mode),10,35),'Z',HEX(AES_ENCRYPT(your_pk,'your_password'))) AS 'token'
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = "your_table";
이 솔루션의 마지막 장점은 php, python, js 또는 사용할 수 있는 다른 언어로 쉽게 복제할 수 있다는 것입니다.
아래는 숫자 고유 랜덤 ID...를 참조하기 위한 것입니다.
도움이 될지도...
$query=mysql_query("select * from collectors_repair");
$row=mysql_num_rows($query);
$ind=0;
if($row>0)
{
while($rowids=mysql_fetch_array($query))
{
$already_exists[$ind]=$rowids['collector_repair_reportid'];
}
}
else
{
$already_exists[0]="nothing";
}
$break='false';
while($break=='false'){
$rand=mt_rand(10000,999999);
if(array_search($rand,$alredy_exists)===false){
$break='stop';
}else{
}
}
echo "random number is : ".$echo;
그리고 ->와 같은 코드로 char를 추가할 수 있습니다.$rand=mt_rand(10000,999999) .$randomchar; // assume $radomchar contains char;
고유성을 위해 유닉스 타임스탬프를 가져다가 임의의 문자열을 추가하여 사용합니다.
crypt()
제안한 대로 salt를 일부 구성 파일에 저장하고 salt를 1부터 시작하고 중복되는 것을 발견하면 다음 값 2로 이동합니다.두 개의 차를 사용할 수 있지만, 소금을 넣기에 충분한 조합이 됩니다.
문자열을 생성할 수 있습니다.openssl_random_pseudo_bytes(8)
. 따라서 이것은 임의적이고 짧은 문자열(11 char)을 제공해야 합니다.crypt()
.
결과에서 소금을 제거하면 무작위로 실패할 때마다 소금을 바꾸면 1억 개 이상의 사람들이 충분히 무작위해야 할 11개의 문자만 있을 것입니다.
사용하는 것도 고려해 볼 수 있습니다.crypt()
*제약 조건 내에 [거의 보장된] 고유 ID를 생성합니다.
<?php
$hostname_conn = "localhost";
$database_conn = "user_id";
$username_conn = "root";
$password_conn = "";
$conn = mysql_pconnect($hostname_conn, $username_conn, $password_conn) or trigger_error(mysql_error(),E_USER_ERROR);
mysql_select_db($database_conn,$conn);
// run an endless loop
while(1) {
$randomNumber = rand(1, 999999);// generate unique random number
$query = "SELECT * FROM tbl_rand WHERE the_number='".mysql_real_escape_string ($randomNumber)."'"; // check if it exists in database
$res =mysql_query($query,$conn);
$rowCount = mysql_num_rows($res);
// if not found in the db (it is unique), then insert the unique number into data_base and break out of the loop
if($rowCount < 1) {
$con = mysql_connect ("localhost","root");
mysql_select_db("user_id", $con);
$sql = "insert into tbl_rand(the_number) values('".$randomNumber."')";
mysql_query ($sql,$con);
mysql_close ($con);
break;
}
}
echo "inserted unique number into Data_base. use it as ID";
?>
사용하기
$info = random_bytes(16);
$info[6] = chr(ord($info[6]) & 0x0f | 0x40);
$info[8] = chr(ord($info[8]) & 0x3f | 0x80);
$result =vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($info), 4));
return $result;
이렇게 하면 랜덤 ID가 생성됩니다.
CREATE TABLE Persons (
ID Integer PRIMARY KEY AUTOINCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
트위터의 눈송이를 사용할 수 있습니다.
즉, 시간, 서버 ID, 시퀀스를 기반으로 고유 ID를 생성합니다.64비트 값을 생성하므로 상당히 작고 INT64에 적합합니다.값을 올바르게 정렬할 수도 있습니다.
https://developer.twitter.com/en/docs/basics/twitter-ids
요약하면 여러 대의 서버, 높은 동시성, 정렬 값 등을 모두 64비트로 처리할 수 있습니다.
여기 MySQL에 대한 구현이 있습니다.
https://github.com/EFTEC/snowflake-mysql
함수와 표로 구성되어 있습니다.
검색한 결과 이 기사를 발견했습니다.
계획 A: UUID 또는 GUID.
플랜 B: 랜드:
SELECT FLOOR(rand() * 90000 + 10000);
계획 C: 전체 MD5:
SELECT MD5(NOW());
계획 D: MD5의 일부:
SELECT LEFT(MD5(NOW()), 4);
계획 E: 암호화/복호화
SELECT HEX(AES_ENCRYPT(123, 'foo'));
SELECT AES_DECRYPT(UNHEX('C7FC2E77A3D894D2BA02F2214E37F107'), 'foo');
언급URL : https://stackoverflow.com/questions/1467581/how-to-generate-unique-id-in-mysql
'code' 카테고리의 다른 글
HTML 테이블에서 실시간 검색 및 필터링을 수행하는 방법 (0) | 2023.09.25 |
---|---|
Oracle Database의 데이터를 사용한 Visual Studio 2015 웹 테스트 (0) | 2023.09.25 |
PHP 디버깅은 어떻게 하나요? (0) | 2023.09.25 |
SQL 결과가 서로 옆에 있습니다. (0) | 2023.09.25 |
'Method' get_을 수정하는 방법정보'를 'Oracle' 유형으로 입력합니다.EntityFrameworkCore에는 구현이 없습니다.' (0) | 2023.09.25 |