source

"무시 삽입" vs "삽입...중복된 키 업데이트 시"

lovecheck 2022. 10. 19. 21:13
반응형

"무시 삽입" vs "삽입...중복된 키 업데이트 시"

" " " "INSERT행이 많은 스테이트먼트에서는, 중복하는 엔트리는 생략해 주세요.그렇지 않으면 에러가 발생할 수 있습니다.조사한 , 중 하나를 할 수 것 같습니다.

  • ON DUPLICATE KEY UPDATE, 불필요한 이 어떤 한 갱신을 합니다.또는
  • INSERT IGNORE다른 종류의 실패가 예고도 없이 들어오는 것에 대한 초대를 의미합니다.

이 가정들이 맞습니까?중복이 발생할 수 있는 행을 건너뛰고 다른 행으로 넘어가는 가장 좋은 방법은 무엇입니까?

를 사용하는 것을 추천합니다.INSERT...ON DUPLICATE KEY UPDATE.

「 」를 사용하고 INSERT IGNORE그러면 중복 키가 생성될 경우 행이 실제로 삽입되지 않습니다.하지만 이 문장은 오류를 생성하지 않습니다.대신 경고가 생성됩니다.예를 들어 다음과 같습니다.

  • " " 가 붙은 열에 키 :PRIMARY KEY ★★★★★★★★★★★★★★★★★」UNIQUE★★★★★★ 。
  • 을 NULL로 에 삽입합니다.NOT NULL약이있있 있있있다다
  • 분할된 테이블에 행을 삽입하지만 삽입한 값이 분할된 테이블에 매핑되지 않습니다.

