2015年10月12日月曜日

2大OSSデータベースのMySQLとPostgreSQLの違いについて話してきた

第32回 PostgreSQL 勉強会(2015年10月10日)で登壇してきました。
内容は前に書いたエントリーの


を元に発表してきました。
と言っても今回は参加者がPostgresSQLに詳しい前提だったのでMySQLを中心に話をしました。
実際の資料は下記のとおりです。
当日はビデオ撮影があったのでそのうち動画が上がると思います。

第32回 PostgreSQL 勉強会まとめ ~ togetter ~




流石に2時間は疲れました。
内容としては眠くならないように面白おかしく伝えようと思ったのですがなかなか難しかったです。
前半はMySQLとPostgreSQLの方向性の違いをメインにしました。
後半はMySQLは僕が実際にハマった事などをメインにしました。
個人的にはRDBの選択は適材適所以上の答えは無いと思ってます。
MySQLの並列処理性能やレプリケーションはPostgresSQLには足りないものです。
PostgresSQLの方が素晴らしいではなく住み分けだよと伝えたつもりです。
資料だけだとMySQLのDis話がメインなのですれ違いが無いようにここで補足しておきます。
実際にもっと深く知りたい人はMyNA会やPostgreSQLカンファレンスに来てもらえたらと思います。
ということでPostgreSQL勉強会デビューの話しでした。

####追記####



マサカリ訂正をいくつかいただいたので追記します。
間違った知識広がったらいけませんし。

1. トランザクションレベルのSERIALIZABLEの挙動の誤記
SERIALIZABLEの読み取りロックはNOって書いてますけどYESが正しいです。
PostgreSQLもMySQLもSERIALIZABLEにするとロックを獲得すると他トランザクションのSELECTに対してもロック待ちさせます。
SERIALIZABLEについては触れなかったので当日は誰も気づいてなかったぽいですが間違いです。

2. MySQLのInnoDBはREPEATABLE READはファントムリードしない
PostgreSQLはするのでそういうもんだと思ってました。
デフォルトのREPEATABLE READが堅いということになります。
MySQLすごい!!

3. @yoku0825さんからの指摘事項がいっぱい



















つまり、みんな@yoku0825をフォローしよう。
(いつもアドバイスありがとうございます)

#スライドの中で話題にした本並べときます







2015年10月6日火曜日

問題にチャレンジしてもらうために必要な事を考えてみた

私は人が成長するときは


  • 行動した時(そしてその最中)
  • 結果を振り返った時(失敗、成功を問わず)


の2つだと考えてます。
その2つを得るには問題にチャレンジすることが非常に重要です。
つまりチームやメンバーが成長していくためには如何にチャレンジを繰り返せるかです。
しかし元も子もない話をすると私は「崖から落とされたら勝手に這い上がってくる」タイプです。
ですから成長方法は基本的に崖から落とされて真っ向から突き進んで失敗したり解決したりして強くなってきました。
この手法を個人的にはサイヤ人ブートキャンプと言っていて、死にかけて強くなるので高速に成長します。
ただし、用法用量を守らないと死にます(精神または物理で)
ですので他の人に勧められる方法ではないなと悩んでいます。
そして不幸な事に地球人が崖から落ちてしまう事もあります。
そんな時、助ける術も必要だなぁと最近良く考えているので整理してみます。

まず@razonさんが仰るとおり



がすべてを表しています。
私には階段が思いつきません。
そもそもこのツイートを見て「なるほど、階段って手があるのか!」と目からウロコだったほどです。
実際にはエレベータだろうが階段だろうが「そもそも登らない」だろうが選択肢はN択です。
なのでバカ正直に真っ向から登る必要は無いのですが私は真っ向から登って登れてしまうので発想が貧弱なのです。
「人間は経験したことしか想像できない」ものです。
だからこそ、このアウトプットを元に新たなインプットに期待してます。


と前置きが長くなりましたが本題。

アジェンダは


  1. チャレンジする人のメンタルモデル
  2. チャレンジの手法について
  3. 実際にチャレンジしてもらうには


です。
では早速本題に入ります。

1. チャレンジする人のメンタルモデル

チャレンジャーな人は活発的な人が多いとかそういうのは関係ないです。
ここは単純に

チャレンジした結果、成功した体験がある

って事に集約されると思ってます。
これは幼少期からこれまでの間の成功体験を元に問題解決を計ります。
大切なのは

成功体験の内容でチャレンジの手法が決まる

