DDLとは?DBMS別の挙動・注意点と実務で使えるスキーマ変更のベストプラクティス

DDLとは何か — 概要

DDL(Data Definition Language、データ定義言語)は、データベースのスキーマや構造(テーブル、インデックス、ビュー、シーケンス、トリガー、スキーマ自体など)を定義・変更・削除するためのSQLの一部です。一般的なDDL文には、CREATE、ALTER、DROP、RENAME、TRUNCATE、COMMENT(オブジェクトにコメントを付ける)などが含まれます。DDLはデータそのもの(行)を操作するDML(SELECT/INSERT/UPDATE/DELETE)と区別されます。

代表的なDDLコマンドと用途

  • CREATE:新しいテーブル、ビュー、インデックス、スキーマ、データベース、ユーザー等を作成します。例:CREATE TABLE users (...);
  • ALTER:既存オブジェクトの構造を変更します。例:ALTER TABLE users ADD COLUMN age INT;
  • DROP:オブジェクトを削除します。例:DROP TABLE users;
  • TRUNCATE:テーブル内の全データを一括削除します(挙動はDBMSにより異なる)。
  • RENAME:オブジェクト名を変更します(RDBMSごとに構文は異なる)。
  • COMMENT:オブジェクトに説明を付与します(スキーマ管理に有用)。

DDLの特徴 — データ辞書(カタログ)とロック

DDLを実行すると、データベースの「メタデータ」(データ辞書/カタログ)が更新されます。これに伴い、オブジェクトレベルやシステムレベルのロックが発生することがあり、他のトランザクションと競合する可能性があります。例えば大きなテーブルのALTERはテーブル全体をロックし、アプリケーションのパフォーマンスや可用性に影響を与えることがあります。

トランザクションとDDL:DBMSごとの違い

DDLがトランザクション内で扱えるか(ロールバック可能か)はDBMSによって異なります。ここは設計時に特に注意すべき点です。

  • PostgreSQL:多くのDDL文はトランザクション内で実行でき、ロールバック可能です(つまり「Transactional DDL」をサポート)。詳細は公式ドキュメントを参照してください(PostgreSQLはDDLを含むトランザクション制御が可能)。
  • MySQL:多くのDDL(CREATE/ALTER/DROPなど)が暗黙のコミット(implicit commit)を発生させます。ストレージエンジンやバージョンによって細部は異なりますので注意が必要です。MySQLのドキュメントで「暗黙のコミット」の挙動を確認してください。
  • Oracle:ほとんどのDDLは暗黙にコミットされます。したがってDDLはロールバックできないものが多く、DDL実行前後でコミットが自動的に行われます。
  • SQL Server:多くのDDLはトランザクションの一部として実行でき、ロールバック可能です。TRUNCATE TABLE はトランザクション内でロールバック可能である点など、挙動はドキュメントで確認してください。

TRUNCATEはDDLか?DMLか?

TRUNCATEの分類と挙動はDBMSに依存します。一般的にTRUNCATEは「高速にテーブルを空にする(ページを解放する)」操作であり、DML(DELETE)とは異なり大量の行単位ログを残さない/最小限のログとなる場合が多いです。

  • Oracle:TRUNCATEはDDLに分類され、暗黙コミットが発生しロールバックできません。
  • MySQL:TRUNCATEは暗黙コミットを伴う(バージョンやストレージエンジンで挙動差あり)。
  • PostgreSQL / SQL Server:TRUNCATEはトランザクション内で実行できる(ロールバック可能)場合が多いが、制約や参照整合性に注意が必要。

運用上の注意点(実務的ベストプラクティス)

  • DDLは本番環境で実行する前にステージングで検証する。特にALTERやDROPはロールバックできない場合がある。
  • 互換性のある(非破壊的な)変更を優先する。例:まずNULL許容の新列を追加→アプリを段階的に対応→データをバックフィル→不要カラム削除。
  • ゼロダウンタイムを目指す場合はオンラインDDLやツールを活用する(例:MySQLのオンラインALTER、gh-ost、pt-online-schema-change、PostgreSQLのpg_repackなど)。
  • DDLをソース管理(マイグレーションスクリプト)で管理する。Liquibase、Flyway、Alembic、Rails/Djangoのマイグレーションなどを利用すると再現性が高まる。
  • DDLの実行は監査・承認フローを設定する。DDLはメタデータを変更するためリスクが高い。
  • バックアップとリカバリ手順を確認してから破壊的DDLを実行する。
  • パフォーマンス面では、インデックスや外部キーの追加・削除が大きく影響するため、メンテナンス時間帯やオンラインオプションを検討する。

スキーマ変更の設計手法(実践的アプローチ)

安全にスキーマを進化させるための一般的な手順:

  • 要求分析:本当に構造変更が必要か、アプリ側の対応で済むか検討。
  • 互換性優先の手順:新しい列の追加→アプリの対応→データ移行→古い列の削除。
  • マイグレーションを小さく分割して段階的に適用する。
  • ロールバック計画を明確に用意(可能なら逆マイグレーションを作る)。
  • 長時間かかる操作はオンラインツールやシャーディング戦略で回避。

実例(簡単なDDLサンプル)

CREATE TABLEやALTER TABLEの基本例:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(255) UNIQUE
);

ALTER TABLE users ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;

DROP TABLE old_logs;

運用ツールと手段

  • マイグレーションフレームワーク:Liquibase、Flyway、Alembic、ActiveRecord/Django Migrations
  • オンラインスキーマ変更ツール:gh-ost(GitHub)、pt-online-schema-change(Percona)、pg_repack(PostgreSQL)
  • 監査とトリガー:DDLイベントをキャプチャする機能(PostgreSQLのevent triggers、OracleのDDLトリガなど)

まとめ(チェックリスト)

  • DDLはスキーマ変更を伴うためリスクが高い。必ず事前検証を行う。
  • DBMSごとにトランザクション性や暗黙コミットの挙動が異なるため、公式ドキュメントを確認する。
  • マイグレーションはソース管理し、段階的かつ後方互換性を意識して実施する。
  • オンラインオプションや専用ツールを活用して、ダウンタイムやロックの影響を最小化する。

参考文献