programing

MySQL 중복 삽입에서 자동 증분 방지

padding 2023. 8. 6. 09:54
반응형

MySQL 중복 삽입에서 자동 증분 방지

MySQL 5.1.49를 사용하여 두 개의 열이 있는 테이블에 태그 시스템을 구현하려고 합니다.id(autoincrement),tag(unique varchar) (InnoDB)

쿼를사용때할리,,INSERT IGNORE INTO tablename SET tag="whatever" 증분id삽입이 무시된 경우에도 값이 증가합니다.

, 저는 이 표에 을 삽입하려는 합니다. 즉, 저의 인 " 로이되않만지문지대테특, 저는이중삽을많복입하가는려같다다니습과즉값음다다시니음은일합예상도를반은한능적으한정것이은블에제가▁which▁normally▁for▁next▁value같▁my다다니값습▁dupl▁that음과음은▁for▁partic다icates▁but▁attempts▁to▁wouldn▁tableular▁means▁i▁a▁this▁insert▁this즉일'▁expect반▁possible▁lot▁of,,▁aid새 행의 필드가 너무 많이 점프합니다.

예를 들어, 저는 세 줄로 되어 있지만 나쁜 테이블로 끝날 것입니다.id

1   | test
8   | testtext
678 | testtextt

또한, 만약 내가 하지 않는다면,INSERT IGNORE그리고 그냥 규칙적으로 하라.INSERT INTO오류를 처리하면 자동 증분 필드가 계속 증가하므로 다음 참 삽입은 여전히 잘못된 자동 증분입니다.

를 중지할 수 있는 방법이 있습니까?INSERT중복 행 시도?

4이증가하지 으로 MySQL 4.1을 .SELECTMySQL 버전을 다운그레이드하기 위해 태그가 존재하는지 또는 더 나쁜지를 확인하기 위해 미리 설명합니다.

INSERT를 다음과 같이 수정할 수 있습니다.

INSERT INTO tablename (tag)
SELECT $tag
FROM tablename
WHERE NOT EXISTS(
    SELECT tag
    FROM tablename
    WHERE tag = $tag
)
LIMIT 1

에▁where디$tag태그가 없는 경우 추가할 태그(따옴표로 묶이거나 자리 표시자로 지정)입니다.태그가 이미 있는 경우 이 접근 방식은 INSERT(및 그에 따른 자동 증분 폐기)를 트리거하지도 않습니다.당신은 아마도 그것보다 더 좋은 SQL을 생각해 낼 수 있겠지만 위의 것들은 그럴 것입니다.

테이블이 올바르게 인덱싱된 경우 존재 검사를 위한 추가 선택이 빨라지고 데이터베이스는 어쨌든 해당 검사를 수행해야 합니다.

그러나 이 접근 방식은 첫 번째 태그에는 적용되지 않습니다.항상 사용될 것으로 생각되는 태그로 태그 테이블을 시드하거나 빈 테이블을 별도로 확인할 수 있습니다.

방금 이 보석을 발견했어요...

http://www.timrosenblatt.com/blog/2008/03/21/insert-where-not-exists/

INSERT INTO [table name] SELECT '[value1]', '[value2]' FROM DUAL
WHERE NOT EXISTS(
    SELECT [column1] FROM [same table name]
    WHERE [column1]='[value1]'
    AND [column2]='[value2]' LIMIT 1
)

영향을 받는 행 = 1이면 삽입되고, 영향을 받는 행 = 0이면 중복됩니다.

v 5.5용 MySQL 설명서에는 다음과 같은 내용이 나와 있습니다.

"If you use INSERT IGNORE and the row is ignored, the AUTO_INCREMENT counter 
is **not** incremented and LAST_INSERT_ID() returns 0, 
which reflects that no row was inserted."

참조: http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id

버전 5.1 이후 InnoDB에는 자동 증분 잠금이 구성 가능합니다.http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html#innodb-auto-inc 도 참조...

해결 방법: innodb_autoinc_lock_mode=0(추가) 옵션을 사용합니다.

