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.
18 baris dikonversi, 8 perbaikan, tidak ada yang ditolak
Tabel di shop_2024.sqlDump MySQL 8.0.46 · ditulis oleh mysqldump · utf8mb4
customers8 baris3
7 kolom id bigint not null name varchar(100) not null email varchar(150) not null country varchar(2) not null is_active boolean not null signed_up date created_at timestamptz(0) not null orders10 baris5
9 kolom id bigint not null customer_id bigint not null status text not null total numeric(10,2) not null items integer not null ordered_at timestamp(0) not null shipped_at timestamp(0) note varchar(255) updated_at timestamptz(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
- "id" dari customers bersifat unsigned, jadi menjadi bigint dengan CHECK bahwa nilainya tidak negatif.
- "signed_up" dari customers kini mengizinkan NULL: sebagian nilainya tidak bisa disimpan dan menjadi NULL.
- Default "signed_up" di customers, 0000‑00‑00, bukan tanggal yang diterima PostgreSQL, jadi kolom itu tanpa default.
- "customer_id" dari orders bersifat unsigned, jadi menjadi bigint dengan CHECK bahwa nilainya tidak negatif.
- "id" dari orders bersifat unsigned, jadi menjadi bigint dengan CHECK bahwa nilainya tidak negatif.
- "items" dari orders bersifat unsigned, jadi menjadi integer dengan CHECK bahwa nilainya tidak negatif.
- 1 baris dari "status" di orders berisi nilai kosong yang disimpan MySQL untuk entri tidak valid; CHECK untuk nilainya mengizinkannya.
- "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 MySQL | Di PostgreSQL | Baris laporan |
|---|---|---|
| TINYINT(1), BOOL | boolean 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 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. | unsigned_widened |
| ZEROFILL and display widths | dihapusIsian 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 NULL | NOT 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 |
| TIME | time 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 |
| YEAR | smallint 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. | |
| DATETIME | timestampDATETIME adalah pembacaan jam dinding tanpa zona waktu, seperti timestamp di PostgreSQL. | |
| TIMESTAMP | timestamptz 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 |
| ENUM | text 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 list | tanpa CHECKNilai yang tidak ada di daftar akan gagal di CHECK, jadi CHECK tidak dibuat. | enum_check_skipped |
| SET | text[] dengan CHECK bahwa setiap elemen ada di daftarArray memisahkan setiap elemen, jadi kueri bisa menguji keanggotaan. | |
| JSON | jsonb; 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 text | dihapusTeks PostgreSQL tidak bisa memuat byte NUL. Byte itu dihapus dan laporan menghitung nilainya. | nul_removed |
| text that isn't valid in its character set | byte 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_INCREMENT | GENERATED 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 key | satu penghitung untuk tabelMyISAM menghitung per grup kolom pertama kunci; PostgreSQL punya satu penghitung per kolom. | myisam_group_autoincrement |
| ON UPDATE CURRENT_TIMESTAMP | trigger BEFORE UPDATETrigger mengatur kolom ke waktu saat ini ketika baris berubah dan pembaruannya tidak mengatur kolom itu, seperti di MySQL. | on_update_trigger |
| generated columns | STOREDPostgreSQL 13 sampai 17 hanya menyimpan kolom generated; rumusnya sama. | virtual_as_stored |
| generated columns with functions PostgreSQL lacks | kolom biasaRumus yang tidak bisa ditulis untuk PostgreSQL menyisakan kolom biasa dan satu baris laporan. | generated_not_translated |
| INVISIBLE columns | kolom biasaPostgreSQL tidak punya kolom yang tidak terlihat. | invisible_column |
| CHECK constraints | diterjemahkan, langsung di CREATE TABLECHECK di dalam tabel diuji saat setiap baris dimuat, bukan dengan pemindaian per CHECK sesudahnya. | |
| CHECK constraints with functions PostgreSQL lacks | tidak dibuatCHECK yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan. | check_skipped |
| CHECK ... NOT ENFORCED | tidak dibuatMySQL menyimpan CHECK ini tanpa menerapkannya, jadi baris bisa melanggarnya. | check_not_enforced |
| defaults with functions PostgreSQL lacks | tanpa 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 indexes | GIN pada to_tsvector('simple', ...)Pencarian teks lengkap memakai @@ alih-alih MATCH ... AGAINST. | fulltext_as_gin |
| indexes on values over 2,000 bytes | hashEntri btree tidak bisa memuat nilai sepanjang itu; indeks hash tetap menemukan nilai yang sama. | index_on_wide_values |
| SPATIAL indexes | tidak dibuat tanpa PostGISIndeks spasial memerlukan PostGIS. | spatial_index_skipped |
| functional indexes PostgreSQL can't write | tidak dibuatIndeks pada ekspresi yang tidak bisa ditulis untuk PostgreSQL dihilangkan dan dilaporkan. | index_skipped |
| foreign keys | setelah 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 key | tidak dibuatPostgreSQL memerlukan kunci unik pada kolom yang dirujuk; InnoDB tidak. | foreign_key_skipped |
| table and column names | huruf kecil jika tetap unikNama huruf kecil bisa ditulis tanpa tanda kutip di PostgreSQL. | identifier_renamed |
| names over 63 bytes | dipersingkat 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, BLOB | byteaByte tetap byte. | |
| PARTITION BY | satu 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 engines | tabel biasaPostgreSQL punya satu engine tabel. | engine_dropped |
| views, triggers, procedures, functions and events | dicantumkan di laporanKodenya ditulis dalam bahasa MySQL, jadi dicantumkan agar Anda bisa membuatnya ulang. | not_converted_objects |
| dumps without CREATE TABLE | tipe 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 TABLE | WKB di byteaFormat geometri MySQL dikenali dari nilainya dan disimpan sebagai WKB standar. | geometry_inferred |
| _ci collations | perbandingan persisPostgreSQL membandingkan teks secara persis kecuali diminta lain. | case_insensitive_collation |
| SET NAMES utf8 from utf8mb4 tables | dikonversi, 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-8 | dibaca sebagai Latin-1 (Windows-1252)latin1 di MySQL adalah Windows-1252, pengodean yang biasa dipakai dump semacam itu. | charset_guessed |
| sjis, cp932, gbk, big5 dumps | dibaca sebagai UTF-8, dengan peringatanPengodean ini belum didekode. | unsupported_charset |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | dievaluasiBeberapa 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 | NULLKonverter yang tidak menjalankan database tidak bisa mengevaluasinya. | expression_value |
| DEFAULT in VALUES | nilai default kolomDefault literal disalin ke baris. | default_keyword_filled |
| DEFAULT in VALUES without a literal default | NULLTidak ada nilai untuk disalin. | default_keyword_null |
| REPLACE and INSERT IGNORE | baris biasaDump punya satu baris per kunci, jadi barisnya sama. | replace_as_insert |
| types IntoSQL doesn't know | textText memuat nilai apa pun; ubah tipenya setelah pemuatan. | unknown_type |
| values that don't fit their column | NULLDump 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 geometries | NULLByte 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.sqlForeign 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.