不毛ですねえ。せめてあさ◎の中の人を引きずり込みたい(笑) (血統の森+はてな)
遅くなって申し訳ありませんでした(笑)。読ませてはいただいていたのですが、的外れなことを言っても混乱を招くだけですし、どういう風に参加したらいいものやらと考えておりました。
とりあえず、あさ◎DBで、血統DBを設計した時の手順や留意点、あとは簡単な構造などをまとめて見ましたので、参考になればと思います。オーソドックスな設計で、特別変わったことはしていません。重要そうな点については、下線を引いておきました。
◆基本的な設計
(1)I/O設計
・そもそもどこからどうやってデータを引っ張ってくるか?★
・想定するデータ数(テーブルの大きさ)
・全体のトラフィックとサーバ負荷(参照される回数、更新頻度)←おおざっぱでよい
・修正・削除をどうやって行なうか(血統の場合、修正は日常茶飯事)
(2)概念設計
・カバー対象(国内?海外?)
・項目 の範囲(ファミリーナンバーや種付け料までカバーするかどうか)
・系統をどうするか
(3)詳細設計
・テーブル設計(E‐RなりXMLなり)
・必須項目
・データ型
・非正規化(馬名重複、別名)
(4)運用
・継続可能な更新方法(飽きないで続けられるのが一番)★
◆血統DB作成上の留意点
(1)不完全なツリー構造
・血統のデータは概念上はツリー型構造をしています。しかし厄介なのは実際には不完全なツリー構造にならざるを得ないだということです。最初から全サラブレッドの血統を埋め尽くすことができればいいのですが、そんなことはとうていできません(デルマですら上のほうは穴だらけ)。ツリーのどの位置に配置すればいいのかわからないデータが、相当な割合で生じます(あさ◎DBでは半分以上)。完璧なツリーが実際に完成することはほぼありえないので、あまりツリー構造のデータだと意識せずに設計した方がいいと思います。
繁殖馬にせよ競走馬にせよ、すべてが入力されたデータを想定するのではなく、最低限の情報しか入っていないデータを想定した方がいいです。生年月日がわからないor誤った馬が入力されることも十分ありえるので、プライマリキーに生年月日等の意味をもたせるのも危険だと思います(JRA-VANの繁殖馬データですら間違いはかなりあります)。
(2)スケーラビリティ
・JRA-VANの繁殖馬は100万頭くらいでしょうか。あさ◎DBですらおよそ60000頭くらいあり、4年目を迎えつつある現在でも1年で5000件ずつくらい増えています。ある程度の網羅性を得るにはかなり大きくなることを想定(最低15000〜20000頭くらい)しないといけないと思います。
(3)系統の持たせ方
・実は系統の持たせ方は、悩みました。現在、[出馬表]などで系統が表示されていますが、これは、
「父が系統テーブルにデータのある種牡馬かどうかを調べる」→「父父を検索」→「父父父を検索」
という形で、系統を遡り、適当な系統が見つかるか、父の入力がないところまで繰り返します。従って表示処理が重くなり、実は24頭以上だと処理が落ちます(24頭以上の場合は系統を表示しないという形で対応中)。これを解決するには、Sire Tableで各繁殖馬に系統を持たせればいいのですが、これをやるにはプログラムを3本くらい書かなくてはいけない(例えば、新たな「系統」を切り出したときに、繁殖馬テーブル全体にそれを反映させるプログラム)のと、種牡馬ごとに系統を持たせると今度は種牡馬の新規登録・更新処理の方が重くなってしまう恐れがあったので、やめました。
ちなみに系統別の成績集計のプログラムは一応書きましたが、今のデータの持ち方ではまったく動きませんでした。系統別集計を用意するなら、繁殖馬ごとに系統を持たせないとまず無理だと思います。
(4)非正規化
・1件の繁殖馬データが父、母だけでなく、父父、父母、母父、母母・・・と遡ったデータを持つような設計を「非正規化」といいます。 更新の処理が不必要に重くなり、かつデータの整合性が取れなくなる原因になるので、基本的には反則なのですが、表示上やむを得ない場合(ex.参照される回数は多いのに、DBが大きすぎる場合)のみ、行なわれます。この辺参照。
血統DBでは、絶えずデータが更新・修正されるのですが、表示のためにDBを過度に非正規化し、各馬について5代前までの血統を全部持たせると、更新・修正処理が重くなります。たとえば新たに「サンデーサイレンスの父ヘイロー」が新たに入力された時に、SSの血を持つ繁殖馬すべてについて更新を行なわなくてはならなくなります。
(5)XMLDB or RDBMS?
・この辺にあるように、一般にXMLDBの長所は「データ構造を運用中に変更することが容易」という点にあると思います。RDBのテーブルAlterは、システム全般に影響を与えるクリティカルマターになりますが、XMLではそんなことはありません。その一方で、「リレーショナルデータベースにおけるSQLのような統一規格が(まだ)ない」、「(今のところ)パフォーマンス上問題がある」という欠点があります。
血統関係のデータは性質上データが頻繁に変更されることがないですし、規模も大きいので基本的にはRDB向きだと思います。ただ、別に仕事でやるわけじゃないですし、極端な話失敗しても構わないのですから、XMLでやったらどうなるのかというのを試したいというのであれば全然やっちゃってもいいとおもいます。使いたくもない技術では、モチベーションも保てないというものです(笑)
◆あさ◎DBの血統関係のデータ構造
特に変則的なことはしていません。
<繁殖テーブル(Sire Table)>
繁殖馬ID (必須)
馬名 (必須)
英語名
日本語名
性
生年
父(繁殖馬ID)
母(繁殖馬ID)
毛色
産国 (国ID)
供用国 (日本のみフラグ、馬名表示のコントロール用)
・トランザクションマスタ。新規登録はオン・バッチあわせて60頭/週程度。
・件数は約75000件
・必須項目は2つのみ。なお、「日本語名」か「英語名」のどちらかには必ず値が入ります。
・「馬名」は持っていますが、これは検索用で表示用には使ってません。何故こうなってしまうかというと、↓の問題のせいです。
・「重複」(ex.Brian's Timeとブライアンズタイム)、「同名」(ex.Bold Lad1とBold Lad2)が非常に厄介になると思います。
・空欄ばかりになってしまう項目を持ってもしょうがないと思ったので、最低限の項目しか持っていません。
・「牧場」や「種付け料」なども一度は考えましたが、トレースするのがあまりに大変なので、やめました。
<現役馬テーブル(Horseinfo Table)>
現役馬ID(必須)
馬名(必須)
日本語名
英語名
性
生年
父(繁殖馬ID)
母(繁殖馬ID)
毛色
産国(国ID)
厩舎(厩舎ID)
オーナー(不使用)
・トランザクションマスタ。新規登録は20頭/週程度。
・件数は約7000件
・Sireと似てますが、明確に分けてます。
・「馬名」については繁殖馬と同じ(ハリウッドオークスの"Cesario"と日本で走るシーザリオは別のデータとしてDBに入ってくる)。
・理由は概念的に異なるエンティティなのでわけないとごちゃごちゃになるのと、SireTableは現役馬の10倍以上大きいので、分けないと負荷がかかるからです。これはJRA-VanやJSEさんも分けてらっしゃると思います。
<系統テーブル(Sire Line Table)>
系統ID(必須)
系統名(必須)
小系統(必須)(繁殖馬ID)
大系統(必須)(繁殖馬ID)
大系統フラグ
色
・純然たるマスタテーブル。ほとんど内容が更新されることはない。
・件数は約130件
・これわけわからないと思いますが、 小系統はHaloやStorm Catなどある程度細分された系統です。これに対し、大系統はHerodとかNorthern Dancerといったおおざっぱな系統です。各馬の系統は、小系統によって表示し、大系統によって色分けしています。
・この図を見たらわかりやすいかもしれません。
質問や何かわからないことがありましたら、遠慮なくお願いします。たいして参考になるようなことは言えないと思いますが、自分のスキル上、あるいは経験上わかる範囲でお答えします(^^;
◆Track Back用リンク
http://d.hatena.ne.jp/momdo/20060127
http://d.hatena.ne.jp/arikui/20060128
この記事に対するコメント