---
title: "MySQL を PostgreSQL に変換"
description: "MySQL や MariaDB のダンプを、一度で読み込める PostgreSQL スクリプトに変換し、すべての変更をレポートします。ブラウザ上で動作し、ダンプはアップロードされません。"
canonical: https://intosql.com/ja/mysql-to-postgresql
last_updated: 2026-10-15
---

# MySQL を PostgreSQL に変換

mysqldump、mariadb-dump、mysqlpump、phpMyAdmin、Adminer で作成したダンプ (.sql または .sql.gz) をドロップすると、同じテーブル、キー、インデックス、データを持つ PostgreSQL スクリプトをダウンロードできます。PostgreSQL がそのまま保持できない値と、引き継がないオブジェクトは、すべてレポートに記載されます。

## MySQL から PostgreSQL で変わること

各行はコンバーターが適用するルールです。ルールによってデータが変わったときにレポートに書かれる行も示します。

| MySQL では | PostgreSQL では | レポートの行 |
| --- | --- | --- |
| TINYINT(1), BOOL | すべての値が 0 か 1 なら boolean、それ以外は smallint | `bool_kept_numeric` |
| UNSIGNED integers | 負でないことを確かめる CHECK 付きの 1 段大きい整数型。BIGINT UNSIGNED は、すべての値が収まれば bigint、それ以外は numeric(20,0) | `unsigned_widened` |
| ZEROFILL and display widths | 削除 | `zerofill_dropped` |
| FLOAT(M,D) | real または double precision、桁数指定なし | `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 を削除 | `not_null_relaxed` |
| DEFAULT '0000-00-00' | デフォルト値なし | `zero_date_default` |
| TIME | すべての値が 1 日以内なら time、それ以外は interval | `time_as_interval` |
| YEAR | 範囲の CHECK 付きの smallint |  |
| CHAR(n) | varchar(n) |  |
| DATETIME | timestamp |  |
| TIMESTAMP | ダンプが示すタイムゾーンでの timestamptz。示されていなければ UTC | `timestamp_zone_assumed` |
| ENUM | 値の CHECK 付きの text |  |
| ENUM holding '' (MySQL's error value) | チェック制約が許可する空の値 | `enum_invalid_value` |
| ENUM or SET holding values outside its list | CHECK なし | `enum_check_skipped` |
| SET | すべての要素がリストにあることを確かめる CHECK 付きの text[] |  |
| JSON | jsonb。値に \u0000 があれば json | `json_not_jsonb` |
| NUL bytes in text | 削除 | `nul_removed` |
| text that isn't valid in its character set | 不正なバイトを置換文字に | `invalid_utf8_replaced` |
| text decoded twice (Ã±) | そのままコピー | `mojibake_suspected` |
| AUTO_INCREMENT | GENERATED BY DEFAULT AS IDENTITY、カウンターはコピーした ID の後から |  |
| MyISAM AUTO_INCREMENT on the second column of a key | テーブルに 1 つのカウンター | `myisam_group_autoincrement` |
| ON UPDATE CURRENT_TIMESTAMP | BEFORE UPDATE トリガー | `on_update_trigger` |
| generated columns | STORED | `virtual_as_stored` |
| generated columns with functions PostgreSQL lacks | 普通の列 | `generated_not_translated` |
| INVISIBLE columns | 通常の列 | `invisible_column` |
| CHECK constraints | 変換して CREATE TABLE 内に記述 |  |
| CHECK constraints with functions PostgreSQL lacks | 作成しない | `check_skipped` |
| CHECK ... NOT ENFORCED | 作成しない | `check_not_enforced` |
| defaults with functions PostgreSQL lacks | デフォルト値なし | `default_not_translated` |
| keys and indexes on a prefix, c(20) | left(c, 20) のインデックス | `prefix_unique` |
| FULLTEXT indexes | to_tsvector('simple', ...) の GIN | `fulltext_as_gin` |
| indexes on values over 2,000 bytes | hash | `index_on_wide_values` |
| SPATIAL indexes | PostGIS がなければ作成しない | `spatial_index_skipped` |
| functional indexes PostgreSQL can't write | 作成しない | `index_skipped` |
| foreign keys | データの後に NOT VALID で作成してから検証し、孤立した行があれば警告 |  |
| foreign keys to columns without a unique key | 作成しない | `foreign_key_skipped` |
| table and column names | 一意のままなら小文字 | `identifier_renamed` |
| names over 63 bytes | ハッシュを付けて短縮 | `name_shortened` |
| GEOMETRY, POINT, POLYGON... | bytea に WKB | `geometry_as_wkb` |
| INET4, INET6, UUID (MariaDB) | inet, uuid |  |
| BINARY, VARBINARY, BLOB | bytea |  |
| PARTITION BY | 1 つのテーブル | `partitions_dropped` |
| WITH SYSTEM VERSIONING (MariaDB) | 現在の行を持つテーブル | `system_versioning_dropped` |
| MyISAM, MEMORY and other engines | 通常のテーブル | `engine_dropped` |
| views, triggers, procedures, functions and events | レポートに記載 | `not_converted_objects` |
| dumps without CREATE TABLE | 値から読み取った型 | `no_schema` |
| geometries in a dump without CREATE TABLE | bytea に WKB | `geometry_inferred` |
| _ci collations | 厳密な比較 | `case_insensitive_collation` |
| SET NAMES utf8 from utf8mb4 tables | 変換し、警告を表示 | `dump_lost_four_byte_chars` |
| dumps without SET NAMES whose text isn't UTF-8 | Latin-1 (Windows-1252) として読み込み | `charset_guessed` |
| sjis, cp932, gbk, big5 dumps | UTF-8 として読み込み、警告を表示 | `unsupported_charset` |
| UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows | 評価 |  |
| other expressions in rows | NULL | `expression_value` |
| DEFAULT in VALUES | 列のデフォルト値 | `default_keyword_filled` |
| DEFAULT in VALUES without a literal default | NULL | `default_keyword_null` |
| REPLACE and INSERT IGNORE | 通常の行 | `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 |  |

