DBAtlas · Atlas de operações de banco de dados

Comparar dois schemas/ambientes (schema diff)

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.

O Oracle não tem um schema diff nativo de comando único. O método comum é gerar DDL determinístico dos dois ambientes com DBMS_METADATA.GET_DDL (com os atributos de STORAGE/segmento desligados) e fazer um diff de texto. Para comparação visual/automatizada, use o assistente Database Diff do SQL Developer ou o 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

A forma mais simples é gerar a saída de pg_dump --schema-only nos dois ambientes e compará-la com diff. apgdiff e migra são ferramentas que convertem a diferença diretamente em instruções ALTER executáveis. Adicione --no-owner --no-privileges para uma saída determinística.

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)

A ferramenta mysqldbcompare do MySQL Utilities informa as diferenças de objetos/schema entre dois servidores (como instruções aplicáveis com difftype=sql). O método sem ferramenta é gerar a saída de mysqldump --no-data (apenas schema) ou SHOW CREATE TABLE nos dois ambientes e comparar com diff. O mysqldbcompare agora está obsoleto; para MariaDB/8.x, prefere-se Liquibase ou 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

Para diferenças de schema, SqlPackage /Action:DeployReport retorna como relatório XML as alterações a serem aplicadas no destino; /Action:Script gera um script de diff executável. O 'Schema Compare' do Visual Studio / Azure Data Studio usa o mesmo engine. Para diferenças de dados em nível de linha, existe o utilitário de linha de comando 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.

O MongoDB é schemaless; não há DDL fixo. A comparação é feita de duas formas: compare as regras do validador $jsonSchema definidas na coleção (via getCollectionInfos) ou gere um schema inferido a partir dos dados com mongodb-schema / Compass e compare as distribuições de campos e tipos. Para índices, faça diff da saída de 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

Não se aplica: o Redis não tem o conceito de schema (tabela/coluna/DDL), então um schema diff clássico não se aplica. Se for necessária uma comparação estrutural, apenas o padrão de nomes das chaves (namespace) pode ser listado com SCAN e comparado.

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

No Elasticsearch, o equivalente a um schema é o mapping do índice. O método padrão é obter a saída de GET <index>/_mapping (e _settings, se necessário) dos dois clusters e comparar com diff. Como os campos do mapping são em grande parte imutáveis, uma diferença detectada pode exigir um novo índice + _reindex.

Abrir no DBAtlas →