PostgreSQL vs MySQL

PostgreSQLとMySQLの
SQL方言の違いを比較

Web開発でよく使われる2つのRDBMS。似ているようで少し違うSQLの書き方を、実際にブラウザで書き比べてみましょう。

CONCAT()と||、AUTO_INCREMENTとSERIALなど、目的は同じでもPostgreSQLとMySQLでは代表的な書き方が異なります。

PostgreSQLミリア MySQLミリア

SQL Dialects

代表的な書き方を比べてみる

まずは、実務でも違いに気づきやすい代表的な構文だけを並べてみます。

やりたいこと PostgreSQL MySQL
文字列結合a || bCONCAT(a, b)
IDの自動採番SERIAL / IDENTITYAUTO_INCREMENT
NULLの置換COALESCE()IFNULL()
大文字小文字を無視した検索ILIKE照合順序などに依存
件数制限LIMITLIMIT
CONCAT vs ||

文字列結合と「NULL」の落とし穴

標準SQLに準拠するPostgreSQLやOracle Databaseでは、||(パイプ2つ)演算子で文字列を結合します。

PostgreSQL
SELECT first_name || ' ' || last_name
FROM users;

一方、MySQLでは CONCAT() 関数を使って結合するのが最も一般的です。

MySQL
SELECT CONCAT(first_name, ' ', last_name)
FROM users;
実務でハマりやすい2つの違い

① MySQLで「||」を使うとどうなる?
MySQLのデフォルト設定では、|| は文字列結合ではなく「論理OR(どちらかが真なら1)」として計算されます。そのため、文字列同士を || で繋ぐと結果が 0 になってしまう事故が多発します。(※MySQL側の設定で PIPES_AS_CONCAT モードを有効にすれば || でも結合可能です)。

② PostgreSQLでCONCAT()を使うときの「NULL」の扱い
実は最近のPostgreSQLでも CONCAT() 関数は使えます。しかし、最大の注意点は「NULLが含まれていた時の挙動」です。|| を使って 'A' || NULL と書くと結果は全体が NULL に消滅してしまいます。しかし、CONCAT('A', NULL) の場合はNULLが無視されて 'A' が返ります。DB移行時にバグを生みやすい非常に重要な違いです。

AUTO INCREMENT

自動採番も、書き方が違う

PostgreSQLの既存コードでは、自動採番列としてSERIALを目にすることがあります。

PostgreSQL
CREATE TABLE items (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100)
);

MySQLではAUTO_INCREMENTが代表的です。

MySQL
CREATE TABLE items (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100)
);
Architecture & Types

データ型と文字の囲み方の決定的な違い

構文(方言)以上に、実務でのDB移行や、複数RDBMSを併用するエンジニアを苦しめるのが「データ型」と「文字の囲み方(クォーテーション)」のルールの違いです。

比較ポイント PostgreSQL MySQL
真偽値 (Boolean) ネイティブな BOOLEAN 型が存在(TRUE / FALSE) 実は内部的に TINYINT(1) として扱われる(1 / 0)
テーブル名の囲み文字 ダブルクォーテーション "users" バッククォート `users`(ANSIモード以外)
大文字・小文字の検索 厳密に区別する。無視したい場合は ILIKE を使う デフォルトの照合順序設定では区別しない(Aとaは同じ扱い)

例えば、MySQLでは文字列をダブルクォーテーション(")で囲んでも許容されることが多いですが、PostgreSQLを含む標準SQLの世界では「文字列はシングルクォート(')、カラム名やテーブル名などの識別子はダブルクォート(")」と厳格に定められています。

また、大文字・小文字の検索ルールが根本から違うため、MySQLで動いていた「メールアドレスの重複チェック」システムをPostgreSQLに移行した途端、大文字小文字の違いで重複登録がすり抜けてしまうといったインシデントに繋がることもあります。

Migration Trouble

実務での「DB移行」で起きるエラー

システム開発の途中で「PostgreSQLからMySQLへ移行する(またはその逆)」というケースは実務でも発生します。その際、単純にデータを移すだけではアプリケーションが動きません。

  • 文字列の囲み方: MySQLはダブルクォーテーション " を文字列として許容しますが、PostgreSQLでは識別子(カラム名など)とみなされてエラーになります(標準SQLではシングルクォーテーション ' が正解です)。
  • 大文字・小文字の検索: PostgreSQLには大文字小文字を無視する ILIKE がありますが、MySQLには存在しません(MySQLは照合順序の設定に依存します)。

このように、RDBMSごとの「方言」を知らないまま開発を進めると、後から膨大なSQLの書き換え作業が発生してしまいます。

Compare in Browser

読むより、書き比べるのが一番早い。

表を眺めるだけでも違いはわかりますが、実際にSQLを書くとさらに明確になります。

Miria SQL Learningでは、PostgreSQLモードとMySQLモードを切り替えながら、同じ目的のSQLをそれぞれの書き方で試せます。

Try Comparison

2つのDBを
書き比べよう。

アプリ内でモードを切り替えると、同じ構文でもエラーに
なったり、結果が変わるのを体験できます。

ミリア

Related Guides

他のガイドを確認する

Miria SQL Learning

PostgreSQLとMySQL、
両方書いて比べてみよう。

環境構築なし。
ブラウザ上でRDBMSを切り替えて試せます。

PostgreSQL / MySQL をブラウザから体験