Лучший способ перенести таблицу MySQL с дупю на другой стол с уникальным ограничением
-
26-09-2019 - |
Вопрос
Я пытаюсь выработать лучший подход к миграции данных.
Я мигрирую некоторые данные (~ 8000 строк) из таблицы, как это:
CREATE TABLE location (
location_id INT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
addr VARCHAR(1000) NOT NULL,
longitude FLOAT(11),
latitude FLOAT(11)
) Engine = InnoDB, DEFAULT CHARSET=UTF8;
в таблицу, как это:
CREATE TABLE location2 (
location_id INT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
addr VARCHAR(255) NOT NULL UNIQUE,
longitude FLOAT(11),
latitude FLOAT(11)
) Engine = InnoDB, DEFAULT CHARSET=UTF8;
Не важно сохранить первичный ключ.
Адреса в «местоположении» дублируются много раз. В большинстве случаев с такой же широтой и долготой. Но в некоторых случаях есть строки с одинаковым значением для ADDR, но разных ценностей для широты и долготы.
В таблице Final Location2 должна иметь одну запись для каждой уникальной записи ADDR в месте. Там, где следует использовать более одного возможного значения для широты / долготы, новейшее (самое высокое местоположение_id) следует использовать.
Я создал процедуру, чтобы сделать это, но это не понравится строки, где addr такой же, но широта / долгота разные.
DROP PROCEDURE IF EXISTS migratelocation;
DELIMITER $$
CREATE PROCEDURE migratelocation()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE a VARCHAR(255);
DECLARE b, c FLOAT(11);
DECLARE cur CURSOR FOR SELECT DISTINCT addr, latitude, longitude FROM location;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
REPEAT
FETCH cur INTO a, b, c;
IF NOT done THEN
INSERT INTO location2 (addr, latitude, longitude) VALUES (a, b, c);
END IF;
UNTIL done END REPEAT;
CLOSE cur;
END $$
DELIMITER ;
CALL migratelocation();
Есть хороший способ сделать это? Я продолжаю хотеть сдаться и написать немного PHP PROG, чтобы сделать это, но я предпочел бы узнать правильный путь SQL, если смогу.
Возможно, мне просто нужно найти правильный выбор из первой таблицы, и я могу использовать:
INSERT INTO location2 SELECT ... ;
мигрировать данные.
Спасибо!
Решение
Вы можете использовать INSERT IGNORE напрямую, или ЗАМЕНЯТЬ - Я предполагаю, что это односторонний процесс, или, по крайней мере, один, где производительность не является основным соображением.
В этом случае запись с наивысшим местоположением_ид WINS:
INSERT IGNORE
INTO location2
SELECT *
FROM location
ORDER BY
location_id DESC
Последующие записи остроумие одинаковое значение первичного ключа просто отбрасываются вставкой.
Вам нужно будет отключить строгий режим SQL, в противном случае усечение поля ADDR даст ошибки.