最近、MySQL しない が "alter table"などのDDLのロールバックをサポートしていることを発見しました。それを許可しない..それをサポートしないための技術的な理由はありますか?それは単に彼らにとって「興味のない」機能なのでしょうか?
編集:見つかったばかり この比較 。 doがトランザクションDDLをサポートする多くのDBMSがあるようです。
これがPostgreSQLで機能する理由は、システムカタログが通常のテーブルであるためです。たとえば、新しい関数を作成するには、pg_proc
テーブルに行を挿入するだけで済みます。列のデフォルト値を変更するには、pg_attrdef
の一部の行を更新するだけです。とにかくテーブルはトランザクション対応なので、そのように機能させないためには、ほとんどの場合、邪魔にならないようにする必要があります。 (ここで省略された多くの痛みを伴う実装の詳細。;-))
ソースコードがわからないため、他のデータベースエンジンはカスタム内部構造を使用してシステムカタログ情報を表現していると思います。そのため、トランザクションDDLを機能させるために、余分な労力を費やす必要があり、多くの労力が必要になる可能性があります。これは、明らかに彼らにとって優先事項ではありません。
これの裏側は、これがPostgreSQLのメジャーバージョンのアップグレードが非常に面倒な理由であるということです。他の製品はおそらく、変更と更新を考慮して内部メタデータ構造を設計できるため、新しいメジャーバージョンにアップグレードしても問題はありません。 PostgreSQLでは、システムカタログにアクセスする必要があるため、少なくともシステムをオンラインにしたままでは、システムカタログテーブルを突然新しいバージョンのシステムカタログテーブルのように変更する方法はありません。ああ。
ほとんどはしませんか?残念。
私は主にSQL Serverを使用しています。私はOracleがそうではないことを知っていますが、Oracleは異常であるかもしれないと思いました。
SQL Serverでは、1つのトランザクションで複数のDDLステートメントを実行できると確信していますが、いくつかの制限がある(すべて忘れている)と思います。必要に応じて、ほとんどのものを作成または変更したり、ドロップしたり、ロールバックしたりできます。 Red-Gate SQL Compare(私が大好きなツール)はこれを利用しています。
これを行うことの問題は、トランザクションスコープがかなり興味深いものになることです...システムカタログを更新トランザクション(DDL)に含める場合、いくつかの非常に重要なロックを取得するリスクがあり、システムカタログへのアクセスをブロックする可能性があります。クエリがカタログ内のテーブルを見つけられない場合、ユーザーは多くのことを行えません。
ただし、全体として、複数ステートメントのトランザクションにDDLを含めることができると便利です。
より便利なのは、SQL Server DDLコマンドTRUNCATE
マルチステートメントトランザクションの要素にすることもできます です。ターゲットテーブルを切り捨て(非常に高速)、ビルドしてから、結果が気に入ったらコミットすることができます。何かがうまくいかない場合は、ロールバックして出来上がりです!テーブルを邪魔したことがないようです。ログ領域も最小化されます。私はそれをかなり頻繁に利用しています。
SQL Serverでは、DDLステートメントをロールバックできます。ステートメントの最後で自動コミットを使用していません。他のDBMSではわかりませんが、Oracleでは同じことができないことを覚えています。私はそれが各DBMSに固有であると信じていますが、SQL標準がこれについて何と言っているかはわかりませんが、100%標準を実装しているプロデューサーはいないと思います。
SOにも同様の質問があります: トランザクション内(SQL Server内)で複数のDDLステートメントを実行することは可能ですか?
Oracleはクエリ解析を共有しているため、1つのセッションで実行されるSELECT * FROM table_aは(通常)別のセッションのものと同じです。あるセッションがテーブルに10列あると考え、別のセッションが11列あると考えた場合、それは壊れます。