2010-09-09 6 views
4

У меня есть таблица с первичным ключом с автоматическим добавлением. Я хочу вставить в него кучу данных и получить ключи для каждого из них без дополнительных запросов.Является ли объемная вставка атомой?

START TRANSACTION; 
INSERT INTO table (value) VALUES (x),(y),(z); 
SELECT LAST_INSERT_ID() AS last_id; 
COMMIT; 

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

id(z) = last_id; 
id(y) = last_id - 1; 
id(x) = last_id - 2; 
+1

last_insert_id() предоставит вам идентификатор первой вставки для нескольких вставок. Поэтому вы должны делать last_id + 1 и last_id + 2 вместо минуса. – Pacerier

ответ

2

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

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

Этот тип «блокировки стола» является поведением по умолчанию в большинстве случаев.

В необычных обстоятельствах вы можете найти, что в РСУБД установлены определенные опции, что означает, что поведение «нормального» по умолчанию (блокировка таблицы) не является тем, что происходит для этой конкретной установки. Если это так, вы можете переопределить значение по умолчанию, указав, что вы хотите заблокировать таблицу как часть инструкции INSERT.

EDIT:

У меня есть большой опыт работы на MS-SQL Server и пятнистый опыт на многих других СУБД. Ни в какое время я не нашел гарантии, что вставка будет происходить в определенном порядке.

Одной из причин этого является то, что часть SELECT INSERT может быть вычислена параллельно. Это означало бы, что данные, которые нужно вставить, готовы к выходу из строя.

В том случае, когда вставляются особенно большие объемы данных, РСУБД может идентифицировать, что новые данные будут охватывать несколько страниц памяти или дискового пространства. Опять же, это может привести к параллельной работе.

Насколько я знаю, MySQL имеет функцию типа row_number(), которую вы можете указать в запросе SELECT, результат которого вы можете сохранить в базе данных. Затем вы сможете полагаться на это поле (построенное вами), но не на поле идентификатора auto-increment (построенное СУРБД).

0

Насколько я знаю, это будет работать практически во всех SQL-двигателях.

+1

Чтобы быть уверенным, существуют ли какие-либо доказательства? Официальные документы или что-то в этом роде. – Andrew

+0

Поскольку только самый высокий идентификатор хранится как значение «AUTOINCREMENT» для каждой таблицы, маловероятно, что какой-нибудь SQL-движок снова будет использовать выпущенные идентификаторы. – jwueller

+0

В ситуации одновременных вставок? А как насчет порядка, всегда ли он такой же, как в запросе? – Andrew

Смежные вопросы