というところです。
これは2.に繋がるのですが冒頭でも触れた「人間は経験したことしか想像できない」というところにも繋がります。
逆説的ですが成功体験が無い場合、チャレンジをするメリットもわかりませんし、手法もありません。
これは卵が先か鶏が先かの難しい問題も秘めています。

2. チャレンジの手法について

1.でも触れたとおり、成功体験が重要です。
真っ直ぐ登って登れた人はまずは登ろうとします。
周囲に階段を作って成功した人を知っていれば階段を作り始めるかもしれません。
具体的には私は素直な子?でしたから問題については実力行使(物理)で突き進んできました。
ですので現在もよく崖から落ちたら真っ直ぐ崖を登り始めます。
これがチームの場合、大抵多くの人が「私には無理だ」と呆れてついてこれません。
これも過去何度も経験しました。
また素上りした結果、落石などのアクシデントやヒューマンエラーなどで何度も死にかけました。
その結果、最近は

  • 流石に素上り危ないから命綱を持とう
  • 一人では限界があるからサポートメンバーを持とう

などの選択肢を覚えてきました。
これが問題解決のノウハウとよべる部分です。
ですがこのノウハウは基本的には問題に真っ向勝負志向の人です。
階段派などにはこのノウハウを共有してもなかなかマッチしません。
つまりノウハウを共有しても必ずもすべての人に有益とは限りません。
そしてチームは多様性を持つべきですし色んな人がいます。
ですので往々にして多くの人にとって有益なノウハウとなりません。
これでは周囲はなかなかチャレンジできません。
ですのでビスマルクの

愚者は経験に学び、賢者は歴史に学ぶ

が大事だと思います。
つまりは他人の成功体験を知る。
しかしこれは好きな女性が相手ならまだしもどうでもいいおっさんの場合は苦痛です。
しかも自分と考え方の指向性が違えば自分のノウハウとして蓄積しない(共感できない)ため尚更です。
なので情報収集のスタイルも十人十色だと思います。
ここでは私の代表的な情報収集スタイルをご紹介します。

・本を読む

ありきたりですが確実に情報を収集できます。
多くの手法を学ぶには一番手っ取り早いかもしれません。
また新書で出てることが多くちょっとした時間で読むことができます。
ただしデメリットが2つあって一つは基本的に良い話しかありません。
罠や泥臭い話は映えないのでカットされがちです。
それと大分話を盛ってあることも多いので鵜呑みにすると痛い目をみます。
誰もが若かりし青春時代、ニーチェを読み、ユングを読み、痛い厨二病時代があった思います。
また意識高い新卒にありがちなビジネス書や自己啓発本に毒されて応用が利かない時代もあったと思います。
人それぞれですが偏ると何事も毒になるので要注意です。

・飲み会に行く

基本的におっさんは自分の成功体験の昔話を若者にしたがるものです。
なので飲み会にホイホイ付いて行けば自然とその話を聞くこともできるでしょう。
これは自分に近い立場の人ほど自分に近い経験なので情報として有益です。
また成功体験と言ってもそのプロセスの詳細も聞けるので本には無い罠や泥臭い話も聞けます。
ただしこのデメリットは


  • おっさんは酔っ払うと話がループする
  • 同じような話を毎回する
  • 途中から説教になる


があります。
なのである程度一通り聞いてしまうとそれ以上の情報収集は難しいです。
このリスク回避は非常に難しいのですが下記の方法を取ると評価を上げるチャンスになります。



もし会社の飲み会がつまらないなぁと思うなら上司の話を話半分に聞きながらやってみてください。
酔っ払いのおっさんほど効果抜群です。
20~30分前に行ってた事をオウム返しするだけでも十分です。
するとおっさんも「君は見込みがあるなぁ!」など言い出すでしょう。
そうなると次回の飲み代も出してくれるはずです。
今度はいい飲み屋知ってますよ!!とか言ってちょっと普段行かないお高いお店行ったりして有効活用しましょう。
おっと話が脱線しました。
会社の飲み会だけでなくエンジニアの集まる勉強会や地域の会合などにも同様の効果があります。
こちらは会社よりもメンバーの流動性が高いので多くの話を聞くことが出来るでしょう。
こういう場を上手く活用すれば現場の生の声を沢山得ることが出来ると思います。


私の場合はこの2つがメインの軸です。
なので機会があれば皆様の成功体験を聞かせていただければと思います。
また情報収集についても「こんな方法もあるよ」というのがあれば是非教えていただければと思います。


3. 実際にチャレンジしてもらうには

1と2の結論として


  • 本人(またはチームに)成功体験がある
  • その成功体験にマッチした手法がある


