アプリケーション開発ポータルサイト
ServerNote.NET
Amazon.co.jpでPC関連商品タイムセール開催中!
カテゴリー【MySQLPostgreSQL
PostgreSQLデータベースをMySQLへコンバートする
POSTED BY
2023-05-01
、テーブル定義文は何個あっても大した量じゃないはずなので手動で書き直す。主な違いは以下。


MySQLデフォルトはデータ値の大文字小文字の区別をしない
これを忘れてユニークカラムを作ると運用時エラーになってしまう。
実際、ドコモケータイユーザのUIDを保存する際、昔のUIDは短いので、大文字小文字を区別しなかったら結構な頻度でカブる。UIDには当然ユニーク制約をかけるのでエラー。

大文字小文字を区別させたいカラムには BINARY 句を付与する。

id VARCHAR(32) BINARY PRIMARY KEY,
name VARCHAR(64) BINARY UNIQUE KEY,
data TEXT BINARY, -- UNIQUE系のキーは付与できない。

CREATE TABLE定義最後にパラメータ付与
何も指定しなければデフォルト設定が入るので問題ないが、一応

CREATE TABLE (...) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

などとしておく。

TEXT型にUNIQUEキーは指定できない。VARCHAR型に書き直すこと。

普通のインデックスは張ることはできるが、PostgreSQLのようにそのまま張ろうとすると(data TEXT,があったとして)

CREATE INDEX i_data on datarec (data);
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

エラーになる。これはデフォルトだとそのカラムの取りうるMAX長まで張ろうとするためで(TEXT型は数万バイトまで入る)、
エラー文にあるように、インデックス長は3072バイトまでと怒られエラー。なのでMySQLはインデックス長を指定できるようになっている。

CREATE INDEX i_data on datarec (data(512));
Query OK, 0 rows affected (14.75 sec)
Records: 0  Duplicates: 0  Warnings: 0

などと、先頭512バイトまでのインデックス、とすればTEXT型はVARCHAR(1024)など長いカラムにもインデックスが張れる。が、MySQLはこのようなノーマルINDEX+LIKE検索は遅くて使い物にならない。レコードが30万件ほどあったとして、上記にこんな検索かけると、

SELECT data FROM datarec WHERE data LIKE '%ローソン%';

平気で数分結果が返ってこない
よってMySQLではフルテキストインデックスをBOOLEAN MODEで使う。詳しくはこちら

TEXT型はMEDIUMTEXTとLONGTEXT型がある。INSERTでtoo longエラーが出た場合どちらかに書き直す。

フィールド名に「key」は指定できない。別の名前に変更する。

key TEXT NOT NULL #エラー
ekey TEXT NOT NULL #OK

TIMESTAMP,DATEの扱いに大きな差あり。

TIMESTAMP NOT NULL DEFAULT 'now()'

はエラー。

TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP

と書き直す。更新時に自動で更新させたいなら

TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

また、NULLを許容するなら明示的にそれを書かなくてはいけない。

TIMESTAMP NULL DEFAULT NULL

SEQUENCE型は無い。

number PRIMARY KEY DEFAULT NEXTVAL('my_sequence')

はエラー。

number SERIAL PRIMARY KEY

と、シリアル型を直接指定する。

OFFSET N LIMIT N はエラー。LIMIT N OFFSET N の順番でなければいけない。

、PostgreSQLの実データをINSERT形式でダンプする。

pg_dump --data-only --no-owner --no-privileges --disable-dollar-quoting --column-inserts pgtestdb > pgtestdb.dmp

、文字コードが違うなら変換する(同じな場合不要)
例)UTF-8へ変換

apt install nkf
nkf -wx pgtestdb.dmp > pgtestdb_utf.dmp

、INSERT文のみをMySQL用に変換抜き出し(ここがキモ)
・ダンプファイル先頭数行にPostgreSQL専用文あり、INSERT文のみgrep
・public.という接頭辞はいらない、削除する。
・VALUESの前のフィールド名列挙を削除(フィールド名変更した場合必須)。

grep "INSERT INTO public." pgtestdb_utf.dmp | sed 's/ public.\(.*\) (.*) VALUES / \1 VALUES /g' > mytestdb_utf.dmp

、これでテーブル定義、変換後データの出来上がり。

create database mytestdb;
mysql -D mytestdb < mytestdb_tables.sql #1、で作ったテーブル定義文
mysql -D mytestdb < mytestdb_utf.dmp # データ入れ込み
※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】