DBAtlas · データベース運用アトラス

2 つのスキーマ/環境を比較(スキーマ差分)

Oracle

-- Extract the schema DDL from both environments and take a text diff
-- (generate deterministic DDL with DBMS_METADATA)
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);
EXEC DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',FALSE);
SELECT DBMS_METADATA.GET_DDL('TABLE', table_name) FROM user_tables ORDER BY table_name;
-- Spool the output to a file in both environments and compare with diff/fc.

-- Export the schema as a changelog with SQLcl's Liquibase integration:
-- SQL> lb generate-schema
-- Commercial: the Oracle SQL Developer 'Database Diff' tool is also used.

Oracle には単一コマンドで行う組み込みのスキーマ差分はない。一般的な方法は、両方の環境から DBMS_METADATA.GET_DDL(STORAGE/セグメント属性をオフにして)で決定的な DDL を生成し、テキストの差分を取ること。視覚的/自動的な比較には SQL Developer の Database Diff ウィザードまたは SQLcl を使用する。

PostgreSQL

# Dump only the schema from both databases and diff them
pg_dump --schema-only --no-owner --no-privileges sourcedb > source_schema.sql
pg_dump --schema-only --no-owner --no-privileges targetdb  > target_schema.sql
diff -u source_schema.sql target_schema.sql

# Tool that generates applicable ALTERs: apgdiff (Another PostgreSQL Diff Tool)
# apgdiff source_schema.sql target_schema.sql > migration.sql
# Alternatives: migra, Liquibase diffChangeLog

最も簡単な方法は、両方の環境で pg_dump --schema-only の出力を取得し、diff で比較すること。apgdiff と migra は差分を直接実行可能な ALTER 文に変換するツール。決定的な出力にするには --no-owner --no-privileges を付ける。

MySQL

# Schema/object comparison with MySQL Utilities (5.x):
mysqldbcompare --server1=root:password@host1 --server2=root:password@host2 \
  shop:shop --difftype=sql --run-all-tests

# Built-in method: take CREATE statements from both environments and diff them
mysqldump --no-data --skip-comments shop > source_schema.sql
# SHOW CREATE TABLE customer;  (to see a single table definition)

MySQL Utilities の mysqldbcompare ツールは、2 つのサーバー間のオブジェクト/スキーマの差異を報告する(difftype=sql で適用可能な文として)。ツールを使わない方法は、両方の環境から mysqldump --no-data(スキーマのみ)または SHOW CREATE TABLE の出力を取得し、diff で比較すること。mysqldbcompare は現在非推奨で、MariaDB/8.x では Liquibase または Skeema が推奨される。

SQL Server

-- Schema comparison/deploy report with SqlPackage (what will change before applying):
sqlpackage /Action:DeployReport /SourceFile:source.dacpac \
  /TargetConnectionString:"Server=target;Database=shop;Integrated Security=true" \
  /OutputPath:diff_report.xml

-- For data differences (row level), the tablediff utility:
tablediff -sourceserver S1 -sourcedatabase shop -sourcetable customer \
  -destinationserver S2 -destinationdatabase shop -destinationtable customer

スキーマの差異には、SqlPackage /Action:DeployReport がターゲットに適用される変更を XML レポートとして返し、/Action:Script が実行可能な差分スクリプトを生成する。Visual Studio / Azure Data Studio の「Schema Compare」も同じエンジンを使用する。行レベルのデータの差異には tablediff コマンドラインユーティリティがある。

MongoDB

// The schema is implicit; extract and compare the field structure of both environments.
// Read the $jsonSchema validator definition (collection rules):
db.getCollectionInfos({ name: "customer" })[0].options.validator

// External tools for inferred schema comparison by sampling:
// mongodb-schema (npm) or the Compass 'Schema' tab
// Take samples with mongoexport and diff the field/type distribution of both environments.

MongoDB はスキーマレスで、固定の DDL はない。比較には 2 つの方法がある。コレクションに定義された $jsonSchema バリデータのルールを比較する(getCollectionInfos 経由)か、mongodb-schema / Compass でデータから推定スキーマを生成し、フィールドと型の分布を比較する。インデックスは db.collection.getIndexes() の出力の差分を取る。

Redis

# Not applicable: Redis is a schemaless key-value store; there are no
# table/column definitions (DDL) to compare.
# Closest equivalent: compare the key space (namespace) structure
# redis-cli --scan --pattern 'customer:*' | sort > source_keys.txt

該当なし: Redis にはスキーマの概念(テーブル/列/DDL)がないため、従来のスキーマ差分は適用されない。構造的な比較が必要な場合は、SCAN でキーの命名パターン(名前空間)のみを一覧表示して比較できる。

Elasticsearch

# Fetch the index mapping from both clusters and compare
curl -s 'http://source:9200/customer/_mapping?pretty' > source_mapping.json
curl -s 'http://target:9200/customer/_mapping?pretty'  > target_mapping.json
diff -u source_mapping.json target_mapping.json

# To compare settings as well:
# GET customer/_settings   and   GET customer/_mapping

Elasticsearch でスキーマに相当するのはインデックスのマッピング。標準的な方法は、両方のクラスタから GET <index>/_mapping の出力(必要に応じて _settings も)を取得し、diff で比較すること。マッピングのフィールドはほとんど変更不可のため、差異が検出された場合は新しいインデックス + _reindex が必要になることがある。

DBAtlas で開く →