MySQL Import: предотвращение дублирования при импорте записей без первичного ключа - PullRequest
1 голос
/ 21 апреля 2019

Мы получаем данные от третьей стороны и, к сожалению, эти данные содержат уникальные записи, но не содержат уникальный ключ. Нам нужно импортировать эту информацию в базу данных MySQL, предпочтительно с использованием PHP, но нужно убедиться, что строки не дублируются.

Записи никогда не меняются после того, как они были сгенерированы, поскольку они представляют собой моментальные снимки балансов в счетах с отметкой времени.

Когда набор данных стал меньше, мы просто обновили всю базу данных, удалив все данные и повторно импортировав все заново. Поскольку размер набора данных увеличивается, это не является устойчивым решением, поскольку использует слишком много системных ресурсов и занимает все больше и больше времени.

Сначала мы выгружаем импортированные данные во временную таблицу MySQL (исходные данные не имеют первичного ключа):

Структура таблицы: импортированные данные

    BalanceDate DATE NOT NULL COMMENT 'Date Balance Was Fetched From Bank',
    BalanceTime TIME NOT NULL COMMENT 'Time Balance Was Fetched from Bank',
    AccountName VARCHAR(100) DEFAULT NULL COMMENT 'Name of Account Downloaded from Source',
    AccountNo VARCHAR(50) DEFAULT NULL COMMENT 'Account Number Downloaded from Source',
    InstName VARCHAR(150) DEFAULT NULL COMMENT 'Financial Institution Name Downloaded from Source',
    Balance DECIMAL(10, 2) NOT NULL COMMENT 'Balance in Account',
    Type VARCHAR(50) NOT NULL COMMENT 'Type of Account',
    Class VARCHAR(50) NOT NULL COMMENT 'Class of Account',
    Index INT(11) DEFAULT NULL COMMENT 'Index Number Downloaded from Source',

Обратите внимание, что номер индекса уникален для каждого финансового учреждения, но не уникален для каждой записи.

Живая таблица имеет вышеуказанные поля плюс автоматически инкрементированное поле уникального идентификатора. Мы также добавили несколько столбцов для внешних ключей, которые мы конвертируем с помощью простого оператора IF THEN.

Структура таблицы: дополнительные поля в живой таблице

    ID INT(11) NOT NULL AUTO_INCREMENT,
    AccountID INT(11) NOT NULL COMMENT 'Linked to Accounts table (Account at Financial Institution)',
    InstID INT(11) NOT NULL COMMENT 'Links to Institution table (Financial Institution)',

PHP

    // Accounts and Banks and prepopulated into the database in other tables.
    // This is a simplified example of the logic. Actual code a bit more complicated.
    if ($AccountName == "Whatever Account" AND $InstName == "Whatever Bank") {
       $AccountID = 1;
       $InstID = 1;
    }

Цель состоит в том, чтобы перенести данные в нашу базу данных и не дублировать записи в процессе.

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

1 Ответ

1 голос
/ 21 апреля 2019

Добавьте виртуальный столбец в таблицу, которая содержит хэш всех остальных столбцов, и укажите его UNIQUE

HashCode CHAR(32) AS MD5(CONCAT_WS(',', BalanceDate, BalanceTime, AccountName, AccountNo, ...) UNIQUE

Затем, когда вы вставляете из временной таблицы, вы можете использовать INSERT IGNORE. Если какая-либо из входящих строк хешируется так же, как и одна из существующих строк, индекс на HashCode приведет к ее пропуску.

Это замедлит процесс импорта, поскольку каждая новая строка должна быть хеширована и проверена по индексу. Нет такого понятия, как бесплатный обед, и для него не потребуется столько места, сколько для индексации всего ряда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...