Langsung ke konten

Konversi MySQL ke PostgreSQL

Letakkan dump dari mysqldump, mariadb-dump, mysqlpump, phpMyAdmin, atau Adminer, sebagai .sql atau .sql.gz, lalu unduh skrip PostgreSQL dengan tabel, kunci, indeks, dan data yang sama. Setiap nilai yang tidak bisa disimpan PostgreSQL apa adanya, dan setiap objek yang tidak didukungnya, dicantumkan di laporan.

File Anda
sqlshop_2024.sqlFile contoh, 5,1 kB
Database Anda

18 baris dikonversi, 8 perbaikan, tidak ada yang ditolak

Tampilkan

Tabel di shop_2024.sqlDump MySQL 8.0.46 · ditulis oleh mysqldump · utf8mb4

  • customers8 baris3
    7 kolom
    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 baris5
    9 kolom
    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();

Perbaikan

  1. "id" dari customers bersifat unsigned, jadi menjadi bigint dengan CHECK bahwa nilainya tidak negatif.
  2. "signed_up" dari customers kini mengizinkan NULL: sebagian nilainya tidak bisa disimpan dan menjadi NULL.
  3. Default "signed_up" di customers, 0000‑00‑00, bukan tanggal yang diterima PostgreSQL, jadi kolom itu tanpa default.
  4. "customer_id" dari orders bersifat unsigned, jadi menjadi bigint dengan CHECK bahwa nilainya tidak negatif.
  5. "id" dari orders bersifat unsigned, jadi menjadi bigint dengan CHECK bahwa nilainya tidak negatif.
  6. "items" dari orders bersifat unsigned, jadi menjadi integer dengan CHECK bahwa nilainya tidak negatif.
  7. 1 baris dari "status" di orders berisi nilai kosong yang disimpan MySQL untuk entri tidak valid; CHECK untuk nilainya mengizinkannya.
  8. "updated_at" dari orders berubah ke waktu saat ini di setiap pembaruan; di PostgreSQL, trigger yang melakukannya.

Perlu diperiksa

  • 1 nilai di "signed_up" dari customers adalah tanggal nol atau mustahil, misalnya 0000‑00‑00, yang tidak bisa disimpan PostgreSQL, jadi menjadi NULL. Jika tanggal itu bermakna, ganti di sumber dengan tanggal sungguhan sebelum membuat dump.
  • 1 nilai di "shipped_at" dari orders adalah tanggal nol atau mustahil, misalnya 0000‑00‑00 00:00:00, yang tidak bisa disimpan PostgreSQL, jadi menjadi NULL. Jika tanggal itu bermakna, ganti di sumber dengan tanggal sungguhan sebelum membuat dump.

File Anda dikonversi di komputer ini dan tidak pernah diunggah.

Contoh lain:

Yang berubah dari MySQL ke PostgreSQL