この2つが重要だと言う結論になりました。
しかしもう一つ重要な要素があります。

適切な大きさの問題

であることです。
みなさんもチャレンジする側が成熟していないのに大きい問題にぶつかり挫折する。
そんなシーンを見たことがあるのではないでしょうか。
この適切な大きさの問題については@snagaさんに面白い記事を紹介してもらいました。



ここでは成功体験の有無や手法など関係なく

適切な問題が生まれれば自然と解決する人が生まれる

という話題が出てきます。
これは私も経験があります。
つまりこの2つをまとめると


  • チャレンジさせたい人には適切な問題を与える
  • 解決したい問題を適切な問題に細分化し再配布する


これが成長するマネージメントのコツなのでは無いかと思います。
そうなると1の成功体験の有無は関係ないように見えます。
しかしこれは「自ら適切な問題は見出したり細分化する際に必要」なことなのです。
なので多くの成功体験を持った方がセルフマネージメントに長けた人になるのです。
また2の多くの成功手法を知る人が適切なチームマネージメントを行える人になるのです。
もっと視野を広げれば「適切な問題を生み出せる」事が経営者やリーダーとして適正なのではないでしょうか。

ということで以上の事を踏まえた上で私は今、「適切な問題を生み出す」とは何なのか考えています。

2015年9月15日火曜日

SlackにPostgreSQL部屋を作った

こないだ酒気帯びブログでこんな反響があった。



MySQLのSlackに参加してて積極的に意見交換されてて素晴らしいなと思っていたので即行動してみた。


PostgreSQL部屋に入るSlackin



しばらくは僕が管理人をしてますが上手いことみんなに権限をシェアしていけたらいいなと思ってます。
なんかSlack inが動いてないよーとか新しいチャネル欲しいよーとかあれば@soudai1025まで。
ほんとに気軽にご活用ください。
他愛もない話でもいいですしイベントの告知とかもありです。
ちょっと困った事とか日本語ドキュメントよくわからないとかも良いと思います。
それではみなさま、お待ちしております。

コミュニティに参加してよかったなと思うことをまとめてみた 〜 第11回 中国地方DB勉強会 in 広島 〜

今週末の9/19にはOSC広島、9/20には中国地方DB勉強会 in 広島があるのだけどDB勉強会は登壇するので資料を作りました。
その資料を敢えて先に公開します。
当日来る人はこの内容を呼んだ上で思うところをFAQでぶつけてくれると嬉しいです。



まとめてしまうとJPUGの宣伝と昔話とコミュニティに感謝の話です。
僕はエンジニアになって本当にコミュニティに育てて貰ったと思うし30代はその恩送りをしていく時期だと思ってます。
だからこそ地方のエンジニアは積極的にコミュニティに参加して欲しいと願っています。
以前にも真面目な話のエントリも書いたけど中四国地方は大切なターニングポイントの時期に来てると思ってます。
そんな時期に僕もそうだし、みんなにも考えるきっかけになってくれれば幸いです。
その上で「何か新しいことに踏みだそう」と思ってる方がいれば僕が押してもらったように僕も背中を押したいと思います。
そうやって恩は巡って行くものだと思うしコミュニティはそうやって形を変えていくものだと思うので。

ということで皆様にどこかのコミュニティでお会いできるのを楽しみにしています。

2015年9月5日土曜日

Webで役立つPostgreSQLの話をしてきた ~ OSC新潟2015 ~




初めての新潟行って来ました!!
15分しかなかったのでざっくりPostgreSQLの話をしました。



久々にチャレンジでした。
無事に15分で収まった(収まってないけど)のは奇跡でしたねw
また各項目の詳細はそれぞれ別々のイベントで細かく話したので纏めを置いておきます。




■第九回 中国地方DB勉強会 in 米子を開いてきた
(SQLの話をした時の資料がまとまってます)

■MyNA・JPUG合同DB勉強会 in 東京を開催してきた(FDWの話もしてきた)
FDWの話をした時の資料がまとまってます。
またNTTデータの澤田くんがナイスなJSONの話をしてるので是非一読してください!!

日本酒!お米!!新潟!!
OSCは全国で開催されているので気軽に旅行する理由になって最高ですね!!
そういえばちょうど次は広島で行われるそうです。
興味がある人は是非。

■OSC2015 Hiroshimaタイムテーブル
日程:2015年9月19日(土) 10:00-17:00(展示は10:00-16:00)
会場:サテライトキャンパスひろしま [アクセスマップ]
   (広島県民文化センター 5F)広島市中区大手町1丁目5-3
   広電最寄駅→紙屋町西 ・ 最寄バス停→紙屋町

