---
title: "Konversi MySQL ke PostgreSQL"
description: "Konversi dump MySQL atau MariaDB menjadi skrip PostgreSQL yang langsung bisa dimuat, dengan laporan setiap perubahan. Di browser: dump tidak diunggah."
canonical: https://intosql.com/id/mysql-ke-postgresql
last_updated: 2026-10-15
---

# 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.

## 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.

| Di MySQL | Di PostgreSQL | Baris laporan |
| --- | --- | --- |
| TINYINT(1), BOOL | boolean jika setiap nilai 0 atau 1, selain itu smallint | `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) | `unsigned_widened` |
| ZEROFILL and display widths | dihapus | `zerofill_dropped` |
| FLOAT(M,D) | real atau double precision, tanpa skala | `float_scale_dropped` |
| BIT(1), BIT(n) | boolean, bit(n) |  |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULL | `invalid_date_null` |
| NOT NULL columns with values that become NULL | NOT NULL dihapus | `not_null_relaxed` |
| DEFAULT '0000-00-00' | tanpa default | `zero_date_default` |
| TIME | time jika setiap nilai dalam sehari, selain itu interval | `time_as_interval` |
| YEAR | smallint dengan CHECK rentangnya |  |
| CHAR(n) | varchar(n) |  |
| DATETIME | timestamp |  |
| TIMESTAMP | timestamptz dalam zona waktu yang disebutkan dump, UTC jika tidak disebutkan | `timestamp_zone_assumed` |
| ENUM | text dengan CHECK nilainya |  |
| ENUM holding '' (MySQL's error value) | nilai kosong yang diizinkan CHECK | `enum_invalid_value` |
| ENUM or SET holding values outside its list | tanpa CHECK | `enum_check_skipped` |
| SET | text[] dengan CHECK bahwa setiap elemen ada di daftar |  |
| JSON | jsonb; json jika ada nilai yang berisi \u0000 | `json_not_jsonb` |
| NUL bytes in text | dihapus | `nul_removed` |
| text that isn't valid in its character set | byte yang rusak menjadi karakter pengganti | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | disalin apa adanya | `mojibake_suspected` |
| AUTO_INCREMENT | GENERATED BY DEFAULT AS IDENTITY, dengan penghitung diatur melewati id yang disalin |  |
| MyISAM AUTO_INCREMENT on the second column of a key | satu penghitung untuk tabel | `myisam_group_autoincrement` |
| ON UPDATE CURRENT_TIMESTAMP | trigger BEFORE UPDATE | `on_update_trigger` |
| generated columns | STORED | `virtual_as_stored` |
| generated columns with functions PostgreSQL lacks | kolom biasa | `generated_not_translated` |
| INVISIBLE columns | kolom biasa | `invisible_column` |
| CHECK constraints | diterjemahkan, langsung di CREATE TABLE |  |
| CHECK constraints with functions PostgreSQL lacks | tidak dibuat | `check_skipped` |
| CHECK ... NOT ENFORCED | tidak dibuat | `check_not_enforced` |
| defaults with functions PostgreSQL lacks | tanpa default | `default_not_translated` |
| keys and indexes on a prefix, c(20) | indeks pada left(c, 20) | `prefix_unique` |
| FULLTEXT indexes | GIN pada to_tsvector('simple', ...) | `fulltext_as_gin` |
| indexes on values over 2,000 bytes | hash | `index_on_wide_values` |
| SPATIAL indexes | tidak dibuat tanpa PostGIS | `spatial_index_skipped` |
| functional indexes PostgreSQL can't write | tidak dibuat | `index_skipped` |
| foreign keys | setelah data, NOT VALID, lalu divalidasi dengan peringatan untuk baris yatim |  |
| foreign keys to columns without a unique key | tidak dibuat | `foreign_key_skipped` |
| table and column names | huruf kecil jika tetap unik | `identifier_renamed` |
| names over 63 bytes | dipersingkat dengan hash | `name_shortened` |
| GEOMETRY, POINT, POLYGON... | WKB di bytea | `geometry_as_wkb` |
| INET4, INET6, UUID (MariaDB) | inet, uuid |  |
| BINARY, VARBINARY, BLOB | bytea |  |
| PARTITION BY | satu tabel | `partitions_dropped` |
| WITH SYSTEM VERSIONING (MariaDB) | tabel dengan baris saat ini | `system_versioning_dropped` |
| MyISAM, MEMORY and other engines | tabel biasa | `engine_dropped` |
| views, triggers, procedures, functions and events | dicantumkan di laporan | `not_converted_objects` |
| dumps without CREATE TABLE | tipe dibaca dari nilai | `no_schema` |
| geometries in a dump without CREATE TABLE | WKB di bytea | `geometry_inferred` |
| _ci collations | perbandingan persis | `case_insensitive_collation` |
| SET NAMES utf8 from utf8mb4 tables | dikonversi, dengan peringatan | `dump_lost_four_byte_chars` |
| dumps without SET NAMES whose text isn't UTF-8 | dibaca sebagai Latin-1 (Windows-1252) | `charset_guessed` |
| sjis, cp932, gbk, big5 dumps | dibaca sebagai UTF-8, dengan peringatan | `unsupported_charset` |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | dievaluasi |  |
| other expressions in rows | NULL | `expression_value` |
| DEFAULT in VALUES | nilai default kolom | `default_keyword_filled` |
| DEFAULT in VALUES without a literal default | NULL | `default_keyword_null` |
| REPLACE and INSERT IGNORE | baris biasa | `replace_as_insert` |
| types IntoSQL doesn't know | text | `unknown_type` |
| values that don't fit their column | NULL | `invalid_value_null` |
| unreadable geometries | NULL | `bad_geometry` |
| CREATE SEQUENCE (MariaDB) | CREATE SEQUENCE dengan nilai saat ini |  |

## 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.

```shell
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

### 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.

## Konversi lain ke PostgreSQL

- [Konversi Excel ke PostgreSQL](https://intosql.com/id/excel-ke-postgresql)
- [Konversi CSV ke PostgreSQL](https://intosql.com/id/csv-ke-postgresql)
- [Konversi JSON ke PostgreSQL](https://intosql.com/id/json-ke-postgresql)