## スクリプトを PostgreSQL に読み込む

スクリプトはテーブルを作成して行をコピーしてから、キー、インデックス、外部キーを追加します。そのため読み込みが速く、最初のエラーで止まります。

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

外部キーは NOT VALID で追加してから検証します。存在しない行を参照している行があれば、途中で失敗する代わりに、どの制約かをスクリプトが示します。

大きなダンプでは、先にデータベースを作成し、サーバーと同じマシンから psql でスクリプトを実行してください。

## MySQL を最適な方法でダンプする

コンバーターはダンプの内容を読み取ります。次のオプションを使うと、より多くのデータがダンプに残ります。

- --default-character-set=utf8mb4 を使うと、絵文字などの 4 バイト文字が残ります。utf8 のダンプでは、コンバーターが読む前にこれらの文字が失われます。
- --hex-blob はバイナリ列を 16 進数で書き出すため、システム間でコピーしても壊れません。
- --routines --triggers --events を使うとこれらのオブジェクトがダンプに含まれ、レポートに一覧できます。

## 変換されないもの

ビュー、トリガー、ストアドプロシージャ、関数、イベントは、データベースごとに独自の言語で書かれます。黙って削除されることはなく、レポートに名前で一覧されるので、PostgreSQL 用に書き直せます。

## pgloader との比較

同じダンプを IntoSQL と pgloader 3.6.7 で変換して読み込み、1 台のマシン (SATA SSD 搭載の 10 コア i9-10900K) で 2026 年 10 月に測定しました。

- 2、-1、-5 を持つ TINYINT(1) 列: pgloader は警告なしに、すべてを true として読み込みます。IntoSQL は数値を保ち、レポートにその理由が書かれます。
- 'it's' というデフォルト値、バッククォートを含む名前のテーブル、空の値を持つ ENUM、24 時間を超える TIME を含むダンプ: pgloader は止まります。IntoSQL は変換して読み込みます。
- pgloader で読み込んだ結果では、主キー、一意キー、外部キー、IDENTITY が失われています。IntoSQL はすべて保持します。
- 3000 万行、5.3 GB のダンプ: pgloader は先に稼働中の MySQL への復元が必要で、それに 18 分かかり、その後デフォルト設定ではメモリ不足になります。IntoSQL はダンプを 10 秒で変換し、psql はスクリプトを約 3 分で読み込みます。
- MySQL 5.5 から 9、MariaDB 10.3 から 12 の 476 個のダンプを PostgreSQL 13 と 18 に読み込みました。読み込みエラーはなく、レポートに記載されずに変わった値もありません。

## MySQL から PostgreSQL への変換に関する質問

### ダンプはアップロードされますか？

いいえ。コンバーターはブラウザ上で動作し、ダンプをディスクから少しずつ読み込むため、ダンプがコンピューターの外に出ることはありません。デスクトップアプリとコマンドラインも、お使いのコンピューター上で変換します。

### ダンプはどのくらいの大きさまで扱えますか？

コンバーターはダンプ全体をメモリに保持しません。ファイルを範囲ごとに 2 回読み、読みながらスクリプトを書き出します。数 GB のダンプも、ブラウザ、デスクトップアプリ、コマンドラインで変換できます。

### MariaDB のダンプも読み込めますか？

はい。mariadb-dump や MariaDB 10.3 から 12 のダンプも同じ方法で変換されます。MariaDB の INET6、INET4、UUID 列も対象です。

### 0000-00-00 の日付はどうなりますか？

PostgreSQL にはゼロ日付がないため、NULL になり、列は NULL を許可します。各列にいくつあったかはレポートに記載されます。

### AUTO_INCREMENT の値は保持されますか？

はい。各 AUTO_INCREMENT 列は IDENTITY 列になり、すべての行が ID を保ちます。次の ID は最大の ID の後から、テーブルの AUTO_INCREMENT の方が大きければその後から続きます。

### TINYINT(1) は boolean になりますか？

列のすべての値が 0 か 1 の場合だけです。2 や -1 など他の数がある場合は数値のままで、レポートにその理由が書かれるため、誤って true になる値はありません。

### ストアドプロシージャやトリガーはどうなりますか？

データベースごとに独自の言語で書かれるため、変換はせず、レポートに名前で一覧します。例外は ON UPDATE CURRENT_TIMESTAMP で、PostgreSQL のトリガーになります。

### スクリプトはどの PostgreSQL バージョンで読み込めますか？

PostgreSQL 13 から 18 です。どのバージョンでも同じスクリプトを読み込め、問題があれば最初のエラーで止まります。

## PostgreSQL へのその他の変換

- [Excel を PostgreSQL に変換](https://intosql.com/ja/excel-to-postgresql)
- [CSV を PostgreSQL に変換](https://intosql.com/ja/csv-to-postgresql)
- [JSON を PostgreSQL に変換](https://intosql.com/ja/json-to-postgresql)
