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

0

Мы получаем данные от третьей стороны и, к сожалению, эти данные содержат уникальные записи, но не содержат уникальный ключ. Нам нужно импортировать эту информацию в базу данных 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;
    }

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

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

Теги:
mysqli

1 ответ

1
Лучший ответ

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню