Недавно я обнаружил, что MySQL не поддерживает откат DDL, такой как «изменение таблицы» ... При использовании для PostgreSQL это показалось мне странным, но мой друг сказал мне, что даже Oracle не позволяет этого ... Есть ли технические причины не поддерживать его? Это просто "неинтересная" особенность для них?
Изменить: только что нашел это сравнение . Похоже , есть много DBMSes , которые делают поддержку транзакций DDL.
DROP
илиRENAME
?Ответы:
Причина, по которой это работает в PostgreSQL, заключается в том, что системные каталоги представляют собой обычные таблицы. Так, например, создание новой функции просто требует вставки строки в
pg_proc
таблицу, изменение значения столбца по умолчанию просто требует обновления какой-либо строки в строкеpg_attrdef
и т. Д. Так как таблицы в любом случае являются транзакционными, вам почти придётся изо всех сил не делать так, чтобы это работало. (Много болезненных деталей реализации здесь опущено. ;-))Я полагаю, не зная исходного кода, что другие движки баз данных используют некоторые собственные внутренние структуры для представления информации своего системного каталога. И поэтому им пришлось бы приложить дополнительные усилия, вероятно, много дополнительных усилий, чтобы заставить транзакционный DDL работать, и это, очевидно, не является для них приоритетом.
Обратная сторона этого заключается в том, что именно поэтому основные обновления PostgreSQL так болезненны. Другие продукты могут проектировать свои внутренние структуры метаданных с учетом изменений и обновлений, поэтому при обновлении до новой основной версии проблем не возникает. В PostgreSQL нет способа изменить таблицу системного каталога так, чтобы она внезапно выглядела как более новая версия таблицы системного каталога, по крайней мере, при сохранении системы в оперативном режиме, поскольку для этого потребуется доступ к системным каталогам. Urgh.
источник
Больше нет? Облом.
Я главным образом использую SQL Server, и это делает. Я знаю, что Oracle нет, но я думал, что Oracle может быть отклонением.
В SQL Server я вполне уверен, что вы можете запускать несколько операторов DDL в одной транзакции, хотя я также думаю, что есть несколько ограничений (о которых я все забыл). Вы можете создать, изменить или отбросить большинство вещей и откатить их, если хотите. Red-Gate SQL Compare (инструмент, который мне нравится) использует это преимущество.
Проблема заключается в том, что ваша область транзакции становится довольно интересной ... Когда вы включаете системные каталоги в транзакцию обновления (DDL), вы рискуете получить некоторые действительно важные блокировки и можете заблокировать доступ к системным каталогам. Пользователи не могут многое сделать, если их запросы не могут найти их таблицы в каталогах!
В целом, однако, удобно иметь возможность включать DDL в транзакции с несколькими операторами.
Более полезно то, что команда SQL Server DDL
TRUNCATE
также может быть элементом транзакции с несколькими операторами . Вы можете усечь целевую таблицу (очень быстро), построить ее, а затем сделать коммит, если вам нравится результат. Если что-то пойдет не так, вы откатываетесь и вуаля !, как будто вы никогда не мешали столу. Пространство журнала также минимизировано. Я пользуюсь этим довольно часто.источник
TRUNCATE
не может быть отменен. Я был неправ.В SQL Server мы можем откатывать операторы DDL, он не использует автоматическую фиксацию в конце оператора. В других СУБД я не знаю, но я помню, что в Oracle нельзя делать то же самое. Я считаю, что это специфично для каждой СУБД, не уверен, что об этом скажет стандарт SQL, но я уверен, что ни один производитель не реализует этот стандарт на 100%.
Есть аналогичный вопрос о SO: возможно ли выполнить несколько операторов DDL внутри транзакции (в SQL Server)?
источник
Oracle имеет общий анализ запросов, поэтому SELECT * FROM table_a, выполняемый одним сеансом, (обычно) такой же, как и в другом сеансе. Это сломалось бы, если бы в одном сеансе было десять столбцов в таблице, а в другом - одиннадцать.
источник