ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

PostgreSQLコミュの配列型の効率性について

  • mixiチェック
  • このエントリーをはてなブックマークに追加
PostgreSQL は "O"RDB としても価値ある存在だと思うのですが、配列を挿入すること自体、第1正規形を崩しているわけですよね。DB の概念に疎いせいか、配列を扱えるという自由度自体を単純に喜ばしく思っているのですが、実際はあまり多用すべきではないのでしょうか?

例えば、A,B,Cという3つのレコードがあり、それぞれに以下のような親子関係を定義したいとします。
 A
 ├B
 │└C
 └C
 ※ Cは同一

【1】この場合、配列型を用いれば、以下のように単一のテーブルでスマートに記述できますよね。
< node テーブル>
 [ id ]  [ parent ]  [ child ]  [その他]・・・
  A    {}      {B,C}
  B    {A}     {C}
  C    {A,B}   {}
しかも、「SELECT * FORM node WHERE 'A' = ANY( parent )」とするだけでAの子ノードを、「SELECT * FORM node WHERE 'C' = ANY( child )」とするだけでCの親ノードを、一発で抽出することが出来ます。

【2】しかしここで配列が使えないとすると、親子関係を定義するテーブルが別途必要になりますよね。
 < info テーブル>
 [ id ]  [その他]・・・
  A
  B
  C
 < link テーブル>
 [ parent ] [ child ]
   A     B
   A     C
   B     C
しかも、Aの子ノードを検索するのに、「SELECT * FROM info WHERE id IN ( SELECT child FROM link WHERE parent = 'A' )」といったサブクエリを使う必要も出てきます。

というわけで、配列を使うか使わないかで、データベースの構造が大きく異なるわけですが、やはり【2】に基づいて正規化を追求するべきなのでしょうか? サブクエリにオーバーヘッドがあるのなら【1】にも価値があると思うのですが、このような構造は非常識なのでしょうか? もっとも、配列型は中身の操作しにくいので、link テーブルのように展開してしまった方が、親子定義の操作が柔軟になる気もしますが。

何卒よろしく、ご教示願います。(>_<)

コメント(8)

どうも、通りすがりの酔っ払いです。

例にあるような、データ自体が複雑な体系のプロジェクトには、
関わったらめんどくさそうなので、あまり関わりたくないです。
データはなるったけ単純じゃなくっちゃ嫌です。

うーん・・・
Aの子でもあるBの子って、、CがAの養子になれば良いのか?!

・・・とまぁ、意味不明な感想の僕ですが、、

直感で言うと【2】を使うべきだと思いました。
将来、 "O"RDB を実装していない他のdbに移行する可能性が少なからず有るはずですし。。
その時はdataもsqlも作り直しまくりになるはずです。

ではおやすみなさーい。。
早速のご教示感謝致します。(^ ^)

> データはなるったけ単純じゃなくっちゃ嫌です。
なるほど、常識的に見てあまり、データベースで扱うべき構造ではないわけですね。正規化を考えても、なるべく簡素化するように勤めてみます。

> Aの子でもあるBの子って、、CがAの養子になれば良いのか?!
ははは、確かに。(^ ^) というのも現在、有向グラフをデータベース化できないかと模索していまして、このような例になってしまいました。親が必ず一人になるツリー構造を想定して頂いても構いません。

> 直感で言うと【2】を使うべきだと思いました。
やはりそうですか。小規模なシステムを想定していましたが、確かに汎用性を考えると辛いものがありますね。あと、リンク数が増えた時に、配列が膨れ上がるのがちょっと怖く思えました。再検討してみます。
【トピックへの追記】
・サブクエリのオーバーヘッドは無視できる程度なのでしょうか? もっとも、そんなシビアなシステムを作りたいわけではないのですが、積極的に使用してよいものなのか悩んでいます。
・PostgreSQLで配列型を利用する効果的なシーンにはどのようなものがあるのでしょうか? "O"RDBが出現した経緯も、マルチメディア的な複雑なデータを柔軟に扱おうとするニーズに答えたものだとは理解していますが、ちょこまかと配列を使う程度では、その恩恵があまり発揮されないものなのでしょうか?
あたりまえの答えになるんですが、配列を利用する効果的なシーンってのは、配列を使ったほうが楽で、配列を使うことによる悪影響がないときです

ANY()使っての検索にパフォーマンスが必要なら、配列はあきらめてRDBMSとして使ったほうがいいです(表がわかれたほうがチューニングのやりようはありますので)
> 配列を使うことによる悪影響がないときです
そうですね。その辺をもっと突き詰めてみます。

> 表がわかれたほうがチューニングのやりようはありますので
チューニング関連のサイトを色々見てみましたが、なるべく簡素にSQLまとめるのが鉄則のようですね。なるほど、決心が付きました。(^ ^) ご教示ありがとうございました。
> 配列でANY的な検索をしてもインデックスが使える機能
なるほど、"O"RDB としての進化もさらに進むのですね。オブジェクト指向に慣れ親しんだ私としてはとても喜ばしいのですが、やはりシンプルな RDB としての数学的な美しさも奥が深く、正直混乱してきてしまいました。(^_^;) 賛否両論はあるようですが、最近では完全なる ODB も開発されてきているようですし、とりあえず RDB の理解を深めながら動向を探っていきたいと思います。
【訂正】【2】の場合でも「SELECT * FORM info, link WHERE parent = 'A' AND child = id」と、サブクエリーなしに検索できましたね。(^_^;) 無知ですみません。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

PostgreSQL 更新情報

PostgreSQLのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング