最近、MySQL が「alter table」などのDDLのロールバックをサポートしていないことがわかりました。サポートしない技術的な理由はありますか?それは単に彼らにとって「面白くない」機能ですか?
編集:この比較が見つかりました。トランザクションDDLをサポートする多くのDBMSがあるようです。
DROP
いRENAME
ます。
最近、MySQL が「alter table」などのDDLのロールバックをサポートしていないことがわかりました。サポートしない技術的な理由はありますか?それは単に彼らにとって「面白くない」機能ですか?
編集:この比較が見つかりました。トランザクションDDLをサポートする多くのDBMSがあるようです。
DROP
いRENAME
ます。
回答:
これがPostgreSQLで機能する理由は、システムカタログが通常のテーブルであるためです。そのため、たとえば、新しい関数を作成するには、pg_proc
テーブルに行を挿入するだけで、列のデフォルト値を変更するにはpg_attrdef
、などで行を更新するだけで済みます。とにかくテーブルはトランザクションであるため、そのように動作させないためには、ほとんど邪魔にならないようにする必要があります。(多くの苦痛を伴う実装の詳細はここでは省略しました。;-))
他のデータベースエンジンは、カスタムの内部構造を使用してシステムカタログ情報を表すと、ソースコードを知らないと思います。そのため、トランザクションDDLを機能させるために、余分な労力を費やす必要があります。おそらく、彼らにとって優先事項ではないようです。
これの裏側は、これがPostgreSQLのメジャーバージョンアップグレードが非常に苦痛な理由であるということです。他の製品は、おそらく変更と更新を念頭に置いて内部メタデータ構造を設計できるため、新しいメジャーバージョンへのアップグレードに問題はありません。PostgreSQLでは、少なくともシステムをオンラインにしたままでは、システムカタログテーブルをシステムカタログテーブルの新しいバージョンのように突然変更する方法はありません。システムカタログにアクセスする必要があるためです。ほら
ほとんどない?残念。
私は主にSQL Serverを使用していますが、実際に使用しています。オラクルはそうではないことは知っていますが、オラクルは異常かもしれないと思いました。
SQL Serverでは、単一のトランザクションで複数の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は(通常)別のセッションと同じです。1つのセッションがテーブルに10個の列があると考え、別のセッションが11個あると考えた場合、それは壊れます。