Pular para o conteúdo
Início do IntoSQL

Converta um banco de dados em outro banco de dados

Solte um dump do mysqldump, mariadb-dump, pg_dump, SSMS, SQL Developer ou SQLcl, ou um arquivo .db do SQLite, e baixe um script para PostgreSQL, MySQL, MariaDB, SQLite, SQL Server ou Oracle com as mesmas tabelas, chaves, índices e dados. Cada mudança é listada em um relatório, e o dump nunca sai do seu computador.

Seu arquivo
sqlshop_2024.sqlArquivo de exemplo, 5,1 kB
Seu banco de dados

18 linhas convertidas, 8 correções, nenhuma rejeitada

Mostrar

Tabelas em shop_2024.sqlDump do MySQL 8.0.46 · gerado por mysqldump · utf8mb4

  • customers8 linhas3
    7 colunas
    idbigint not null
    namevarchar(100) not null
    emailvarchar(150) not null
    countryvarchar(2) not null
    is_activeboolean not null
    signed_update
    created_attimestamptz(0) not null
  • orders10 linhas5
    9 colunas
    idbigint not null
    customer_idbigint not null
    statustext not null
    totalnumeric(10,2) not null
    itemsinteger not null
    ordered_attimestamp(0) not null
    shipped_attimestamp(0)
    notevarchar(255)
    updated_attimestamptz(0) not null
-- Written by IntoSQL from a MySQL dump. Load it with: psql -v ON_ERROR_STOP=1 -f <file>
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET synchronous_commit = off;
SET maintenance_work_mem = '512MB';

CREATE TABLE customers (
    id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    name varchar(100) NOT NULL,
    email varchar(150) NOT NULL,
    country varchar(2) DEFAULT 'US' NOT NULL,
    is_active boolean DEFAULT true NOT NULL,
    signed_up date,
    created_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
    CONSTRAINT customers_id_check CHECK (id >= 0)
);

CREATE TABLE orders (
    id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    customer_id bigint NOT NULL,
    status text DEFAULT 'pending' NOT NULL,
    total numeric(10,2) NOT NULL,
    items integer DEFAULT 1 NOT NULL,
    ordered_at timestamp(0) NOT NULL,
    shipped_at timestamp(0),
    note varchar(255),
    updated_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
    CONSTRAINT orders_id_check CHECK (id >= 0),
    CONSTRAINT orders_customer_id_check CHECK (customer_id >= 0),
    CONSTRAINT orders_status_check CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled', '')),
    CONSTRAINT orders_items_check CHECK (items >= 0)
);

COPY customers (id, name, email, country, is_active, signed_up, created_at) FROM stdin;
1	Ana Martínez	ana@example.com	MX	t	2023-01-15	2023-01-15 10:24:00+00:00
2	Zoë Müller	zoe@example.de	DE	t	2023-02-03	2023-02-03 08:11:42+00:00
3	José Peña	jose@example.es	ES	f	2023-03-21	2023-03-21 19:05:17+00:00
4	李雷	lilei@example.cn	CN	t	2023-05-09	2023-05-09 02:40:00+00:00
5	Noah O'Brien	noah@example.ie	IE	t	\N	2023-06-30 14:00:00+00:00
6	Amélie Laurent	amelie@example.fr	FR	t	2024-01-02	2024-01-02 09:30:00+00:00
7	Ravi Patel	ravi@example.in	IN	f	2024-02-29	2024-02-29 23:59:59+00:00
8	Sofia Rossi 🌻	sofia@example.it	IT	t	2024-04-12	2024-04-12 12:12:12+00:00
\.

COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, updated_at) FROM stdin;
1	1	shipped	129.90	3	2024-03-01 10:00:00	2024-03-02 16:30:00	\N	2024-03-02 16:30:00+00:00
2	2	paid	54.00	1	2024-03-02 11:15:00	\N	Gift wrap 🎁	2024-03-02 11:20:00+00:00
3	1	cancelled	12.50	1	2024-03-03 09:45:00	\N	Customer changed their mind	2024-03-03 10:00:00+00:00
4	4	shipped	980.00	12	2024-03-05 02:10:00	2024-03-07 08:00:00	请小心轻放	2024-03-07 08:00:00+00:00
5	5	pending	45.75	2	2024-03-08 17:20:00	\N	Leave at the door; ring twice	2024-03-08 17:20:00+00:00
6	6	shipped	310.40	5	2024-03-10 13:00:00	2024-03-11 09:00:00	Fragile: "glass"	2024-03-11 09:00:00+00:00
7	8	paid	76.20	2	2024-03-11 18:45:00	\N	\N	2024-03-11 18:46:00+00:00
8	2		19.99	1	2024-03-12 08:00:00	\N	Status lost in an old import	2024-03-12 08:00:00+00:00
9	3	shipped	64.00	2	2024-03-14 15:30:00	\N	Shipping date never recorded	2024-03-15 10:00:00+00:00
10	7	paid	1499.00	1	2024-03-15 21:05:00	\N	C:\\Users\\ravi\\invoice.pdf	2024-03-15 21:05:00+00:00
\.


-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX customers_uq_email ON customers (email);
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX orders_idx_customer ON orders (customer_id);
CREATE INDEX orders_idx_status_date ON orders (status, ordered_at);
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_uq_email UNIQUE USING INDEX customers_uq_email;
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE orders ADD CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
    ALTER TABLE orders VALIDATE CONSTRAINT fk_orders_customer;
EXCEPTION WHEN foreign_key_violation THEN
    RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'fk_orders_customer';
END $f$;
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1001), 9223372036854775807)::bigint, false);
COMMENT ON TABLE customers IS 'People who bought at least once';
SELECT setval(pg_get_serial_sequence('orders', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM orders)::numeric, 0) + 1, 5001), 9223372036854775807)::bigint, false);
CREATE FUNCTION orders_updated_at_on_update() RETURNS trigger LANGUAGE plpgsql AS $f$
BEGIN
    IF NEW IS DISTINCT FROM OLD AND NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at THEN
        NEW.updated_at := CURRENT_TIMESTAMP;
    END IF;
    RETURN NEW;
END
$f$;
CREATE TRIGGER orders_updated_at_on_update BEFORE UPDATE ON orders FOR EACH ROW EXECUTE FUNCTION orders_updated_at_on_update();

Correções

  1. "id" de customers é sem sinal, então virou bigint com um CHECK de que não é negativa.
  2. "signed_up" de customers agora aceita NULL: alguns dos seus valores não puderam ser guardados e são NULL.
  3. O valor padrão de "signed_up" em customers, 0000‑00‑00, não é uma data que o PostgreSQL aceite, então a coluna fica sem valor padrão.
  4. "customer_id" de orders é sem sinal, então virou bigint com um CHECK de que não é negativa.
  5. "id" de orders é sem sinal, então virou bigint com um CHECK de que não é negativa.
  6. "items" de orders é sem sinal, então virou integer com um CHECK de que não é negativa.
  7. 1 linha de "status" em orders contém o valor vazio que o MySQL guarda para entradas inválidas; o CHECK dos valores o permite.
  8. "updated_at" de orders muda para a hora atual a cada atualização; no PostgreSQL, um gatilho faz isso.

Para revisar

  • 1 valor em "signed_up" de customers é uma data zero ou impossível, como 0000‑00‑00, que o PostgreSQL não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.
  • 1 valor em "shipped_at" de orders é uma data zero ou impossível, como 0000‑00‑00 00:00:00, que o PostgreSQL não consegue guardar, então ficou NULL. Se essas datas têm significado, troque-as na origem por datas reais antes do dump.

Seu arquivo é convertido neste computador e nunca é enviado.

Outros exemplos:

Todos os pares de bancos de dados

As linhas são o banco de dados de onde vem o dump, as colunas o banco de dados para o qual é o script. Cada par tem sua própria página com o conversor preparado para ele, as regras que aplica e como carregar o script.

Tipos de dados de cada par

O que é mantido e o que é relatado

O conversor lê o próprio dump, sem um servidor de banco de dados, e escreve o script a partir do que ele contém. A página de cada par lista as regras que aplica, entre 25 e 67 por par, com a linha do relatório que cada uma escreve.