Setiap baris adalah aturan yang diterapkan konverter, beserta baris laporan yang ditulisnya saat aturan itu mengubah sesuatu di data Anda.

  • TINYINT(1), BOOL

    boolean jika setiap nilai 0 atau 1, selain itu smallint

    BOOL di MySQL adalah TINYINT(1) yang bisa berisi angka apa pun dari -128 sampai 127. Kolom yang hanya berisi 0 dan 1 menjadi boolean; kolom yang berisi 2 atau -1 tetap berupa angka agar tidak ada nilai yang berubah makna.

    Baris laporan: bool_kept_numeric

  • UNSIGNED integers

    bilangan bulat yang lebih lebar dengan CHECK bahwa nilainya tidak negatif; BIGINT UNSIGNED menjadi bigint jika semua nilai muat, selain itu numeric(20,0)

    PostgreSQL tidak punya bilangan bulat unsigned. Tipe yang lebih lebar memuat seluruh rentang unsigned, dan CHECK mencegah nilai negatif seperti di MySQL.

    Baris laporan: unsigned_widened

  • ZEROFILL and display widths

    dihapus

    Isian nol adalah cara menampilkan angka, bukan bagian dari angka. Angkanya dipertahankan; format saat dibaca jika isian itu penting.

    Baris laporan: zerofill_dropped

  • FLOAT(M,D)

    real atau double precision, tanpa skala

    Bilangan floating-point PostgreSQL tidak punya skala tetap. Nilai yang tersimpan disalin apa adanya.

    Baris laporan: float_scale_dropped

  • BIT(1), BIT(n)

    boolean, bit(n)

    Satu bit berarti ya atau tidak; field bit yang lebih lebar mempertahankan setiap bit.

  • zero, partial or impossible dates (0000-00-00, 2024-02-30)

    NULL

    PostgreSQL hanya menyimpan tanggal kalender yang nyata. MySQL menyimpan tanggal nol dan mustahil jika mode SQL-nya mengizinkan; tanggal itu menjadi NULL dan laporan menghitungnya.

    Baris laporan: invalid_date_null

  • NOT NULL columns with values that become NULL

    NOT NULL dihapus

    Kolom yang nilainya harus menjadi NULL tidak bisa mempertahankan NOT NULL, atau pemuatan akan berhenti.

    Baris laporan: not_null_relaxed

  • DEFAULT '0000-00-00'

    tanpa default

    Default yang tidak bisa disimpan PostgreSQL dihilangkan, bukan diganti dengan tanggal karangan.

    Baris laporan: zero_date_default

  • TIME

    time jika setiap nilai dalam sehari, selain itu interval

    TIME di MySQL adalah durasi dari -838:59:59 sampai 838:59:59. Kolom yang nilainya muat dalam sehari tetap menjadi jam dalam sehari; kolom dengan nilai lebih panjang atau negatif menjadi interval.

    Baris laporan: time_as_interval

  • YEAR

    smallint dengan CHECK rentangnya

    PostgreSQL tidak punya tipe tahun; CHECK mempertahankan nilai yang sama dengan yang diizinkan MySQL.

  • CHAR(n)

    varchar(n)

    MySQL menghapus spasi di akhir nilai CHAR saat membacanya, dan char(n) di PostgreSQL akan menambahkannya kembali, jadi varchar(n) mempertahankan nilai seperti yang dikembalikan MySQL.

  • DATETIME

    timestamp

    DATETIME adalah pembacaan jam dinding tanpa zona waktu, seperti timestamp di PostgreSQL.

  • TIMESTAMP

    timestamptz dalam zona waktu yang disebutkan dump, UTC jika tidak disebutkan

    TIMESTAMP adalah satu momen. Dump menyebutkan zona tempat nilainya ditulis (mysqldump menulis UTC); tanpa itu, nilainya dibaca sebagai UTC dan laporan menyebutkannya.

    Baris laporan: timestamp_zone_assumed

  • ENUM

    text dengan CHECK nilainya

    Text dengan CHECK mempertahankan nilai yang sama dan lebih mudah diubah daripada enum type PostgreSQL.

  • ENUM holding '' (MySQL's error value)

    nilai kosong yang diizinkan CHECK

    MySQL menyimpan string kosong saat nilai tidak valid masuk ke ENUM dalam mode SQL yang longgar. Baris itu dipertahankan dan CHECK mengizinkannya.

    Baris laporan: enum_invalid_value

  • ENUM or SET holding values outside its list

    tanpa CHECK

    Nilai yang tidak ada di daftar akan gagal di CHECK, jadi CHECK tidak dibuat.

    Baris laporan: enum_check_skipped

  • SET

    text[] dengan CHECK bahwa setiap elemen ada di daftar

    Array memisahkan setiap elemen, jadi kueri bisa menguji keanggotaan.

  • JSON

    jsonb; json jika ada nilai yang berisi \u0000

    jsonb adalah tipe yang diindeks dan dikueri PostgreSQL dengan baik, tetapi menolak escape \u0000, jadi kolom yang berisi itu tetap json.

    Baris laporan: json_not_jsonb

  • NUL bytes in text

    dihapus

    Teks PostgreSQL tidak bisa memuat byte NUL. Byte itu dihapus dan laporan menghitung nilainya.

    Baris laporan: nul_removed

  • text that isn't valid in its character set

    byte yang rusak menjadi karakter pengganti

    Teks PostgreSQL harus berupa UTF-8 yang valid.

    Baris laporan: invalid_utf8_replaced

  • text decoded twice (ñ)

    disalin apa adanya

    Dump berisi persis karakter ini, jadi karakter itu disalin; laporan menunjukkannya.

    Baris laporan: mojibake_suspected

  • AUTO_INCREMENT

    GENERATED BY DEFAULT AS IDENTITY, dengan penghitung diatur melewati id yang disalin

    Kolom identity menerima id yang disalin, dan penghitung berlanjut setelah id tertinggi atau AUTO_INCREMENT dari dump, mana yang lebih tinggi.

  • MyISAM AUTO_INCREMENT on the second column of a key

    satu penghitung untuk tabel

    MyISAM menghitung per grup kolom pertama kunci; PostgreSQL punya satu penghitung per kolom.

    Baris laporan: myisam_group_autoincrement

  • ON UPDATE CURRENT_TIMESTAMP

    trigger BEFORE UPDATE

    Trigger mengatur kolom ke waktu saat ini ketika baris berubah dan pembaruannya tidak mengatur kolom itu, seperti di MySQL.

    Baris laporan: on_update_trigger

  • generated columns

    STORED

    PostgreSQL 13 sampai 17 hanya menyimpan kolom generated; rumusnya sama.

    Baris laporan: virtual_as_stored

  • generated columns with functions PostgreSQL lacks

    kolom biasa

    Rumus yang tidak bisa ditulis untuk PostgreSQL menyisakan kolom biasa dan satu baris laporan.

    Baris laporan: generated_not_translated

  • INVISIBLE columns

    kolom biasa

    PostgreSQL tidak punya kolom yang tidak terlihat.

    Baris laporan: invisible_column

  • CHECK constraints

    diterjemahkan, langsung di CREATE TABLE

    CHECK di dalam tabel diuji saat setiap baris dimuat, bukan dengan pemindaian per CHECK sesudahnya.

  • CHECK constraints with functions PostgreSQL lacks

    tidak dibuat

    CHECK yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan.

    Baris laporan: check_skipped

  • CHECK ... NOT ENFORCED

    tidak dibuat

    MySQL menyimpan CHECK ini tanpa menerapkannya, jadi baris bisa melanggarnya.

    Baris laporan: check_not_enforced

  • defaults with functions PostgreSQL lacks

    tanpa default

    Default yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan.

    Baris laporan: default_not_translated

  • keys and indexes on a prefix, c(20)

    indeks pada left(c, 20)

    PostgreSQL bisa mengindeks ekspresi, jadi prefiks yang sama diindeks.

    Baris laporan: prefix_unique

  • FULLTEXT indexes

    GIN pada to_tsvector('simple', ...)

    Pencarian teks lengkap memakai @@ alih-alih MATCH ... AGAINST.

    Baris laporan: fulltext_as_gin

  • indexes on values over 2,000 bytes

    hash

    Entri btree tidak bisa memuat nilai sepanjang itu; indeks hash tetap menemukan nilai yang sama.

    Baris laporan: index_on_wide_values

  • SPATIAL indexes

    tidak dibuat tanpa PostGIS

    Indeks spasial memerlukan PostGIS.

    Baris laporan: spatial_index_skipped

  • functional indexes PostgreSQL can't write

    tidak dibuat

    Indeks pada ekspresi yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan.

    Baris laporan: index_skipped

  • foreign keys

    setelah data, NOT VALID, lalu divalidasi dengan peringatan untuk baris yatim

    Dump dimuat dengan FOREIGN_KEY_CHECKS=0 dan MyISAM tidak pernah memeriksa, jadi baris tanpa induk umum ditemukan. Key dibuat lebih dulu dan divalidasi terakhir; baris yatim membuatnya tetap NOT VALID dengan peringatan, bukan menghentikan pemuatan.

  • foreign keys to columns without a unique key

    tidak dibuat

    PostgreSQL memerlukan kunci unik pada kolom yang dirujuk; InnoDB tidak.

    Baris laporan: foreign_key_skipped

  • table and column names

    huruf kecil jika tetap unik

    Nama huruf kecil bisa ditulis tanpa tanda kutip di PostgreSQL.

    Baris laporan: identifier_renamed

  • names over 63 bytes

    dipersingkat dengan hash

    Nama di PostgreSQL memuat 63 byte; hash menjaga nama yang dipersingkat tetap berbeda.

    Baris laporan: name_shortened

  • GEOMETRY, POINT, POLYGON...

    WKB di bytea

    Tanpa PostGIS, format biner well-known standar mempertahankan setiap geometri dengan persis.

    Baris laporan: geometry_as_wkb

  • INET4, INET6, UUID (MariaDB)

    inet, uuid

    PostgreSQL punya tipe yang sama.

  • BINARY, VARBINARY, BLOB

    bytea

    Byte tetap byte.

  • PARTITION BY

    satu tabel

    Barisnya sama; partisi ulang tabel di PostgreSQL jika diperlukan.

    Baris laporan: partitions_dropped

  • WITH SYSTEM VERSIONING (MariaDB)

    tabel dengan baris saat ini

    Dump hanya berisi baris saat ini.

    Baris laporan: system_versioning_dropped

  • MyISAM, MEMORY and other engines

    tabel biasa

    PostgreSQL punya satu engine tabel.

    Baris laporan: engine_dropped

  • views, triggers, procedures, functions and events

    dicantumkan di laporan

    Kodenya ditulis dalam bahasa MySQL, jadi dicantumkan agar Anda bisa membuatnya ulang.

    Baris laporan: not_converted_objects

  • dumps without CREATE TABLE

    tipe dibaca dari nilai

    Dump yang dibuat dengan --no-create-info hanya berisi baris, jadi tipenya diambil dari nilai.

    Baris laporan: no_schema

  • geometries in a dump without CREATE TABLE

    WKB di bytea

    Format geometri MySQL dikenali dari nilainya dan disimpan sebagai WKB standar.

    Baris laporan: geometry_inferred

  • _ci collations

    perbandingan persis

    PostgreSQL membandingkan teks secara persis kecuali diminta lain.

    Baris laporan: case_insensitive_collation

  • SET NAMES utf8 from utf8mb4 tables

    dikonversi, dengan peringatan

    mysqldump di MySQL 5.x secara default menulis utf8 3 byte dan mengganti setiap emoji dengan tanda tanya sebelum konverter mana pun melihat file itu.

    Baris laporan: dump_lost_four_byte_chars

  • dumps without SET NAMES whose text isn't UTF-8

    dibaca sebagai Latin-1 (Windows-1252)

    latin1 di MySQL adalah Windows-1252, pengodean yang biasa dipakai dump semacam itu.

    Baris laporan: charset_guessed

  • sjis, cp932, gbk, big5 dumps

    dibaca sebagai UTF-8, dengan peringatan

    Pengodean ini belum didekode.

    Baris laporan: unsupported_charset

  • UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows

    dievaluasi

    Beberapa alat dump menulis nilai sebagai panggilan ini; panggilan itu dibaca sebagai nilai yang dihasilkannya, dengan WKT geografis diubah agar longitude lebih dulu.

  • other expressions in rows

    NULL

    Konverter yang tidak menjalankan database tidak bisa mengevaluasinya.

    Baris laporan: expression_value

  • DEFAULT in VALUES

    nilai default kolom

    Default literal disalin ke baris.

    Baris laporan: default_keyword_filled

  • DEFAULT in VALUES without a literal default

    NULL

    Tidak ada nilai untuk disalin.

    Baris laporan: default_keyword_null

  • REPLACE and INSERT IGNORE

    baris biasa

    Dump punya satu baris per kunci, jadi barisnya sama.

    Baris laporan: replace_as_insert

  • types IntoSQL doesn't know

    text

    Text memuat nilai apa pun; ubah tipenya setelah pemuatan.

    Baris laporan: unknown_type

  • values that don't fit their column

    NULL

    Dump yang rusak atau ditulis manual bisa berisi nilai yang tidak muat di kolomnya; nilai itu menjadi NULL agar sisanya tetap dimuat.

    Baris laporan: invalid_value_null

  • unreadable geometries

    NULL

    Byte yang bukan geometri tidak bisa disimpan sebagai geometri.

    Baris laporan: bad_geometry

  • CREATE SEQUENCE (MariaDB)

    CREATE SEQUENCE dengan nilai saat ini

    Sequence PostgreSQL menerima opsi yang sama.

Di MySQLDi PostgreSQLBaris laporan
TINYINT(1), BOOLboolean jika setiap nilai 0 atau 1, selain itu smallintBOOL di MySQL adalah TINYINT(1) yang bisa berisi angka apa pun dari -128 sampai 127. Kolom yang hanya berisi 0 dan 1 menjadi boolean; kolom yang berisi 2 atau -1 tetap berupa angka agar tidak ada nilai yang berubah makna.bool_kept_numeric
UNSIGNED integersbilangan bulat yang lebih lebar dengan CHECK bahwa nilainya tidak negatif; BIGINT UNSIGNED menjadi bigint jika semua nilai muat, selain itu numeric(20,0)PostgreSQL tidak punya bilangan bulat unsigned. Tipe yang lebih lebar memuat seluruh rentang unsigned, dan CHECK mencegah nilai negatif seperti di MySQL.unsigned_widened
ZEROFILL and display widthsdihapusIsian nol adalah cara menampilkan angka, bukan bagian dari angka. Angkanya dipertahankan; format saat dibaca jika isian itu penting.zerofill_dropped
FLOAT(M,D)real atau double precision, tanpa skalaBilangan floating-point PostgreSQL tidak punya skala tetap. Nilai yang tersimpan disalin apa adanya.float_scale_dropped
BIT(1), BIT(n)boolean, bit(n)Satu bit berarti ya atau tidak; field bit yang lebih lebar mempertahankan setiap bit.
zero, partial or impossible dates (0000-00-00, 2024-02-30)NULLPostgreSQL hanya menyimpan tanggal kalender yang nyata. MySQL menyimpan tanggal nol dan mustahil jika mode SQL-nya mengizinkan; tanggal itu menjadi NULL dan laporan menghitungnya.invalid_date_null
NOT NULL columns with values that become NULLNOT NULL dihapusKolom yang nilainya harus menjadi NULL tidak bisa mempertahankan NOT NULL, atau pemuatan akan berhenti.not_null_relaxed
DEFAULT '0000-00-00'tanpa defaultDefault yang tidak bisa disimpan PostgreSQL dihilangkan, bukan diganti dengan tanggal karangan.zero_date_default
TIMEtime jika setiap nilai dalam sehari, selain itu intervalTIME di MySQL adalah durasi dari -838:59:59 sampai 838:59:59. Kolom yang nilainya muat dalam sehari tetap menjadi jam dalam sehari; kolom dengan nilai lebih panjang atau negatif menjadi interval.time_as_interval
YEARsmallint dengan CHECK rentangnyaPostgreSQL tidak punya tipe tahun; CHECK mempertahankan nilai yang sama dengan yang diizinkan MySQL.
CHAR(n)varchar(n)MySQL menghapus spasi di akhir nilai CHAR saat membacanya, dan char(n) di PostgreSQL akan menambahkannya kembali, jadi varchar(n) mempertahankan nilai seperti yang dikembalikan MySQL.
DATETIMEtimestampDATETIME adalah pembacaan jam dinding tanpa zona waktu, seperti timestamp di PostgreSQL.
TIMESTAMPtimestamptz dalam zona waktu yang disebutkan dump, UTC jika tidak disebutkanTIMESTAMP adalah satu momen. Dump menyebutkan zona tempat nilainya ditulis (mysqldump menulis UTC); tanpa itu, nilainya dibaca sebagai UTC dan laporan menyebutkannya.timestamp_zone_assumed
ENUMtext dengan CHECK nilainyaText dengan CHECK mempertahankan nilai yang sama dan lebih mudah diubah daripada enum type PostgreSQL.
ENUM holding '' (MySQL's error value)nilai kosong yang diizinkan CHECKMySQL menyimpan string kosong saat nilai tidak valid masuk ke ENUM dalam mode SQL yang longgar. Baris itu dipertahankan dan CHECK mengizinkannya.enum_invalid_value
ENUM or SET holding values outside its listtanpa CHECKNilai yang tidak ada di daftar akan gagal di CHECK, jadi CHECK tidak dibuat.enum_check_skipped
SETtext[] dengan CHECK bahwa setiap elemen ada di daftarArray memisahkan setiap elemen, jadi kueri bisa menguji keanggotaan.
JSONjsonb; json jika ada nilai yang berisi \u0000jsonb adalah tipe yang diindeks dan dikueri PostgreSQL dengan baik, tetapi menolak escape \u0000, jadi kolom yang berisi itu tetap json.json_not_jsonb
NUL bytes in textdihapusTeks PostgreSQL tidak bisa memuat byte NUL. Byte itu dihapus dan laporan menghitung nilainya.nul_removed
text that isn't valid in its character setbyte yang rusak menjadi karakter penggantiTeks PostgreSQL harus berupa UTF-8 yang valid.invalid_utf8_replaced
text decoded twice (ñ)disalin apa adanyaDump berisi persis karakter ini, jadi karakter itu disalin; laporan menunjukkannya.mojibake_suspected
AUTO_INCREMENTGENERATED BY DEFAULT AS IDENTITY, dengan penghitung diatur melewati id yang disalinKolom identity menerima id yang disalin, dan penghitung berlanjut setelah id tertinggi atau AUTO_INCREMENT dari dump, mana yang lebih tinggi.
MyISAM AUTO_INCREMENT on the second column of a keysatu penghitung untuk tabelMyISAM menghitung per grup kolom pertama kunci; PostgreSQL punya satu penghitung per kolom.myisam_group_autoincrement
ON UPDATE CURRENT_TIMESTAMPtrigger BEFORE UPDATETrigger mengatur kolom ke waktu saat ini ketika baris berubah dan pembaruannya tidak mengatur kolom itu, seperti di MySQL.on_update_trigger
generated columnsSTOREDPostgreSQL 13 sampai 17 hanya menyimpan kolom generated; rumusnya sama.virtual_as_stored
generated columns with functions PostgreSQL lackskolom biasaRumus yang tidak bisa ditulis untuk PostgreSQL menyisakan kolom biasa dan satu baris laporan.generated_not_translated
INVISIBLE columnskolom biasaPostgreSQL tidak punya kolom yang tidak terlihat.invisible_column
CHECK constraintsditerjemahkan, langsung di CREATE TABLECHECK di dalam tabel diuji saat setiap baris dimuat, bukan dengan pemindaian per CHECK sesudahnya.
CHECK constraints with functions PostgreSQL lackstidak dibuatCHECK yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan.check_skipped
CHECK ... NOT ENFORCEDtidak dibuatMySQL menyimpan CHECK ini tanpa menerapkannya, jadi baris bisa melanggarnya.check_not_enforced
defaults with functions PostgreSQL lackstanpa defaultDefault yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan.default_not_translated
keys and indexes on a prefix, c(20)indeks pada left(c, 20)PostgreSQL bisa mengindeks ekspresi, jadi prefiks yang sama diindeks.prefix_unique
FULLTEXT indexesGIN pada to_tsvector('simple', ...)Pencarian teks lengkap memakai @@ alih-alih MATCH ... AGAINST.fulltext_as_gin
indexes on values over 2,000 byteshashEntri btree tidak bisa memuat nilai sepanjang itu; indeks hash tetap menemukan nilai yang sama.index_on_wide_values
SPATIAL indexestidak dibuat tanpa PostGISIndeks spasial memerlukan PostGIS.spatial_index_skipped
functional indexes PostgreSQL can't writetidak dibuatIndeks pada ekspresi yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan.index_skipped
foreign keyssetelah data, NOT VALID, lalu divalidasi dengan peringatan untuk baris yatimDump dimuat dengan FOREIGN_KEY_CHECKS=0 dan MyISAM tidak pernah memeriksa, jadi baris tanpa induk umum ditemukan. Key dibuat lebih dulu dan divalidasi terakhir; baris yatim membuatnya tetap NOT VALID dengan peringatan, bukan menghentikan pemuatan.
foreign keys to columns without a unique keytidak dibuatPostgreSQL memerlukan kunci unik pada kolom yang dirujuk; InnoDB tidak.foreign_key_skipped
table and column nameshuruf kecil jika tetap unikNama huruf kecil bisa ditulis tanpa tanda kutip di PostgreSQL.identifier_renamed
names over 63 bytesdipersingkat dengan hashNama di PostgreSQL memuat 63 byte; hash menjaga nama yang dipersingkat tetap berbeda.name_shortened
GEOMETRY, POINT, POLYGON...WKB di byteaTanpa PostGIS, format biner well-known standar mempertahankan setiap geometri dengan persis.geometry_as_wkb
INET4, INET6, UUID (MariaDB)inet, uuidPostgreSQL punya tipe yang sama.
BINARY, VARBINARY, BLOBbyteaByte tetap byte.
PARTITION BYsatu tabelBarisnya sama; partisi ulang tabel di PostgreSQL jika diperlukan.partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)tabel dengan baris saat iniDump hanya berisi baris saat ini.system_versioning_dropped
MyISAM, MEMORY and other enginestabel biasaPostgreSQL punya satu engine tabel.engine_dropped
views, triggers, procedures, functions and eventsdicantumkan di laporanKodenya ditulis dalam bahasa MySQL, jadi dicantumkan agar Anda bisa membuatnya ulang.not_converted_objects
dumps without CREATE TABLEtipe dibaca dari nilaiDump yang dibuat dengan --no-create-info hanya berisi baris, jadi tipenya diambil dari nilai.no_schema
geometries in a dump without CREATE TABLEWKB di byteaFormat geometri MySQL dikenali dari nilainya dan disimpan sebagai WKB standar.geometry_inferred
_ci collationsperbandingan persisPostgreSQL membandingkan teks secara persis kecuali diminta lain.case_insensitive_collation
SET NAMES utf8 from utf8mb4 tablesdikonversi, dengan peringatanmysqldump di MySQL 5.x secara default menulis utf8 3 byte dan mengganti setiap emoji dengan tanda tanya sebelum konverter mana pun melihat file itu.dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8dibaca sebagai Latin-1 (Windows-1252)latin1 di MySQL adalah Windows-1252, pengodean yang biasa dipakai dump semacam itu.charset_guessed
sjis, cp932, gbk, big5 dumpsdibaca sebagai UTF-8, dengan peringatanPengodean ini belum didekode.unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rowsdievaluasiBeberapa alat dump menulis nilai sebagai panggilan ini; panggilan itu dibaca sebagai nilai yang dihasilkannya, dengan WKT geografis diubah agar longitude lebih dulu.
other expressions in rowsNULLKonverter yang tidak menjalankan database tidak bisa mengevaluasinya.expression_value
DEFAULT in VALUESnilai default kolomDefault literal disalin ke baris.default_keyword_filled
DEFAULT in VALUES without a literal defaultNULLTidak ada nilai untuk disalin.default_keyword_null
REPLACE and INSERT IGNOREbaris biasaDump punya satu baris per kunci, jadi barisnya sama.replace_as_insert
types IntoSQL doesn't knowtextText memuat nilai apa pun; ubah tipenya setelah pemuatan.unknown_type
values that don't fit their columnNULLDump yang rusak atau ditulis manual bisa berisi nilai yang tidak muat di kolomnya; nilai itu menjadi NULL agar sisanya tetap dimuat.invalid_value_null
unreadable geometriesNULLByte yang bukan geometri tidak bisa disimpan sebagai geometri.bad_geometry
CREATE SEQUENCE (MariaDB)CREATE SEQUENCE dengan nilai saat iniSequence PostgreSQL menerima opsi yang sama.

Muat skrip ke PostgreSQL

Skrip membuat tabel, menyalin baris, lalu menambahkan kunci, indeks, dan foreign key, jadi pemuatan berjalan cepat dan berhenti di galat pertama.

psql -v ON_ERROR_STOP=1 -d mydb -f mysql.postgresql.sql

Foreign key ditambahkan sebagai NOT VALID lalu divalidasi. Jika sebuah baris merujuk ke baris yang tidak ada, skrip memberi tahu constraint mana, bukan gagal di tengah jalan.

Untuk dump yang besar, buat database terlebih dahulu dan jalankan skrip dengan psql dari mesin yang sama dengan server.

Buat dump MySQL untuk hasil terbaik

Konverter membaca apa yang ada di dump. Opsi berikut membuat lebih banyak data Anda tetap ada di dalamnya:

  • --default-character-set=utf8mb4 mempertahankan emoji dan karakter 4 byte lainnya, yang hilang di dump utf8 sebelum konverter melihatnya.
  • --hex-blob menulis kolom biner sebagai heksadesimal, yang tetap utuh saat disalin antarsistem.
  • --routines --triggers --events menambahkan objek-objek itu ke dump, sehingga laporan bisa mencantumkannya.

Yang tidak dikonversi

View, trigger, stored procedure, fungsi, dan event ditulis dalam bahasa masing-masing database. Semuanya dicantumkan di laporan berdasarkan nama, tidak pernah dibuang diam-diam, sehingga Anda bisa menulis ulang untuk PostgreSQL.

Diukur terhadap pgloader

Dump yang sama, dikonversi dan dimuat oleh IntoSQL dan oleh pgloader 3.6.7 di satu mesin (i9-10900K 10 inti dengan SATA SSD), pada Oktober 2026.

  • Kolom TINYINT(1) berisi 2, -1, dan -5: pgloader memuat true untuk masing-masing, tanpa peringatan. IntoSQL mempertahankan angkanya dan laporan menjelaskan alasannya.
  • Dump dengan default 'it's', tabel yang namanya memakai backtick, ENUM berisi nilai kosong, dan TIME lebih dari 24 jam: pgloader berhenti. IntoSQL mengonversi dan memuatnya.
  • Yang dimuat pgloader kehilangan primary key, unique key, foreign key, dan identity-nya. IntoSQL mempertahankan semuanya.
  • Dump 5.3 GB berisi 30 juta baris: pgloader memerlukan dump itu dipulihkan dulu ke MySQL yang berjalan, yang memakan 18 menit, lalu kehabisan memori dengan pengaturan bawaannya. IntoSQL mengonversi dump dalam 10 detik, dan psql memuat skripnya dalam sekitar 3 menit.
  • Pada 476 dump dari MySQL 5.5 sampai 9 dan MariaDB 10.3 sampai 12, yang dimuat ke PostgreSQL 13 dan 18: tidak ada galat pemuatan, dan tidak ada nilai yang berubah tanpa satu baris di laporan.

Pertanyaan tentang MySQL ke PostgreSQL

Tidak terjawab di sini? Tulis ke kami dari halaman kontak, dan seseorang akan membalas. Halaman kontak

Apakah dump saya diunggah?

Tidak. Konverter berjalan di browser Anda dan membaca dump dari disk Anda sepotong demi sepotong, jadi dump tidak pernah meninggalkan komputer Anda. Aplikasi desktop dan command line juga mengonversi di komputer Anda.

Seberapa besar dump yang bisa dipakai?

Konverter tidak pernah menyimpan seluruh dump di memori: file dibaca dua kali, per rentang, dan skrip ditulis sambil berjalan. Dump berukuran beberapa gigabyte bisa dikonversi di browser, di aplikasi desktop, dan dengan command line.

Apakah dump MariaDB bisa dibaca?

Ya. Dump dari mariadb-dump dan dari MariaDB 10.3 sampai 12 dikonversi dengan cara yang sama, termasuk kolom INET6, INET4, dan UUID milik MariaDB.

Apa yang terjadi pada tanggal 0000-00-00?

PostgreSQL tidak punya tanggal nol, jadi tanggal itu menjadi NULL dan kolomnya menerima NULL. Laporan menyebutkan jumlahnya di setiap kolom.

Apakah nilai AUTO_INCREMENT dipertahankan?

Ya. Setiap kolom AUTO_INCREMENT menjadi kolom identity, setiap baris mempertahankan id-nya, dan id berikutnya berlanjut setelah id tertinggi, atau setelah AUTO_INCREMENT tabel jika itu lebih tinggi.

Apakah TINYINT(1) menjadi boolean?

Hanya jika setiap nilai di kolom itu 0 atau 1. Jika berisi angka lain, seperti 2 atau -1, kolom tetap berupa angka dan laporan menjelaskan alasannya, jadi tidak ada nilai yang tanpa sengaja menjadi true.

Bagaimana dengan stored procedure dan trigger?

Semuanya dicantumkan di laporan berdasarkan nama dan tidak dikonversi, karena setiap database menulisnya dalam bahasanya sendiri. ON UPDATE CURRENT_TIMESTAMP adalah pengecualian: menjadi trigger PostgreSQL.

Di versi PostgreSQL mana skrip bisa dimuat?

PostgreSQL 13 sampai 18. Skrip yang sama dimuat di setiap versi itu, dan berhenti di galat pertama jika ada yang salah.