メッセージ。 - diary
2011-03-22
# DBMSを使ったソフトウェア実装の定石について
先日、列車予約システムみたいなのを作るにあたって、プログラムの中でSQLをどう呼び出せばよいのか、実装の定石みたいなのがあるはず、と書いたことがあったのだけど(下記の記事)。
http://pikapika.to/~yf/momoka.cgi?op=readmsg&id=3007
http://pikapika.to/~yf/momoka.cgi?op=readmsg&id=3008
これに対して、以前お仕事でお世話になった@takekazuomiさんから詳細なコメントをいただきました。ありがとうございます!せっかくなので、情報共有のためこちらに転載させていただきました。
-- ここから
更新されていたのでコメントしようと
書いたのですが、終わった後でコメントが出来ないことに気が付き…
メールします。
もう解決しているでしょうが、思いついたことをコメントします。
「insertでの一意性保証方式だと、一意性が必要な要素ごとにテーブルを作らなければならなくて」
とありますが、現在のほとんどのRDBMSでは複合INDEXに(複数のカラムを結合して)UNIQ制約
を付けることができます。
つまり、列車番号(?)というカラムに、ひかり105号を入れて、予約番号とかのカラムに連番を
入れ、列車番号+予約番号でUNIQとするINDEXを作ると、「ひかり105号10番目」という行が1つ
しか作れないようになります。
これを使うと、「ひかり105号10番目」が取ってあっても、「ひかり106号の10番目は別途取れる」
という感じにできます。
「列車の何番目の購買」なのかを調べるのは、「count(*) from table where id <= got_id」で調べるの
が一番簡単な実装ですが、場合によってはパフォーマンスの問題が出るかもしれません。
その場合は、何番目の購買かをカウントするカラムを別途用意して、そこでカウントするという方法
が取られます。この方法は、予約と取消の両方でコードでカウンターをメンテンスしなければいけな
いのと、カウンターの行と、予約の行が別になるので、更新処理にトランザクションが必要になる
という問題があります。
このような問題があるのですが、今回のような要件では列車毎の予約情報テーブルと、座席の予約情報
のテーブルを1:Nの関係にして(header, detail という言い方をする)、予約情報に予約数(カウンター)
を保持し、追加、削除、更新はトランザクションで行うパターンがよく用いられると思います。
(どうして、header, detail パターンが使われるのが一般的かという説明が必要な気がしますが、
だいぶ長くなったので省略します。一言だけいうと、このパターンはRDBMSと相性が良いです)
説明がいまいちな気がしてぐぐってみたら、下記のURLが出てきましたが、これも今ひとつな気も
しますが、参考にはなります。(既読かもしれないけど、)
http://www.ogis-ri.co.jp/otc/hiroba/technical/JPLoP/DesignPatterns/HeaderDetail/HeaderDetail.html
今回のケースもそうでなんですが、RDBMSを使っていて、どうもピンと来ない場合があります。
個人的な意見ですが、SQLのクエリー部分は基本的に集合操作を前提として設計されているのに、
実業務に利用する場合の特に更新処置の部分が、集合操作的では無いのがギャップの原因の気が
してます。
このあたりは自分でも、もっと考えて見ないと分からない領域なんですが。
-- ここまで
@takekazuomiさん、本当にありがとうございます。やっぱり、プロの人の意見は信頼感があるなぁ。勉強になります。そういえば少し前、chatonのGauche部屋でも、「RDBMSの機能を使って大小関係の保証されたシリアルIDを振ること自体がRDBMSの思想に反している」というような意見がありました。この件と似ている気がします。考えると面白いところですね。
ただやっぱり、このへんの定石みたいなのは、ちゃんと本かなにか、分かりやすい説明にまとまってて欲しい気がするなぁ。
http://pikapika.to/~yf/momoka.cgi?op=readmsg&id=3007
http://pikapika.to/~yf/momoka.cgi?op=readmsg&id=3008
これに対して、以前お仕事でお世話になった@takekazuomiさんから詳細なコメントをいただきました。ありがとうございます!せっかくなので、情報共有のためこちらに転載させていただきました。
-- ここから
更新されていたのでコメントしようと
書いたのですが、終わった後でコメントが出来ないことに気が付き…
メールします。
もう解決しているでしょうが、思いついたことをコメントします。
「insertでの一意性保証方式だと、一意性が必要な要素ごとにテーブルを作らなければならなくて」
とありますが、現在のほとんどのRDBMSでは複合INDEXに(複数のカラムを結合して)UNIQ制約
を付けることができます。
つまり、列車番号(?)というカラムに、ひかり105号を入れて、予約番号とかのカラムに連番を
入れ、列車番号+予約番号でUNIQとするINDEXを作ると、「ひかり105号10番目」という行が1つ
しか作れないようになります。
これを使うと、「ひかり105号10番目」が取ってあっても、「ひかり106号の10番目は別途取れる」
という感じにできます。
「列車の何番目の購買」なのかを調べるのは、「count(*) from table where id <= got_id」で調べるの
が一番簡単な実装ですが、場合によってはパフォーマンスの問題が出るかもしれません。
その場合は、何番目の購買かをカウントするカラムを別途用意して、そこでカウントするという方法
が取られます。この方法は、予約と取消の両方でコードでカウンターをメンテンスしなければいけな
いのと、カウンターの行と、予約の行が別になるので、更新処理にトランザクションが必要になる
という問題があります。
このような問題があるのですが、今回のような要件では列車毎の予約情報テーブルと、座席の予約情報
のテーブルを1:Nの関係にして(header, detail という言い方をする)、予約情報に予約数(カウンター)
を保持し、追加、削除、更新はトランザクションで行うパターンがよく用いられると思います。
(どうして、header, detail パターンが使われるのが一般的かという説明が必要な気がしますが、
だいぶ長くなったので省略します。一言だけいうと、このパターンはRDBMSと相性が良いです)
説明がいまいちな気がしてぐぐってみたら、下記のURLが出てきましたが、これも今ひとつな気も
しますが、参考にはなります。(既読かもしれないけど、)
http://www.ogis-ri.co.jp/otc/hiroba/technical/JPLoP/DesignPatterns/HeaderDetail/HeaderDetail.html
今回のケースもそうでなんですが、RDBMSを使っていて、どうもピンと来ない場合があります。
個人的な意見ですが、SQLのクエリー部分は基本的に集合操作を前提として設計されているのに、
実業務に利用する場合の特に更新処置の部分が、集合操作的では無いのがギャップの原因の気が
してます。
このあたりは自分でも、もっと考えて見ないと分からない領域なんですが。
-- ここまで
@takekazuomiさん、本当にありがとうございます。やっぱり、プロの人の意見は信頼感があるなぁ。勉強になります。そういえば少し前、chatonのGauche部屋でも、「RDBMSの機能を使って大小関係の保証されたシリアルIDを振ること自体がRDBMSの思想に反している」というような意見がありました。この件と似ている気がします。考えると面白いところですね。
ただやっぱり、このへんの定石みたいなのは、ちゃんと本かなにか、分かりやすい説明にまとまってて欲しい気がするなぁ。
# にゃー
ちょっと近況というか。今年のはじめにWeb系のベンチャー企業に拾ってもらって、いまはPHPでの開発の仕事に携わっている(この日記を見て紹介してくださったAさん、本当にありがとうございます)。それで、まぁいろいろありつつも結構快適に仕事させてもらっていて、この快適さはどこからきているのかと考えている。で、いまふと思ったこと。いまいるベンチャーはずいぶん荒削りで、それによってもたらされる不具合の可能性やリスクが散見されるのだけど。でもこの荒削りにはいいところもあって、それはやはり、会社の人の顔が見えるというか、問題は話し合いで解決すればいい、話し合いの余地がある、と感じられるところではないかという気がする。
逆に前に大きな会社にいたときは、規則やルールが、処与のものとしてそこにあった感じがする。規則やルール、あるいは自分の所属する会社というものが、「個人の力では変えられないもの」、あるいは、変えたい、変えるべきだと思ったとしても、どこにどう掛け合い、アクションすればいいのか、分からない感じがした。また、年配の人や長くいるの意見が強く、新参者は意見を言いにくい雰囲気があったり。まぁ、いまいる環境も手放しでこの点がよいと言えるわけではないけど。
逆に前に大きな会社にいたときは、規則やルールが、処与のものとしてそこにあった感じがする。規則やルール、あるいは自分の所属する会社というものが、「個人の力では変えられないもの」、あるいは、変えたい、変えるべきだと思ったとしても、どこにどう掛け合い、アクションすればいいのか、分からない感じがした。また、年配の人や長くいるの意見が強く、新参者は意見を言いにくい雰囲気があったり。まぁ、いまいる環境も手放しでこの点がよいと言えるわけではないけど。
2011-03-18
# にゃー
メールについての考え方。基本的に、携帯のメールアドレスは公開したくない。なぜかというと、メールのバックアップやメンテナンスが自動化しにくいから。ほとんど同じ理由で、ポケット1つの法則でいきたいというのもある。ところが一方で、Pushで届くのと、いつでもすぐ返事できるという携帯メールの特長も捨てがたい。「鉄は熱いうちに打て」じゃないけど、来たメールに早く返信することには大きな利点もある。
ということで、携帯メールのアドレスは公開せずに、一方で携帯メールの即時性は使えるようにしたい。このような問題に対する1つの(有料の)答が、要するに「スマートフォン」であることは間違いない。しかし、そのためにドコモが要求するパケホーダイ6000円は、貧乏な自分に払える額ではない。なのでまぁ、なにか作ろうと思っているところ。
で、コーディングはまぁまぁ進んでいるのだけど、テストしにくくて、止まっちゃってるんだよなぁ。
ということで、携帯メールのアドレスは公開せずに、一方で携帯メールの即時性は使えるようにしたい。このような問題に対する1つの(有料の)答が、要するに「スマートフォン」であることは間違いない。しかし、そのためにドコモが要求するパケホーダイ6000円は、貧乏な自分に払える額ではない。なのでまぁ、なにか作ろうと思っているところ。
で、コーディングはまぁまぁ進んでいるのだけど、テストしにくくて、止まっちゃってるんだよなぁ。