費用:無料

ということで翌日はDB勉強会 in 広島も行われます。
合わせて旅行駆動勉強会参加をご検討してみてください。

2015年8月25日火曜日

MySQL使いの人がPostgreSQLを始めるときの罠をまとめてみた

昨日書いたエントリがなかなかいい感じに拡散された。

MySQL使いが知るべきPostgreSQLとの違いと変わらない一つのこと


で気付いた。
多分本当にMySQL5.7の罠が理由でPostgreSQLに移行する人は上のエントリを求めてない。
つまり本来ターゲットにすべき人は


  • SQLはORMが解決してくれるから違いなんて気にしない
  • ロジックはSQLではなくアプリケーションコード側が行う
  • DBはデータを置くストレージだ、いいね?


みたいな人だ。
前述のエントリでよしPostgreSQL使おう!!って人は多分MySQL使っても乗り越えていける人たちだ。
勿論そんな人達がPostgreSQLに来てくれるのは嬉しいし大歓迎。
それとは別にもっと窓口を拡げるために必要な移行時の罠をまとめておく。
これはMySQLと比較しながらPostgreSQLの事を書く。
だが初めてPostgreSQLを触る人は知っておいた方が良いことのまとめになるはずだ。


1. DBを作成するときの罠


一番最初にPostgreSQLをLinux等にインストールすると
service postgresql-9.4 initdb
をまずはすると思う。
その場合、PostgreSQLのデフォルトのロケールはOS側に設定されているロケールを使用する。
つまり多くの場合は

ja_JP.UTF-8

となる。
これに伴いDBが壊れるということはない。
ただしソート順に影響する。
具体的には

日本語ロケールでは辞書順(カタカナ→ひらがな, 清音→濁音→半濁音) の順にソートされる

のだ。
多くのシステムの場合、これは想定外のソート順になる。
そのためDBを作成する際には

service postgresql-9.4 initdb --locale=C

service postgresql-9.4 initdb --no-locale
を指定することになる。
どちらも同義である。
こちらを行うことにより文字のバイナリ値を基準にしたソートになる。
絵文字でソートしたい場合も安心だ。
詳しくは下記のエントリを参考にして欲しい。

ロケール(国際化と地域化)



2. アクセス制御の罠


MySQLに対するアクセス制限はmy.cnfに
bind-address = 127.0.0.1
と書いたりMySQLのuserテーブルで指定したりする。
それに対し、PostgreSQLはDBをインストールしたフォルダ内のpg_hba.confで制御する。
こちらについては先日紹介したとみたさんのエントリでも紹介されている。

MySQLユーザーがPostgreSQLを触ってみたメモ


その際に気をつけてほしいことがある。
それはMETHODの指定である。

host    all    all    192.168.0.0/24    trust
としてあったとする。

これは192.168.0.1~192.168.0.255のIPアドレスからのアクセスはパスワード認証無しでアクセスできる設定だ。
もしこのDBが外に晒されており、全てのIPを表す0.0.0.0/0を指定した場合は自由にアクセスできる事になる。
PostgreSQLはdefaultでスーパーユーザーとしてpostgresというユーザが作成される。
この状態でpostgresユーザでアクセスすれば...結果は明白である。
笑い事に聞こえるかもしれないがEC2やVPSでDBを作っている場合に一時的にtrustを指定する人を見かける。
そして設定は明示的にに読み込みを行わなければならない。
ここに大きな罠があり


  1. 確認のためpg_hba.confに0.0.0.0/0 trustを指定して起動。
  2. テスト終了後、pg_hba.confを修正
  3. 再起動時や再読み込みを忘れる


とするとpg_hba.confは正しいのに誰でもアクセス出来る状態のままとなる。
せめてmd5を指定するようにしよう。

host    all    all    192.168.1.1/32    md5

詳しいpg_hba.confの説明等は公式documentを読んで欲しい。

19.1. pg_hba.confファイル


なお蛇足だがそもそもpostgresql.confの設定で

listen_addresses = '*'

を指定しないとdefaultではlocalhost以外からアクセス出来ない。
設定箇所が2箇所あるので要注意だ。


3. テーブル作成時の罠

MySQLからPostgreSQLに移行した時、仮にpgadmin3を使って型を指定しようとしたら驚くだろう。
余りにもデータ型の種類が多いからだ。
データ型についてはまず公式documentのリンクを紹介しておく。

第 8章データ型


君たちが欲しいのは


  • 数値型
  • 文字列型
  • 日付/時刻型


