인터넷 검색으로 시작하여 뮤텍스 테이블에 대해 이야기하는 이 기사 를 찾았습니다 .
~ 1400 만 개의 레코드가있는 테이블이 있습니다. 동일한 형식으로 더 많은 데이터를 추가하려면 한 쌍의 쿼리를 사용하지 않고 삽입하려는 레코드가 없는지 확인하는 방법이 있습니까? 빈)?
unique
필드에 대한 제약 insert
이 이미 존재하는 경우 실패를 보장 합니까?
PHP를 통해 삽입을 발행하면 스크립트가 잠기는 것처럼 단지 제약 조건 이있는 것 같습니다 .
답변
사용하다 INSERT IGNORE INTO table
http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html 참조
INSERT … ON DUPLICATE KEY UPDATE
구문 도 있습니다. dev.mysql.com에서 설명을 찾을 수 있습니다.
Google의 웹 캐시에 따라 bogdan.org.ua에서 게시 :
2007 년 10 월 18 일
시작하려면 : 최신 MySQL부터는 제목에 표시된 구문이 불가능합니다. 그러나 기존 기능을 사용하여 예상되는 것을 달성하는 매우 쉬운 방법이 몇 가지 있습니다.
중복 키 업데이트에 INSERT IGNORE, REPLACE 또는 INSERT…
테이블이 있다고 상상해보십시오.
CREATE TABLE `transcripts` ( `ensembl_transcript_id` varchar(20) NOT NULL, `transcript_chrom_start` int(10) unsigned NOT NULL, `transcript_chrom_end` int(10) unsigned NOT NULL, PRIMARY KEY (`ensembl_transcript_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
이제 Ensembl에서 자동 메타 데이터 가져 오기 스크립트 메타 데이터를 파이프 라인에 가져오고 여러 가지 이유로 파이프 라인이 실행 단계에서 중단 될 수 있다고 상상해보십시오. 따라서 우리는 두 가지를 보장해야합니다.
파이프 라인을 반복해서 실행해도 데이터베이스가 손상되지 않습니다
‘중복 키’오류로 인해 반복 된 실행이 종료되지 않습니다.
방법 1 : REPLACE 사용
매우 간단합니다.
REPLACE INTO `transcripts` SET `ensembl_transcript_id` = 'ENSORGT00000000001', `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
레코드가 있으면 덮어 씁니다. 아직 존재하지 않으면 작성됩니다. 그러나이 방법을 사용하는 것은 효율적이지 않습니다. 기존 레코드를 덮어 쓸 필요가 없으며 그냥 건너 뛰는 것이 좋습니다.
방법 2 : INSERT IGNORE 사용하기 매우 간단합니다.
INSERT IGNORE INTO `transcripts` SET `ensembl_transcript_id` = 'ENSORGT00000000001', `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
여기서 ‘ensembl_transcript_id’가 데이터베이스에 이미 존재하면 자동으로 건너 뜁니다 (무시). (더 정확하게 말하면, MySQL 참조 매뉴얼에서 인용 한 내용은 다음과 같습니다.“IGNORE 키워드를 사용하는 경우 INSERT 문을 실행하는 동안 발생하는 오류는 대신 경고로 처리됩니다. 예를 들어 IGNORE가 없으면 기존 UNIQUE 인덱스를 복제하는 행 또는 테이블의 PRIMARY KEY 값으로 인해 중복 키 오류가 발생하고 명령문이 중단됩니다.”) 레코드가 아직 없으면 레코드가 작성됩니다.
이 두 번째 방법에는 다른 문제가 발생할 경우 쿼리 중단을 포함하여 여러 가지 잠재적 약점이 있습니다 (설명서 참조). 따라서 이전에 IGNORE 키워드없이 테스트 한 경우 사용해야합니다.
방법 3 : INSERT… ON DUPLICATE KEY UPDATE 사용 :
세 번째 옵션은
INSERT … ON DUPLICATE KEY UPDATE
구문 을 사용 하는 것이며, UPDATE 부분에서는 0 + 0 계산과 같이 의미없는 (빈) 작업을 수행하지 않습니다 (Geoffray는이 작업을 무시하기 위해 MySQL 최적화 엔진에 id = id 할당을 제안합니다). 이 방법의 장점은 중복 키 이벤트 만 무시하고 다른 오류로 인해 중단된다는 것입니다.마지막 공지 :이 게시물은 Xaprb에서 영감을 받았습니다. 또한 유연한 SQL 쿼리 작성에 대한 다른 게시물을 참조하는 것이 좋습니다.
답변
해결책:
INSERT INTO `table` (`value1`, `value2`)
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM `table`
WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1)
설명:
가장 안쪽 쿼리
SELECT * FROM `table`
WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1
애즈 사용 WHERE NOT EXISTS
데이터를 삽입하여 이미 행이 존재한다면 -condition 검출한다. 이러한 종류의 행이 발견되면 쿼리가 중지 될 수 있으므로 LIMIT 1
(마이크로 최적화, 생략 될 수 있음)
중간 쿼리
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
삽입 할 값을 나타냅니다. DUAL
모든 Oracle 데이터베이스에 기본적으로 존재하는 특수한 행, 하나의 열 테이블을 나타냅니다 ( https://en.wikipedia.org/wiki/DUAL_table 참조 ). MySQL-Server 버전 5.7.26에서 생략 할 때 유효한 쿼리가 FROM DUAL
있지만 5.5.60과 같은 이전 버전에는 FROM
정보 가 필요한 것 같습니다 . WHERE NOT EXISTS
가장 안쪽 쿼리가 일치하는 데이터를 찾은 경우 중간 쿼리 를 사용 하여 빈 결과 집합을 반환합니다.
외부 쿼리
INSERT INTO `table` (`value1`, `value2`)
중간 쿼리에서 데이터가 반환되면 데이터를 삽입합니다.
답변
중복 키 업데이트 또는 insert ignore 는 MySQL에서 실행 가능한 솔루션 일 수 있습니다.
mysql.com을 기반으로 하는 중복 키 업데이트 업데이트의 예
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
mysql.com을 기반으로 한 insert ignore 예제
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
또는:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
또는:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
답변
예외가 허용되는 경우 간단한 제한 조건이 작업을 수행해야합니다. 예 :
- 대리하지 않은 경우 기본 키
- 열에 대한 고유 제한
- 다중 열 고유 제한 조건
죄송합니다. 이것은 매우 간단합니다. 당신이 우리와 공유하는 링크에 맞지 않는 것 같습니다. ;-(
그러나 나는 이것이 당신의 필요를 채우는 것처럼 보이기 때문에 결코이 대답을하지 않습니다. (그렇지 않으면 요구 사항 업데이트가 트리거 될 수 있으며, 이는 “좋은 것”이기도합니다).
편집 됨 : 삽입으로 인해 데이터베이스 고유 제한 조건이 중단되면 데이터베이스 레벨에서 드라이버에 의해 릴레이되는 예외가 발생합니다. 실패하면 스크립트가 확실히 중지됩니다. PHP에서 그러한 경우를 해결할 수 있어야합니다 …
답변
다음은 지정된 모든 열 값이 테이블에 존재하지 않는 경우에만 행을 삽입하는 PHP 함수입니다.
-
열 중 하나가 다르면 행이 추가됩니다.
-
테이블이 비어 있으면 행이 추가됩니다.
-
지정된 모든 열에 지정된 값이있는 행이 있으면 행이 추가되지 않습니다.
function insert_unique($table, $vars) { if (count($vars)) { $table = mysql_real_escape_string($table); $vars = array_map('mysql_real_escape_string', $vars); $req = "INSERT INTO `$table` (`". join('`, `', array_keys($vars)) ."`) "; $req .= "SELECT '". join("', '", $vars) ."' FROM DUAL "; $req .= "WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE "; foreach ($vars AS $col => $val) $req .= "`$col`='$val' AND "; $req = substr($req, 0, -5) . ") LIMIT 1"; $res = mysql_query($req) OR die(); return mysql_insert_id(); } return False; }
사용법 예 :
<?php
insert_unique('mytable', array(
'mycolumn1' => 'myvalue1',
'mycolumn2' => 'myvalue2',
'mycolumn3' => 'myvalue3'
)
);
?>
답변
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
레코드가 있으면 덮어 씁니다. 아직 존재하지 않으면 작성됩니다.
답변
다음을 시도하십시오 :
IF (SELECT COUNT(*) FROM beta WHERE name = 'John' > 0)
UPDATE alfa SET c1=(SELECT id FROM beta WHERE name = 'John')
ELSE
BEGIN
INSERT INTO beta (name) VALUES ('John')
INSERT INTO alfa (c1) VALUES (LAST_INSERT_ID())
END