Массовая вставка в таблицу с использованием внешнего суррогатного ключа, когда доступен только естественный ключ - PullRequest
0 голосов
/ 24 апреля 2020

Какими способами можно изначально заполнить ассоциации (или другие таблицы), которые ссылаются на базовую таблицу, используя суррогатный ключ, когда данные имеют только естественные ключи? Какова лучшая практика (например, один INSERT...SELECT на строку, временные таблицы, решение кода вне SQL)?

В качестве примера для работы возьмите почтенную схему Author-Book с таблицами для авторов (естественно ключ: имя), книги (естественный ключ: имя и год) и таблица соединений, чтобы связать их в отношениях «многие ко многим». Представьте, что исходные данные связывают авторов с книгами (поэтому суррогатный ключ еще не существует) и должны быть импортированы в базу данных MySQL.

Исходные данные:

'Terry Pratchett', 'The Colour of Magic', 1983
'Terry Pratchett', 'Good Omens', 1990
'Neil Gaiman', 'Good Omens', 1990
'Neil Gaiman', 'Neverwhere', 1996
'Terry Pratchett', 'Dodger', 2012

Пример определения:

CREATE TABLE authors (
    `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(255) UNIQUE NOT NULL
);

CREATE TABLE books (
    `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(255) NOT NULL,
    `year` SMALLINT NOT NULL,
    UNIQUE (`name`, `year`)
);

CREATE TABLE authors_books (
    `author` INT UNSIGNED NOT NULL,
    `book` INT UNSIGNED NOT NULL,
    FOREIGN KEY (`author`) REFERENCES authors (`id`),
    FOREIGN KEY (`book`) REFERENCES books (`id`)
);

Пример данных:

INSERT INTO authors (`name`)
  VALUES
('Neil Gaiman'),
('Terry Pratchett');

INSERT INTO books (`name`, `year`)
  VALUES
('The Colour of Magic', 1983),
('Good Omens', 1990),
('Neverwhere', 1996),
('Dodger', 2012);

1 Ответ

0 голосов
/ 24 апреля 2020

Один из вариантов - использовать (временную) таблицу с естественными ключами для хранения исходных данных и присоединиться к этой таблице для заполнения таблицы ассоциации.

CREATE TEMPORARY TABLE source_authors_books (
    `author` VARCHAR(255) NOT NULL,
    `book` VARCHAR(255) NOT NULL,
    `year` SMALLINT NOT NULL
);

INSERT INTO source_authors_books VALUES ... -- source data

INSERT INTO authors_books
  SELECT authors.id, books.id
    FROM source_authors_books AS source
      JOIN authors ON source.author = authors.name
      JOIN books ON source.book = books.name
                AND source.year = books.year

Можно проверить целостность исходных данных двумя способами:

  1. путем добавления ограничений внешнего ключа к source_authors_books перед вставкой данных; в этом случае ошибки целостности будут препятствовать импорту (и выдают сообщения об ошибках).
  2. выдача SELECT, аналогичную той, которая указана в INSERT, но с использованием внешних объединений и проверкой идентификаторов NULL.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...