저는 mu가 너무 짧은 답변이지만 빈 테이블에 삽입을 하지 않기 때문에 제한적이라는 것을 알았습니다.저는 간단한 수정이 효과가 있다는 것을 발견했습니다.

INSERT INTO tablename (tag)
SELECT $tag
FROM (select 1) as a     #this line is different from the other answer
WHERE NOT EXISTS(
    SELECT tag
    FROM tablename
    WHERE tag = $tag
)
LIMIT 1

from 절의 테이블을 "가짜" 테이블로 바꾸기(select 1) as a해당 부품이 삽입을 허용한 레코드를 반환하도록 허용했습니다.mysql 5.5.37을 실행하고 있습니다.저를 거기까지 데려다 주셔서 감사합니다.

수락된 답변은 유용했지만, 기본적으로 테이블에 항목이 없으면 선택 항목이 지정된 테이블을 사용하기 때문에 작동하지 않는다는 문제가 발생했습니다. 그래서 대신 테이블이 비어 있더라도 삽입할 다음과 같은 내용을 생각해냈습니다. 또한 테이블을 두 곳에 삽입하고 변수를 삽입하면 됩니다.n 1위, 틀리는 것을 덜합니다.

INSERT INTO database_name.table_name (a,b,c,d)
SELECT 
    i.*
FROM
    (SELECT 
        $a AS a, 
            $b AS b,
            $c AS c,
            $d AS d
            /*variables (properly escaped) to insert*/
    ) i
        LEFT JOIN        
    database_name.table_name o ON i.a = o.a AND i.b = o.b /*condition to not insert for*/
WHERE
    o.a IS NULL
LIMIT 1 /*Not needed as can only ever be one, just being sure*/

유용한 정보를 찾으시길 바랍니다.

언제든지 추가할 수 있습니다.ON DUPLICATE KEY UPDATE 여기를 읽으십시오(정확하게는 아니지만 문제가 해결되는 것 같습니다).

댓글에서, @ravi에 의해.

innodb_autoinc_lock_mode 설정에 따라 증가 여부가 달라집니다.0이 아닌 값으로 설정하면 ON DUPLICATE KEY가 실행되더라도 자동 inc 카운터가 증가합니다.

저도 같은 문제가 있었지만, nodb_autoinc_lock_mode = 0에서 사용하고 싶지 않았습니다. 왜냐하면 제가 마치 호이저로 파리를 죽이는 것처럼 느껴졌기 때문입니다.

이 문제를 해결하기 위해 저는 임시 테이블을 사용하게 되었습니다.

create temporary table mytable_temp like mytable;

그런 다음 다음 값을 삽입했습니다.

insert into mytable_temp values (null,'valA'),(null,'valB'),(null,'valC');

그런 다음 다른 삽입을 수행하지만 중복 항목을 무시하려면 "다음에 없음"을 사용합니다.

insert into mytable (myRow) select mytable_temp.myRow from mytable_temp 
where mytable_temp.myRow not in (select myRow from mytable);

성능 테스트를 해보지는 않았지만, 효과가 있고 읽기 쉽습니다.이는 지속적으로 업데이트되는 데이터를 사용하여 작업했기 때문에 이러한 차이를 무시할 수 없었기 때문에 중요했습니다.

mu에서 답변을 수정했습니다. 저는 초보자이고 그의 답변 아래에 코멘트를 할 수 없기 때문에 (한 줄을 삭제합니다).그냥 여기에 올려주세요.

아래 쿼리는 첫 번째 태그에 대해 작동합니다.

 INSERT INTO tablename (tag)
 SELECT $tag
 WHERE NOT EXISTS(
    SELECT tag
    FROM tablename
    WHERE tag = $tag
)

삽입/업데이트 쿼리 뒤에 추가 문을 추가했습니다: ALTER TABLEtable_nameAUTO_INCREMENT = 1 그런 다음 가장 높은 기본 키 ID + 1을 자동으로 선택합니다.

언급URL : https://stackoverflow.com/questions/5924762/prevent-auto-increment-on-mysql-duplicate-insert

반응형