だと思う。
それぞれについて簡単に解説しておく。

●数値型

通常は


  • bigint  8byte整数
  • integer  4byte整数
  • smallint 2byte整数
  • numeric  MySQLのDECIMAL相当
    (MySQLではnumericはDECIMALのエイリアス)


で事足りると思う。
ただPostgreSQLにはこの他に論理値データ型として


  • boolean  1byte


がある。
勿論入るのは0 or 1 or NULL(許可した場合)だ。
SQLとしてはtrue or falseでもよい。
他にも柔軟に受け入れるので使う場合は公式documentをチェックされたい。

論理値データ型


そしてサロゲートキーを使いたい場合にMySQLはAUTO INCREMENTを指定すると思う。
AUTO INCREMENTはPostgreSQLには無い。
その代わりシーケンスを作り、該当の整数型のdefaultにnextval(シーケンス名)を指定することで同義になる。
とは言ったもののその手順は煩雑だ。
そのため最初から


  1. 整数型の指定
  2. シーケンスの作成
  3. 該当シーケンスをdefaultに指定


を全て丸めてやってくれる型がある。
それがserial型だ。


  • bigserial   →  bigint
  • serial     →  integer
  • smallserial  →  smallint


なおPostgreSQLのシーケンスは最大値に行った場合にCYCLEの指定の有無で周回するか決まる。
CYCLEを指定しない場合はNO CYCLEとなり周回せずにエラーが発生する。
だがserial型で作った場合はCYCLEが指定されない=最大値になるとエラーが発生する。
また自分で設定すれば連番の取得の昇降やSTEP、MAXやMINも指定できる。
CYCLEを指定して周回するIDも作れる。
またAUTO INCREMENTと違い複数テーブル(またはカラム)からも参照、指定することが出来る。
シーケンスはMySQLには無い概念なので一度調べてみると設計の幅が広がるのでオススメだ。

●文字型

PostgreSQLの文字列型は


  • character varying 可変長
  • varchar      character varyingのエイリアス
  • character     空白を埋める固定長
  • char        characterのエイリアス
  • text        制限なし可変長


となる。
実際は可変長、固定長、制限なしの可変長だ。
多くの運用の場合、固定長を使うメリットがない。
なので可変長のcharacter varying(以下varchar)かtextを使うことになる。
またvarcharとtextの違いは制限の有無のみだ。
そのため参照速度だけで言えば制限のオーバヘッドの少ないtextの方が早い。
また制限する場合は


  • varchar(n)


とnを指定することになるがnは文字長(文字数)だ。
バイトでは無いので注意が必要だ。
(MySQLの場合のVARCHARはバイト数)
(MySQLも文字数だった、yoku0825さんご指摘あざます!!あと誕生日もおめざす!!)



仕様として標準SQLに準拠しているのだがそもそも標準SQLの仕様に癖がある。
一度公式documentを拝読しておくと救われるかもしれない。

8.3. 文字型


またMySQLとの大きな違いとしてPostgreSQLの文字列型は文字の大小を区別する。
('A' != 'a'である)
つまりMySQLのBINARY属性を指定した状態と同じ挙動である。
文字列に関してはMySQLと大きく違う仕様が多いので注意が必要だ。
(これは逆も然りでPostgreSQL使いがMySQLを使う際に多くの人がこの罠にハマる)
蛇足としてPostgreSQLの多くの関数は文字列を受け付ける際はvarcharを指定してもtextにCASTされる。
そういった理由からよく文字列型は全てtextを指定する設計も見かける。
その場合は不正なデータを入れられた時の予防やディスク容量計算が難しくなる。
適正な型指定はデータを守るのでCHECK制約と合わせて使いわけよう。
更にPostgreSQLには列挙型(enum)もある。

8.7.1. 列挙型の宣言


(MySQLにもEnumがあるらしい)



CHECK制約とは違いデータにソート順を持たせることが出来る。
覚えておいて損はないだろう。


●日付/時刻型

日付/時刻型は

  • timestamp  日付と時刻両方を持つ 例:2015-01-01 00:00:00
  • date     日付を持つ(時刻無し) 例:2015-01-01
  • time     時刻を持つ(日付無し) 例:00:00:00
  • interval   時間間隔       例:1 year 2 months 3 days 4 hours 5 minutes 6 seconds

