Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MySQLとPostgreSQLって何が違うの?

 MySQLとPostgreSQLって何が違うの?

Avatar for 赤神青空

赤神青空

August 16, 2026

More Decks by 赤神青空

Other Decks in Programming

Transcript

  1. ▪「MySQLとPostgreSQL」と言うとき、3つの層が混ざりやすい そもそも、何を比べているのか RDBMS Relational DataBase Management System データを管理するソフトウェア MySQL /

    PostgreSQL / Oracle RDB Relational DataBase 表として組み⽴てられたデータそのもの アプリのテーブル群 関係モデル Relational Model ⽐べているのはここ この2層は 製品を替えても変わらない 関係代数‧正規化などの理論 製品によらず共通 比べているのは一番上の層だけ。正規化の話も、扱うデータの形も、この下の2層にある 今ココ はじめに 3/14
  2. ▪設計はそのまま持っていける。変わるのは一番上の層だけ PostgreSQL へ移したら何が変わるか ◯ そのまま持っていける テーブル設計・正規化の結果 主キーと外部キーの決め方 クエリが何を求めているか △ 移すと変わる

    照合順序の既定値 失敗したときに残るスキーマ 接続の重さ・旧バージョンの片付け 左が RDB の層、右が RDBMS の層。正規化は左にあるので、製品では決まりません。 今ココ はじめに 4/14
  3. ▪機能の多寡ではなく、何を優先してきたか 出発点が違う MySQL PostgreSQL まず動くこと‧速いこと まず正しいこと‧標準に従うこと 運⽤ノウハウの蓄積量が武器 モデルを厳密に表現できるのが武器 ‧標準より実⽤を優先して割り切ってきた ‧ストレージエンジンを差し替える設計

    ‧単純な読み書きが⼤量に来る⽤途に強い ‧SQL標準と厳密さを軸に積み上げてきた ‧単⼀エンジン + extension で拡張する設計 ‧複雑なクエリ‧型‧制約を書きたい⽤途に強い この先の違いは、ぜんぶこの思想の差から降りてくる MySQL 8.0 以降で機能差はかなり縮まった。今は「思想と運用の違い」で見るほうが実態に合う 今ココ 本編 6/14
  4. ▪移行したとき、いちばん静かに壊れるところ 差① 照合順序のデフォルト MySQL の既定は utf8mb4_0900_ai_ci 。ai = アクセント無視、ci =

    大文字小文字無視です。 sql SELECT * FROM users WHERE name = 'Sora'; -- MySQL : 'sora' 'SORA' もヒット(大文字小文字を無視) -- PostgreSQL : 'Sora' だけ SELECT * FROM users WHERE name = 'Andre'; -- MySQL : 'André' もヒット(アクセントも無視) -- PostgreSQL : ヒットしない 今ココ 本編 7/14
  5. ▪DDL=CREATE 差②やトランザクショナルDDL ALTER などスキーマを変える文。失敗時に何が残るか 同じマイグレーションを流して、③ で失敗したとする ① ALTER TABLE users

    ADD COLUMN age INT; ② CREATE INDEX idx_users_age ON users(age); ③ ALTER TABLE users ADD CONSTRAINT chk_age CHECK (...); MySQL DDL ごとに暗黙 COMMIT が⾛る ① 残る 確定済み ② 残る 確定済み 中途半端なスキーマが残る ③ 失敗 適⽤されず age列とインデックスだけ存在し、制約だけ無い 戻すための SQL は⾃分で⽤意する ここで失敗 PostgreSQL BEGIN 〜 ROLLBACK で囲める ① 消える 巻き戻る ② 消える 巻き戻る ③ 失敗 適⽤されず 実⾏前と、完全に同じ状態に戻る 「何も起きなかった」ことにできる 戻す⼿順を⽤意しなくてよい MySQL 8.0 の atomic DDL は「1文が壊れない」保証で、これとは別の話 今ココ 本編 8/14
  6. ▪プロセスかスレッドか。Lambda 差③ 接続モデル と組むと表に出てくる MySQL 1接続 = 1スレッド PostgreSQL 1接続

    = 1プロセス 1つのプロセス thread thread thread thread thread メモリを共有するので、1接続あたりが軽い 接続数が増えてもそれなりに耐える … process process process process process process 1接続ごとにメモリを持つので⾼い Lambda と組むならプーラーが実質必須 PostgreSQL は接続が重い。PgBouncer / RDS Proxy が実質必須になる 今ココ 本編 9/14
  7. ▪MVCC=古い行を残して読み書きを待たせない仕組み。置き場所が製品で違う 差④ 旧バージョンの片付けかた MySQL 旧バージョンは undoログ へ退避する テーブル undoログ 旧バージョン

    (別領域) 最新の⾏だけ テーブル本体は膨らみにくい ⻑いトランザクションが続くと undo領域のほうが膨らむ PostgreSQL 旧バージョンは 同じテーブルに残る テーブル 最新の⾏ 死んだ⾏ 死んだ⾏ VACUUM 回収が追いつかないとテーブルが肥⼤化 autovacuum の挙動を知らないまま 本番に出すと、あとで刺さる VACUUM は PostgreSQL 特有の運用項目。機能一覧を眺めていても出てこない 今ココ 本編 10/14
  8. ▪個別の仕様ではなく、優先したものの帰結として見る 4つの差は、全部つながっている ①照合 ②DDL ③接続 ④MVCC 実用を優先した既定値 トランザクション境界の扱い プロセス ⇔

    スレッド 旧バージョンをどこに置くか 今ココ おわりに 移行でクエリの結果が変わる 失敗時に残るものが変わる サーバーレスとの相性が変わる 運用でやることが変わる 11/14
  9. ▪分散SQLおまけ|分散SQLでは、外部キーが消える に共通する制約。Aurora DSQL だけの話ではない これまでの RDBMS(単⼀ノード) 1つのノード 親テーブル FK ⼦テーブル

    アプリは、何もしなくてよい エンジンが参照整合性を強制する 分散SQL(複数ノード) ノードA 親テーブル FK を張れない ノードB … ノードC ⼦テーブル アプリが存在確認と競合防⽌を担う 強制の担い⼿が、アプリに移る 参照関係そのもの(RDBの層)は消えない。担い⼿が RDBMS からアプリへ移るだけ PostgreSQL互換を名乗っていても強制されない。製品固有の癖ではなく、分散にした帰結 今ココ おまけ 14/14