Чому деякі СУБД не дозволяють відкати для певних операторів DDL?


21

Нещодавно я з'ясував, що MySQL не підтримує відкат DDL, наприклад, "alter table" ... Використовуючи PostgreSQL, це вразило мене як дивне, але мій друг сказав мені, що навіть Oracle цього не дозволяє. Чи є технічні причини, що не підтримують його? Це просто "нецікава" функція для них?

Редагувати: щойно знайшли це порівняння . Схоже, існує багато СУБД, які підтримують транзакційний DDL.


3
MySQL не дозволяє DDL всередині транзакції. Перш ніж виконати оператори DDL, він здійснює поточну транзакцію (всі поточні оператори DML всередині цієї транзакції!) Без будь-якого попередження.
Френк Хайкенс

Точно, дуже дратує IMO :)
Йоріл

Я особисто здивований, що Postgres дозволяє це - ви можете навіть відкатати a DROPчи a RENAME?
Джо

1
Поки ви не
скинете

Тож лише Oracle та MySQL не дозволяють операторам DDL в рамках транзакцій. Ця функція дійсно дозволяє легко розгортати схему.
Мар'ян

Відповіді:


19

Причина, чому це працює в PostgreSQL, полягає в тому, що системні каталоги є звичайними таблицями. Наприклад, для створення нової функції потрібно просто вставити рядок уpg_proc таблицю, зміна значення стовпця за замовчуванням просто потребує оновлення до деякого рядка в pg_attrdefтощо. Оскільки таблиці так чи інакше є транзакційними, вам майже доведеться виходити зі свого шляху, щоб не працювати так. (Тут пропущено багато хворобливих деталей щодо впровадження. ;-))

Я думаю, не знаючи вихідного коду, що інші двигуни бази даних використовують деякі власні внутрішні структури для представлення інформації про їх системний каталог. І тому їм доведеться докласти додаткових зусиль, ймовірно, багато додаткових зусиль, щоб зробити транзакційний DDL роботу, і це, мабуть, не для них пріоритет.

Зворотний бік цього полягає в тому, що це є причиною того, що основні оновлення версій PostgreSQL настільки болючі. Інші продукти, мабуть, можуть спроектувати свої внутрішні структури метаданих з урахуванням змін та оновлень, і тому немає проблем з оновленням до нової основної версії. У PostgreSQL немає способу змінити таблицю системного каталогу, щоб раптом виглядати як новіша версія таблиці системного каталогу, принаймні, не підтримуючи систему в Інтернеті, оскільки це вимагало б доступу до системних каталогів. Ургу.


1
Добре, що я віддаю перевагу моєму БД у постійному стані весь час над простотою оновлення DB-версії, але, мабуть, це питання думки :) Дякую за ваше пояснення!
Йоріл

Це може пояснити проблему для деяких баз даних, але системні каталоги - це звичайні таблиці Oracle.
Лі Ріффель

10

Більшість ні? Бампер.

В основному я використовую SQL Server, і це робить. Я знаю, що Oracle це не так, але я думав, що Oracle може бути відхиленням.

У SQL Server я впевнений, що ви можете запускати кілька операторів DDL за одну транзакцію, хоча я також думаю, що є кілька обмежень (про які я все забув). Ви можете створити твір, змінити або залишити більшість речей і повернути його назад, якщо хочете. Red-Gate SQL Compare (інструмент, який я люблю) використовує це.

Проблема з цим полягає в тому, що область вашої транзакції стає досить цікавою ... Коли ви залучаєте системні каталоги до транзакції оновлення (DDL), ви ризикуєте зробити кілька дійсно важливих блокувань і ви можете заблокувати доступ до системних каталогів. Користувачі не можуть зробити багато, якщо їх запити не можуть знайти свої таблиці в каталогах!

З іншого боку, зручно мати можливість включати DDL в транзакцію з кількома заявами.

Більш корисно, що команда DDL SQL Server TRUNCATE також може бути елементом транзакції з декількома операторами . Ви можете урізати цільову таблицю (дуже швидко), скласти її, а потім зробити фіксацію, якщо результат вам подобається. Якщо щось піде не так, ви відкатуєтесь і вуалі !, це як ніколи не турбували стіл. Простір журналу також мінімізовано. Я цим користуюся досить часто.


2
Ось відповідь, яка показує приклад зв’язаного з транзакціями DDL в SQL Server. Крім того, я завжди думав, що TRUNCATEйого не можна повернути назад. Я був неправий.
Нік Чаммас

5

У SQL Server ми можемо відкатати оператори DDL, але в кінці оператора не використовується автоматична фіксація. В інших СУБД я не знаю, але я пам’ятаю, що в Oracle ніхто не може робити те саме. Я вважаю, що це специфічно для кожної СУБД, не впевнений, що сказав би стандарт SQL про це, але я впевнений, що жоден виробник не реалізує 100% стандарт.

Існує аналогічне запитання щодо SO: Чи можливо запускати кілька операторів DDL всередині транзакції (в межах SQL Server)?


5

Oracle має спільний аналіз запитів, тому SELECT * FROM table_a, виконаний одним сеансом, (як правило) такий же, як у іншого сеансу. Це зламається, якби одна сесія вважала, що в таблиці десять стовпців, а інша - одинадцять.


Цікаво вам сказати, що у мене був подібний вигляд днями, програма мала бути «гарячою» розгорнутою, але змінивши структуру таблиці для нової версії, у неї не було можливості перекомпілювати JDBC PreparedStatements крім перезавантаження , стільки за це!
Гай

2
На відміну від версії 11gR2 представлена ​​концепція випусків, яка допомагає отримати гарячі оновлення. Ефективно існуючі з'єднання використовують одне видання (з п'ятьма колонками). Ви запускаєте нове видання, додаєте стовпець і починаєте нові з'єднання, використовуючи нове видання для нових сесій. Коли всі незавершені сеанси закінчені, старе видання стає суворим, і все використовує нове видання. Ніякого відкату, але ви не розміщуєте нову активність у своїй новій редакції, поки вона не працює.
Гері
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.