がある。
timestampはMySQLのdatetime相当だ。
timestampとtimeについてはtime zoneを持たせることが出来る。
(これによりMySQLのtimestampを表現することが出来る)
指定した場合はUTCとして内部で持ち、表示の際に設定されたタイムゾーンに合わせて計算してくれる。
国内で使う場合はタイムゾーンを指定しないtimestamp without time zoneで問題ない。
またMySQLのtimestampのdefaultのようにUPDATE文の対象になった際に自動的に対象レコードの指定columnをCURRENT_TIMESTAMPで更新する機能は無い。
同じようにしたい場合はトリガーを書くことになる。
これは非常に便利なのでPostgreSQLにも欲しいところだ。
またintervalについては癖の強い型だ。
そのほかの日付/時刻データ型と合わせて公式documentを見ていただきたい。

8.5. 日付/時刻データ型



●配列型と範囲型

補足としてPostgreSQLは配列型と範囲型がある。
どちらも強力な機能だが乱用は毒にもなる。
公式documentと例を上げているエントリを紹介しておく。



4. ORMの罠

RoRを使う人は問題ないがPHPerはFrameworkのORMが対応してないことがある。
まさにFuelPHPの話だ。
私は標準のクエリビルダをラッパーし自作ORMを作成しているがこれは万人向けではない。
そのため、もしPostgreSQLに対応したORMが必要な場合はDoctrine2をオススメする。
ただし悲しいことに公式documentは英語しかない。
しかしDoctrine2はSymfony2のORMだ。
そのためSymfony2の公式documentを読むことで使い方を知ることが出来る。

Symfony2


FuelPHPでインストールする場合はComposerに対応しているので安心して欲しい。

FuelPHPでdoctrine2を使ってみた


またDoctrine2を利用すればスキーママイグレーションも出来る。
(FuelPHPの標準のスキーママイグレーションはMySQL専用なので動かない)



ここまで来た君は手元のアプリケーションからDBに接続し、自由にテーブル設計できたはずだ。
長くなったので今日はここまでとする。
この後、運用で困った事があればメーリングリストで聞いてみるといい。
きっと誰かが答えてくれるはずだ。

PostgreSQLユーザ会 メーリングリスト


それでは検討を祈る。

2015年8月24日月曜日

MySQL使いが知るべきPostgreSQLとの違いと変わらない一つのこと



私が尊敬してるDBスペシャリストの@yoku0825さんがこんな事言ってた。



@yoku0825さんはMySQLのスペシャリスト中のスペシャリストだ。
その@yoku0825さんがこんな事を言うなんて只事じゃない!!
で話になった元ネタはコレ。

日々の覚書: #yapcasia でMySQL 5.7の罠についてLTしてきました


要はMySQL5.7は「目指している正しい姿」になるために下位互換性を幾つかを捨ててるよって話だ。
その中には360日問題があるけどそれ言うと正しさとは?みたいな話になるので今回は話題にしない。
(デフォルトでパスワードが360日後に無効になるという仕様がデフォルトになったという話)
MySQLを使ってる人は@yoku0825さんのブログを一読したほうがいい。
必ず知らなかった罠が幾つか見つかると思う。
そのツイート見て



とブーメラン投げて見事に刺さってるので今から記事書く。
両サイドにはかなり厳しい話もするが俺の本音を聴いておけ(関白宣言)
まぁ歴史の長いRDBなのでお互いの比較記事は沢山ある。
なのでマルチスレッド(MySQL)とマルチプロセス(PostgreSQL)だとかVACUUMだって話はしない。
むしろ実際に使ってみた際の違いをにフォーカスする。

1. SQLの違い


基本的にMySQLでやっていたことはPostgreSQL出来る。
しかし関数の挙動の違いは幾つかある。
例えば時間から曜日に該当する数字に変換した場合に


  • MySQL → date_format(time,"%w") 0から始まり、日曜日に該当する
  • PostgreSQL → to_char(time,'D') 1から始まり、日曜日に該当する


など挙動に互換性がない場合も多い。
関数を使う場合は一度仕様を確認した方がいい。
幸い、PostgreSQLは有志によって日本語ドキュメントが充実している。
今はGithubで管理されてるので誤字脱字、表現の曖昧さなどはプルリクエストすることが出来る。

PostgreSQL日本語ドキュメント




MySQLを使ってた人はPostgreSQLを使うことでWindow関数など新たに知る機能が多いだろう。
MySQLしか触ったことが無く、OracleやMSDB等を触ったことが無いなら一度SQLの勉強をした方がいい。
必ず業務を効率化してくれるはずだ。
SQL勉強する人向けには最近読んだ本でPostgreSQLベースで書いてあって読みやすかった本をオススメしとく。



