Синхронизация базы данных MySQL с внешним источником (.csv) при сохранении предыдущих данных - PullRequest
0 голосов
/ 18 января 2019

Я получаю файл .csv, загружаемый на мой FTP-сервер каждый день, скажем, в 3 часа дня.

Например, давайте использовать это как пример

population.csv

city,population
New York,8008278
Los Angeles,3694825
San Diego,1223405

Я преобразовал файл CSV в массив и использовал INSERT INTO для вставки строк в мою таблицу Populations

╔════╦═════════════╦════════════╦════════╗
║ id ║    city     ║ population ║ status ║
╠════╬═════════════╬════════════╬════════╣
║  1 ║ New York    ║    8008278 ║      1 ║
║  2 ║ Los Angeles ║    3694825 ║      1 ║
║  3 ║ San Diego   ║    1223405 ║      1 ║
╚════╩═════════════╩════════════╩════════╝

id является индексом AUTO INCREMENT, а статус является TINYINT(1), значение которого я устанавливаю равным 1, если оно находится в CSV, загруженном в тот день.

Допустим, завтра в 3 часа дня этот CSV-файл загружен на мой сервер:

city,population
Los Angeles,3694825
San Diego,1229502

Как видите, строка New York не была включена, а population из San Diego изменилось.

Результат, которого я хочу достичь, - ежедневно обновлять строки значениями в файле CSV. Если строка не включает в себя то, что ранее было (например, New York), я бы хотел установить статус 0.

Итак, на следующий день, основываясь на содержимом файла CSV, я бы хотел, чтобы моя база данных разрешила что-то такое:

╔════╦═════════════╦════════════╦════════╗
║ id ║    city     ║ population ║ status ║
╠════╬═════════════╬════════════╬════════╣
║  1 ║ New York    ║    8008278 ║      0 ║
║  2 ║ Los Angeles ║    3694825 ║      1 ║
║  3 ║ San Diego   ║    1229502 ║      1 ║
╚════╩═════════════╩════════════╩════════╝

На данный момент я использую PHP для синтаксического анализа загруженного CSV-файла в массив и дополнительно запрос SELECT для синтаксического анализа базы данных в массив.

Использование условных операторов в PHP Я сравниваю два массива для любых различий (изменения значений строк, новые строки, удаленные строки).

Это моя первая попытка полностью синхронизировать внешний источник с содержимым базы данных, имеющей статус 1.

Есть ли более эффективный способ сделать это в самом MySQL и не полагаться на другой язык программирования для построения моих операторов?

Некоторые идеи, которые приходили мне в голову:

  • Добавляя отметку времени LastUpdated к каждой строке, если эта отметка времени превышает 24 часа, создайте TRIGGER для установки статуса на 0

  • Создайте таблицу аудита для ссылки на изменения за предыдущий день. (Удаленные строки, Вставленные строки и т. Д.). После ссылки повторно вставьте все уникальные / индексированные значения (id) и обозначьте состояние 0 для строк, которые не были включены в сегодняшний файл CSV

Или мой нынешний метод использования PHP для сравнения CSV с текущими записями в таблице - лучший способ сделать это? Как уже говорилось, у меня есть некоторый опыт работы с базами данных, но я никогда не пытался сделать что-то подобное. В каком направлении мне смотреть? Я что-то упускаю из виду?

1 Ответ

0 голосов
/ 18 января 2019

Я бы предложил сначала вставить новый файл во временную таблицу, используя синтаксис LOAD DATA INFILE.Ниже приведен пример, вам может потребоваться изменить его в соответствии с вашим вариантом использования (de этот учебник, например );

LOAD DATA INFILE 'c:/tmp/populations.csv' 
INTO TABLE Temp 
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;

Затем следующий запрос может быть использован для обновлениясуществующие строки в основной таблице:

UPDATE Populations p
LEFT JOIN Temp t ON p.city = t.city
SET 
    p.population = COALESCE(t.population, p.population),
    p.status = CASE WHEN p.city IS NULL THEN 1 ELSE 0 END

И этот запрос вставит строки, которые еще не существуют:

INSERT INTO Populations
SELECT p.name, p.population, 1
FROM Temp t
WHERE NOT EXISTS (
    SELECT 1 FROM Populations WHERE name = t.name)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...