「 」를 사용하고 REPLACE을 실행합니다DELETEINSERT치 않은.

  • 새로운 자동 증분 ID가 할당됩니다.
  • 종속 키를 사용하는 ), """ " " " " " " " " " " " " " " " " " " " 가 됩니다.REPLACE.
  • 에 대한 발화 트리거합니다.DELETE불필요하게 실행됩니다.
  • 부작용은 복제품에도 전파된다.

수정: 둘 다REPLACE ★★★★★★★★★★★★★★★★★」INSERT...ON DUPLICATE KEY UPDATE입니다.은 ANSI SQL 2003을 합니다.MERGE 그 이상)를 할 수 은 MySQL을 .MERGE★★★★★★ 。


사용자가 이 게시물을 편집하려고 했습니다(모델레이터에 의해 편집이 거부되었습니다).편집자는 다음과 같은 주장을 추가하려고 했습니다.INSERT...ON DUPLICATE KEY UPDATE를 지정하면 새로운 자동 인식 ID가 할당됩니다.새 ID가 생성된 것은 맞지만 변경된 행에서는 사용되지 않습니다.

Percona Server 5.5.28입니다. 변수 " " "innodb_autoinc_lock_mode=1 (디폴트):

mysql> create table foo (id serial primary key, u int, unique key (u));
mysql> insert into foo (u) values (10);
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   10 |
+----+------+

mysql> show create table foo\G
CREATE TABLE `foo` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `u` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

mysql> insert into foo (u) values (10) on duplicate key update u = 20;
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   20 |
+----+------+

mysql> show create table foo\G
CREATE TABLE `foo` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `u` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

위의 을 검출하고 하여 ""의 하는 것을 .u 「 」에해 주세요.AUTO_INCREMENT=3ID가 생성되었지만 행에서 사용되지 않았음을 나타냅니다.

반에 whereas whereas.REPLACE는 원래 행을 삭제하고 새로운 행을 삽입하여 새로운 자동 갱신 ID를 생성하고 저장합니다.

mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   20 |
+----+------+
mysql> replace into foo (u) values (20);
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  3 |   20 |
+----+------+

이 모든 것이 무엇을 의미하는지 알고 싶으시다면, 여기 모든 것에 대한 자세한 내용이 있습니다.

CREATE TABLE `users_partners` (
  `uid` int(11) NOT NULL DEFAULT '0',
  `pid` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`uid`,`pid`),
  KEY `partner_user` (`pid`,`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

기본 키는 이 빠른 참조 테이블의 두 열을 모두 기반으로 합니다.기본 키에는 고유한 값이 필요합니다.

시작합시다.

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...1 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1);
...0 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1) ON DUPLICATE KEY UPDATE uid=uid
...0 row(s) affected

상기 컬럼을 자신과 동일하게 설정함으로써 추가 작업이 너무 많이 절약되었습니다.실제로 갱신은 필요 없습니다.

REPLACE INTO users_partners (uid,pid) VALUES (1,1)
...2 row(s) affected

이제 몇 가지 다중 행 테스트:

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...3 row(s) affected

콘솔에는 다른 메시지가 생성되지 않았으며 테이블 데이터에는 이 4개의 값이 포함되어 있습니다.(1,1)을 제외한 모든 것을 삭제하여 동일한 영역에서 테스트 가능

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4) ON DUPLICATE KEY UPDATE uid=uid
...3 row(s) affected

REPLACE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...5 row(s) affected

자, 여기 있네요.이 모든 작업은 거의 데이터가 없고 실제 가동되지 않은 새로운 테이블에서 수행되었기 때문에, 실행 시간은 매우 미묘하고 무관했습니다.실제 데이터를 가진 사람이라면 누구나 기꺼이 기부를 할 것입니다.

추가할 중요한 사항:INSERT IGNORE를 사용할 때 키 위반이 있는 경우 MySQL은 경고를 발생시키지 않습니다!

예를 들어 장애가 있는 레코드를 100개씩 삽입하려고 하면 인터랙티브모드가 됩니다

Query OK, 99 rows affected (0.04 sec)

Records: 100 Duplicates: 1 Warnings: 0

보시는 바와 같이:경고 없음!이 동작은 공식 Mysql 문서에도 잘못 기재되어 있습니다.

스크립트에 통지가 필요한 경우 (키 위반으로 인해) 일부 레코드가 추가되지 않은 경우 mysql_info()를 호출하여 "Duplates" 값을 해석해야 합니다.

는 일상적으로 사용해요.INSERT IGNORE그리고 그건 당신이 찾고 있는 행동처럼 들립니다.인덱스 경합을 일으킬 행이 삽입되지 않고 그에 따라 프로그램을 계획하기만 하면 문제가 발생하지 않습니다.

위에서 설명한 바와 같이 INSERT를 사용하면..IGNORE, INSERT 문 실행 중 발생한 오류는 경고로 처리됩니다.

한 가지 명시적으로 언급되지 않은 것은 INSERT입니다.IGNORE를 사용하면 삽입 시 비활성값이 가장 가까운 값으로 조정됩니다(IGNORE 키워드를 사용하지 않을 경우 비활성값으로 인해 쿼리가 중단됩니다).

Replace 인투는 옵션인 것 같아요.또는 다음 주소로 확인하실 수 있습니다.

IF NOT EXISTS(QUERY) Then INSERT

이렇게 하면 삽입 또는 삭제 후 삽입됩니다.는...을 좋아하는 입니다.IF NOT EXISTS먼저 확인합니다.

INSERT IGNORE(삽입 무시)의 잠재적 위험이 있습니다.VARCHAR 값을 더 길게 삽입하려고 할 경우 컬럼은 다음과 같이 정의됩니다.완전 모드가 네이블이 되어 있어도 값이 잘리고 삽입됩니다.

ON DUPLICE KEY UPDATE는 표준이 아닙니다.REPLACE와 거의 같은 수준입니다.SQL MERGE를 참조하십시오.

기본적으로 두 명령어 모두 표준 명령어 대체 구문 버전입니다.

여기에다가.둘 다 사용하면 INSERT IGNORE ★★★★★★★★★★★★★★★★★」ON DUPLICATE KEY UPDATE같은 스테이트먼트에서 삽입이 중복된 키를 발견해도 갱신은 계속됩니다.., ignore., ignore.보다 우선합니다.에 ᄃ자일 ,ON DUPLICATE KEY UPDATE 키 오류가 하므로 이 됩니다.

이 문제는 여러 개의 고유 키가 있거나 업데이트가 외부 키 제약 조건을 위반하려고 할 때 발생할 수 있습니다.

CREATE TABLE test 
 (id BIGINT (20) UNSIGNED AUTO_INCREMENT, 
  str VARCHAR(20), 
  PRIMARY KEY(id), 
  UNIQUE(str));

INSERT INTO test (str) VALUES('A'),('B');

/* duplicate key error caused not by the insert, 
but by the update: */
INSERT INTO test (str) VALUES('B') 
 ON DUPLICATE KEY UPDATE str='A'; 

/* duplicate key error is suppressed */
INSERT IGNORE INTO test (str) VALUES('B') 
 ON DUPLICATE KEY UPDATE str='A';

「 」를 하고 있는 insert ignore having having havingSHOW WARNINGS;쿼리 세트의 끝에 있는 문에는 중복된 ID를 포함하여 모든 경고가 포함된 테이블이 표시됩니다.

INSERT...ON DUPLICATE KEY UPDATE예기치 않은 예외 관리를 방지하기 위해 를 사용하는 것이 좋습니다.

이 솔루션은 **1의 고유한 제약조건**이 있는 경우에만 작동합니다.

는 알고 .col1 ★★★★★★★★★★★★★★★★★」col2고유한 복합 인덱스를 만듭니다.

오류를 추적하지만 중복 시 예외가 발생하지는 않습니다.퍼포먼스에 관해서는 MySQL이 이를 인지하고 업데이트하지 않는 과 같은 값의 업데이트가 효율적입니다.

INSERT INTO table
  (col1, col2, col3, col4)
VALUES
  (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
    col1 = VALUES(col1),
    col2 = VALUES(col2)

이 접근방식을 사용하는 아이디어는 phpdelusions.net/pdo의 코멘트에서 나왔습니다.

테이블에 삽입할 경우 기본 키 또는 고유 인덱스의 충돌에 대해 해당 행을 삽입하는 대신 충돌하는 행을 업데이트합니다.

구문:

insert into table1 set column1 = a, column2 = b on duplicate update column2 = c;

여기서 이 삽입문은 앞에서 본 것과 다를 수 있습니다.이 삽입문은 a와 b의 값을 가진 행을 각각 column1과 column2에 삽입하려고 합니다.

다음 문장을 자세히 이해합시다.

예를 들어, 여기서 column1은 table1의 프라이머리 키로 정의됩니다.

이제 표 1에 열 1에 값 "a"를 가진 행이 없는 경우.따라서 이 문은 table1에 행을 삽입합니다.

표 1에 열 2에 값 "a"를 가진 행이 있는 경우.따라서 이 문은 column1 값이 "a"인 행의 column2 값을 "c"로 업데이트합니다.

따라서 새 행을 삽입하지 않으면 기본 키 또는 고유 인덱스의 충돌에 대해 해당 행을 업데이트합니다.
은 이 에서 확인하시기 바랍니다.

언급URL : https://stackoverflow.com/questions/548541/insert-ignore-vs-insert-on-duplicate-key-update

반응형