じゃあPostgreSQL優秀じゃん!大は小を兼ねるじゃん!!と言いたいところだがMySQLにしか無い文法もある。
MySQLにもPostgreSQLにもMerge文はSQL標準なのに実装されてない。
しかしMySQLには代替案として




がある。
これに準ずる機能はPostgreSQLには無い。
しかしWITH句とRETURNING句(MySQLには無い機能だね)を使えば一応PostgreSQLでも表現出来る。
第九回 中国地方DB勉強会 in 米子でこの話題は取り上げたので興味がある人は資料を見て欲しい。
このリンクの先に梶山さんのMySQL5.7の話が出てるのでそっち見て欲しい、いや見たほうが良い、絶対見るべきだ。
ただ事ある毎にPostgreSQLにMerge文相当が無いことをDis指摘していたら遂に9.5からそれ相当の構文が実装された。
これはMySQLの「INSERT...ON DUPLICATE KEY UPDATE構文」と似た構文で実装されている。

INSERT ... ON CONFLICT {UPDATE | IGNORE}構文


PostgreSQL9.5に興味が出た人はリリース予定の機能が以下にまとまってる。

What's new in PostgreSQL 9.5(英語)


英語なんて読めるか!って人は下記のブログをcheckするといいだろう。

日々の記録 別館


Twitterで行われるラーメン飯テロに耐えれるなら著者のぬこさんをフォローするのもいい。
あとはみかかな人たちが頑張ってるのでSlideShareをWatchすると幸せになれるかもしれない。
オススメのSlideShareのリンクを貼っておく。

10大ニュースで振り返るPGCon2015


おっと話が大分脱線してしまった。
話を戻すがPostgreSQLのSQLは


  • 文字結合が||で出来る
  • 日付操作がday +1で出来る


などどちらかと言えばOracleを意識した記述も多い。
ただ悪名高き(+)は無いしNULL = ""も無いのでそこは安心して欲しい
なのでわかりやすく例えるとしたら

ザ・キング・オブ・ファイターズの95の京と96の京くらい違う


といったところか。
新日本企画が産んだ名作格ゲー、ザ・キング・オブ・ファイターズを知らない若者は

細かいところは違うけど大体一緒でPostgreSQLの方が痒いところに手が届きやすい


くらいのニュアンスで居るといい。
つまりSQLに関してPostgreSQLに乗り換えて不満が出ることは少ないだろう。


2. 機能の違い


これもPostgreSQLの方が多い。
まずマテリアライズド・ビュー(以下マテビュー)がPostgreSQLにはある。
簡潔に言うとviewの結果を実体としてキャッシュするというものだ。
これでtmp_hogeみたいな中間テーブルを作る必要は無くなる。
ただし銀の弾丸ではない。
乱用するとCPUやHDDリソースなどが死ぬ。
そのほかにもCHECK制約があるがこのへんはMySQLで慣れた人には使うシーンが想像出来ないと思う。
データにバグやヒューマンエラーで不正なデータが入って苦しんだ人は覚えておくいい。
次の新規設計時にDBがデータを守ってくれる。
どちらかと言えば


  • JOINのアルゴリズムが複数ある
  • 相関サブクエリが早い


と言う点がMySQLと比較すると直接的にパフォーマンスが上がりメリット感じるところだろう。
ただしUPDATE文に関してはPostgreSQLの方が遅い(場合が多い)
これは追記型アーキテクチャの壁なのでMySQLの方が有利な点だ。
しかしガンガンUPDATEを走らすようなシステムはロックを必要とするはずでロック待ちの方が速度に影響およぼす。
そのため直接的に問題になることは少ないはずだ。

さてここまで話をしたのはPostgreSQLの良いところだ。
勿論MySQLの方が有利な機能もある。
それはレプリケーションだ。
そもそも論としてMySQLとPostgreSQLはアーキテクチャが違うのだがPostgreSQLには自動フェイルオーバーはない。
PostgreSQLの場合はPacemakerなどのサードパーティを利用して実現することになる。
corosyncに苦い思い出がある人は機会があれば一緒に飲もう。
また自動フェイルオーバーはMySQL5.6からの機能だ。
MySQL5.6をまだCHECKしてない人は奥野さんのブログを見るといいだろう。

開発スピードアクセル全開ぶっちぎり!日本よ、これがMySQL 5.6だッ!!


とは行ってもPostgreSQLのレプリケーションに対する投資は素晴らしく今は追いつきつつあると行っても過言ではない。
以上の通り機能面でもSQLと同様の事が言える。
ここも安心してPostgreSQLを推せる内容だ。


3. GUIツールの違い


