MySQL дубликаты с загрузкой данных INFILE
При использовании LOAD DATA INFILE, есть ли способ пометить дублирующую строку или сбросить любые / все дубликаты в отдельную таблицу?
2 ответа
Из документации ЗАГРУЗИТЬ ДАТУ INFILE:
Ключевые слова REPLACE и IGNORE управляют обработкой входных строк, которые дублируют существующие строки с уникальными значениями ключа:
- Если вы укажете REPLACE, входные строки заменят существующие. Другими словами, строки, которые имеют то же значение для первичного ключа или уникального индекса, что и существующая строка. Смотрите Раздел 12.2.7, "ЗАМЕНИТЕ Синтаксис".
- Если вы укажете IGNORE, входные строки, дублирующие существующую строку с уникальным значением ключа, будут пропущены. Если вы не укажете ни один из параметров, поведение зависит от того, указано ли ключевое слово LOCAL. Без LOCAL возникает ошибка, когда обнаруживается повторяющееся значение ключа, а остальная часть текстового файла игнорируется. С LOCAL поведение по умолчанию такое же, как если бы был указан IGNORE; это связано с тем, что сервер не может остановить передачу файла в середине операции.
По сути, нет способа перенаправить дубликаты записей в другую таблицу. Вам нужно будет загрузить их все вместе, а затем создать другую таблицу для хранения недублированных записей.
Похоже, что на самом деле есть что-то, что вы можете сделать, когда дело доходит до дублирования строк для вызовов LOAD DATA. Однако подход, который я нашел, не идеален: он действует скорее как журнал для всех удалений в таблице, а не только для вызовов LOAD DATA. Вот мой подход:
Настольный тест:
CREATE TABLE test (
id INTEGER PRIMARY KEY,
text VARCHAR(255) DEFAULT NULL
);
Таблица test_log:
CREATE TABLE test_log (
id INTEGER, -- not primary key, we want to accept duplicate rows
text VARCHAR(255) DEFAULT NULL,
time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Триггер del_chk:
delimiter //
drop trigger if exists del_chk;
CREATE TRIGGER del_chk AFTER DELETE ON test
FOR EACH ROW
BEGIN
INSERT INTO test_log(id,text) values(OLD.id,OLD.text);
END;//
delimiter ;
Тестовый импорт (/home/user/test.csv
):
1,asdf
2,jkl
3,qwer
1,tyui
1,zxcv
2,bnm
Запрос:
LOAD DATA INFILE '/home/ken/test.csv'
REPLACE INTO TABLE test
FIELDS
TERMINATED BY ','
LINES
TERMINATED BY '\n' (id,text);
Выполнение вышеуказанного запроса приведет к 1,asdf
, 1,tyui
, а также 2,jkl
добавляется в таблицу журнала. Основываясь на отметке времени, можно связать строки с определенным LOAD DATA
заявление.