Mantido no script

  • Tabelas e colunas, cada uma com o tipo mais próximo que o destino tem, com seu tamanho e precisão.
  • Chaves primárias, únicas e estrangeiras, índices e valores padrão.
  • Colunas AUTO_INCREMENT, identity e serial, com o id de cada linha e o contador continuando de onde o dump parou.
  • Cada linha, com datas, decimais, texto e valores binários como o dump os guarda.

Listado no relatório

  • Valores que o destino não aceita como estão, como uma data 0000-00-00 no PostgreSQL, com a coluna e quantos são.invalid_date_null
  • Tipos que o destino não tem, como ENUM ou INET6, com o tipo em que cada um se tornou.type_replaced
  • Views, triggers, procedures, funções e eventos, pelo nome: são escritos na própria linguagem de cada banco de dados, então não são convertidos.not_converted_objects
  • Texto que não é válido no seu conjunto de caracteres, e dumps que já perderam seus caracteres de 4 bytes.invalid_utf8_replaced

Comparado com o pgloader

Os mesmos dumps, convertidos e carregados pelo IntoSQL e pelo pgloader 3.6.7 em uma única máquina (um i9-10900K de 10 núcleos com SATA SSD), em outubro de 2026.

  • Uma coluna TINYINT(1) com 2, -1 e -5: o pgloader carrega true para cada um, sem aviso. O IntoSQL mantém os números e o relatório explica o motivo.
  • Um dump com um valor padrão 'it's', uma tabela com crase no nome, um ENUM com o valor vazio e um TIME acima de 24 horas: o pgloader para. O IntoSQL o converte e o carrega.
  • O que o pgloader carrega perdeu as chaves primárias, únicas e estrangeiras e as colunas identity. O IntoSQL mantém todas.
  • Um dump de 5.3 GB com 30 milhões de linhas: o pgloader exige restaurá-lo antes em um MySQL em execução, o que leva 18 minutos, e depois fica sem memória com as configurações padrão. O IntoSQL converte o dump em 10 segundos, e o psql carrega o script em cerca de 3 minutos.
  • Em 476 dumps do MySQL 5.5 ao 9 e do MariaDB 10.3 ao 12, carregados no PostgreSQL 13 e 18: nenhum erro de carga e nenhum valor alterado sem uma linha no relatório.
A página de MySQL para PostgreSQL

Exporte o banco de dados que você tem

O conversor lê um arquivo, não um servidor rodando. Cada banco de dados escreve um com suas próprias ferramentas:

Perguntas sobre migração de banco de dados

Não encontrou a resposta? Escreva para nós pela página de contato e uma pessoa responde. Página de contato

Meu dump é enviado?

Não. O conversor roda no seu navegador e lê o dump do seu disco em partes, então ele nunca sai do seu computador. O app para desktop e a linha de comando também convertem no seu computador.

Qual o tamanho máximo do dump?

O conversor nunca guarda o dump inteiro na memória: ele lê o arquivo duas vezes, por intervalos, e escreve o script à medida que avança. Dumps de vários gigabytes são convertidos no navegador, no app para desktop e com a linha de comando.

De quais versões o dump pode vir?

MySQL 5.5 ao 9, MariaDB 10.3 ao 12, PostgreSQL 10 ou posterior, SQL Server 2017 ou posterior, SQLite 3.0 ou posterior, e Oracle 11g ou posterior. A página de cada par diz em quais versões seu script carrega.

Preciso de um servidor de banco de dados rodando?

Não. O conversor lê o próprio arquivo de dump, então o banco de dados de origem não precisa rodar em lugar nenhum. O script carrega com o cliente do próprio destino, como psql, mysql ou sqlcmd.

O que não é convertido?

Views, triggers, stored procedures, funções e eventos são escritos na própria linguagem de cada banco de dados, então aparecem no relatório pelo nome. As tabelas, chaves, índices e linhas estão todos no script.

Ele pode carregar o script direto no meu banco de dados?

O app para desktop e o comando intosql load escrevem direto no SQLite de graça, e no PostgreSQL, MySQL e MariaDB com o IntoSQL Pro. Para SQL Server e Oracle, rode o script com sqlcmd ou sqlplus.