ここからはPostgreSQLのダメな所になる。
正直言ってPostgreSQLの管理や設定を一つのGUIで全て行うのは諦めた方がいい。
まずSQLエディタ(DBAツール)だがMySQL使いはWorkbenchを使ってると思う。
基本無料なので使ってない人は是非使った方がいい。
それに対してPostgreSQLはpgAdmin3になる。
残念ながら使いやすいとは言い難い。
例えばMacOS版は日本語入力がインラインではない。
この時点でリュウが使ったら殺意の波動に目覚めるレベルだ。
カプコンが産んだ名作、ストリートファイターを知らない若者はウメハラの背水の陣を見ておくといい。
そしてpgAdminは大切な場面で度々落ちる。
エクセル方眼紙を彷彿させると言えば共感してくれる方も多いだろう。
とにかく、PostgreSQLのGUI関連は弱い。
周囲に聞くとみんなコマンドラインの黒い画面でpsqlを直接操作しているらしい。
なので不満がコミュニティからあまり出ていないようだ。
しかし私は補完が利かない環境での開発は耐えれない若者なので代替案として以下のツールを使ってる。




どちらも無料で使え、ER図をリバース・エンジニアリングしたり出来る。
しかもPostgreSQLもMySQLにも繋げれるのでオススメだ。
0xDBEはIDEを開発してるJetBrains製でMacOSでもWindowsでも動くので是非試して欲しい。
A5:SQL Mk-2はmatsubaraさんが個人で開発されてる。
日本語だしExcelにテーブル定義書をリバース・エンジニアリング出来る。
これが無料なのが信じれないレベルのクオリティだ。
なおphpMyAdminに対抗したphpPgAdminも一応ある。
インストールしないことをオススメする。
とモダンなUIとは程遠いPostgreSQLだがPythonでpgAdmin4を作るという話が進んでる。
これがキラーアプリになってくれることを切に願っている。

4. ハードウェアでの違い


長くなってきたので簡潔に言う。
PostgreSQLはMySQLと違ってSSDにしたからといって何十倍の速度も出ない
(せいぜい数倍程度)
さらにFusion-ioは特にMySQLに特化してるのでその差は顕著だ。
PostgreSQLはHDDに特化してシーケンスに書き込もうとするのでそのオーバーヘッドの差が大きい。
もし、金の弾丸でPostgreSQLを殴るときはまずはメモリを増やそう。
PostgreSQLに限らずRDBの多くの問題は金で殴ってメモリを増やすと解決することが多い。
それでもダメな場合は優秀なDBエンジニアを用意しよう。
PostgreSQLはハードウェアを金で殴りにくいのは事実だ。

5. クラウド上での違い


やっとAWS RDSにPostgreSQLが去年追加された。
しかしまだ日本語の全文検索拡張はインストール出来ないしAuroraのPostgreSQL版も無い。
だがHerokuを初め、標準的な使い方であればPostgreSQLをsupportしてるところも出てきた。
国内だとニフティがRDSとしてPostgreSQLをサービスしている。
このへんはOSC 沖縄の時に話をしたので興味がある人はそちらを参考にして欲しい。

OSC沖縄でクラウドの選び方の話で登壇してきたので資料を公開する





随分と話が長くなってしまった。
本当はPostgreSQLには


  • PL/SQLの代わりにPL/PythonやPL/JavaScriptが使える
  • 外部テーブルラッパー(FDW)を使えばPostgreSQLのtableのようにMySQLを参照できる
  • MySQLと違いトリガーを行単位とクエリ単位が選べる(MySQLは行単位のみ)


などの話もしたかったがこのへんの話はまた別の機会にしようと思う。
なお、全然実践的じゃなかったし本当にMySQL派の人がPostgreSQLを使うときのハマリどころは皆無だった。
そこでお詫びにとみたさんの記事を紹介する。



最後になるがMySQLとPostgreSQLはライバル同士だ
しかしながらコミュニティ間はフレンドリーそのものだ。
他にライバル同士がこんなにフレンドリーなOSSコミュニティはあるのだろうか。
実際に合同勉強が開かれたりもする。

MyNA・JPUG合同DB勉強会 in 東京を開催してきた(FDWの話もしてきた)


私はそういうところがRDBのOSS界隈の好きなところである。
これを読んで興味を持った人は是非、DBのコミュニティに参加して欲しい。
MyNAもJPUGも暖かく迎えてくれるだろう。
それはどちらのコミュニティも変わらないことだ。


#### 2015/08/25追記 ####

好評だったので第二弾も作った

MySQL使いの人がPostgreSQLを始めるときの罠をまとめてみた