Как зарезервировать диапазон идентификаторов в таблице MySQL - PullRequest
0 голосов
/ 04 февраля 2020

Мне нужно выполнить массовую вставку множества записей со связанными записями (таблица has_many). Поэтому моя стратегия такова:

построить необработанный запрос SQL с указанием последовательных идентификаторов (первичный ключ), чтобы связанные записи могли быть построены с этими идентификаторами в качестве значений внешнего ключа. Но мне нужно предотвратить, чтобы другие параллельные соединения создавали новую запись с идентификатором в диапазоне, который мне нужно использовать для массового запроса. Как я могу зарезервировать диапазон идентификаторов для массовой вставки? Я пытался использовать alter table tablename auto_increment = x, но не работает. Кроме того, я попытался создать поддельную запись с этим запросом:

LOCK TABLES tablename WRITE
# get last id (for example 100)
INSERT INTO tablename (SELECT 201 AS id, name FROM tablename WHERE id = 100)
UNLOCK TABLES

Но это не работает, потому что я получаю ошибку tablename was not locked with LOCK TABLES.

Любая идея, чтобы решить эту проблему ?

Надеюсь, я объяснил себе: D

1 Ответ

0 голосов
/ 04 февраля 2020

Схематически:

INSERT INTO main (fields except ID) 
VALUES (literal values for fields);

INSERT INTO slave (main_id, other fields except ID)
SELECT id, (literal values for other fields)
FROM main
WHERE (fields from main except ID) = (literal values for main fields);

Для массовой вставки вы должны использовать промежуточную таблицу, которая принимает данные как для главной, так и для ведомой (и), а после вставки в нее вы копируете данные в отдельные таблицы с присвоением соответствующих ссылочных значений.

-- working tables
CREATE TABLE main (id SERIAL PRIMARY KEY, 
                   main_val INT);
CREATE TABLE slave (id SERIAL PRIMARY KEY, 
                    slave_val INT,
                    id_main BIGINT UNSIGNED,
                    FOREIGN KEY (id_main) REFERENCES main(id));
-- table for bulk insert
CREATE TABLE for_bulk_insert ( main_val INT, slave_val INT );
-- data for bulk insert, in practice it is loaded using LOAD DATA INFILE
INSERT INTO for_bulk_insert VALUES (11,111), (22,222), (33,333);
-- insert data into main table
INSERT INTO main (main_val)
SELECT main_val FROM for_bulk_insert;
-- insert data into slave table with referenced values from main table
INSERT INTO slave (slave_val, id_main)
SELECT for_bulk_insert.slave_val, main.id
FROM for_bulk_insert
JOIN main ON for_bulk_insert.main_val = main.main_val;
-- check the result
SELECT * FROM main;
SELECT * FROM slave;
id | main_val
-: | -------:
 1 |       11
 2 |       22
 3 |       33

id | slave_val | id_main
-: | --------: | ------:
 1 |       111 |       1
 2 |       222 |       2
 3 |       333 |       3

db <> fiddle здесь

Конечно массив данных вставлен в main (в показанном примере это одно поле main_val) должно быть уникальным для таблицы.

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