あさ◎別館

とりあえず何かを書いてみる別館・・・

2005年04月

2005年04月13日

血統表の表示など。

白駒牧場さまの記事について。血統表の表示ロジック、作る前は難しそうで二の足を踏んでいたのですが、作ってみたらそれほど難しくなかったというのが実感です。

1.データの持ち方

データは以下のように何の工夫もなく持っています。テーブルを設計した時点では、血統表を作るかどうか決めかねていたので、血統表を意識せずにテーブルを設計しました。ですので、このデータの持ち方では苦労するのではないかと予想していました。基本的にはperlで作る場合でも、ファイルシステムを使う場合でもデータの持ち方はこれでいいと思います。

現役馬テーブル 繁殖馬テーブル
ID
馬名
001 ディープインパクト 100 200
002 ブラックタイド 100 200
003 ネオユニヴァース 100 -
       
       
       
       
       
ID
馬名
繁殖
100 サンデーサイレンス 101 201
101 ヘイロー 103 203
102 アルザオ    
103 ヘイルトゥリーズン    
200 ウインドインハーヘア 102 202
1
201 ウィッシングウェル    
1
202 バークレアー    
1
203 コスマー    
1

2.データの取り方

・現役馬「001」(ディープインパクト)のページをリクエスト
・現役馬「001」の父「100」をキーにして、繁殖馬テーブルを検索し、父父「101」と、父母「201」を取得する。
  ・父父「101」をキーにして繁殖馬テーブルを検索し、父父父「103」と、父父母「203」を取得する。
    ・父父父「103」をキーにして・・・・
    ・父父母「203」をキーにして・・・・
・現役馬001の母「200」をキーにして、繁殖馬テーブルを検索し、父父「102」と、父母「202」をを取得する。
・全部取得したらテーブルに配置。取得できなかったら「−」。

こんな感じです。繁殖テーブルを検索ところを関数にしておけば使いまわせるので、そんなに面倒ではありません。

ソースなんぞお見せしてもつまらないとは思いますが、こんな感じになってます。

//血統表表示する関数
function blood_table($sire_in, $dam_in){
global $PHP_SELF;

//データの取得 decode_sireは繁殖馬コードをキーにして、繁殖馬のデータ(名前、生年等)を取得する自作の関数
$decode_blood3 = decode_sire($sire_in["SIRE"], "sire");
$decode_blood4 = decode_sire($sire_in["DAM"], "dam");
$decode_blood5 = decode_sire($dam_in["SIRE"], "sire");
$decode_blood6 = decode_sire($dam_in["DAM"], "dam");
$decode_blood7 = decode_sire($decode_blood3["SIRE"], "sire");
$decode_blood8 = decode_sire($decode_blood3["DAM"], "dam");
$decode_blood9 = decode_sire($decode_blood4["SIRE"], "sire");
$decode_blood10 = decode_sire($decode_blood4["DAM"], "dam");
$decode_blood11 = decode_sire($decode_blood5["SIRE"], "sire");
$decode_blood12 = decode_sire($decode_blood5["DAM"], "dam");
$decode_blood13 = decode_sire($decode_blood6["SIRE"], "sire");
$decode_blood14 = decode_sire($decode_blood6["DAM"], "dam");
$decode_blood15 = decode_sire($decode_blood7["SIRE"], "sire");
$decode_blood16 = decode_sire($decode_blood7["DAM"], "dam");
$decode_blood17 = decode_sire($decode_blood8["SIRE"], "sire");
$decode_blood18 = decode_sire($decode_blood8["DAM"], "dam");
$decode_blood19 = decode_sire($decode_blood9["SIRE"], "sire");
$decode_blood20 = decode_sire($decode_blood9["DAM"], "dam");
$decode_blood21 = decode_sire($decode_blood10["SIRE"], "sire");
$decode_blood22 = decode_sire($decode_blood10["DAM"], "dam");
$decode_blood23 = decode_sire($decode_blood11["SIRE"], "sire");
$decode_blood24 = decode_sire($decode_blood11["DAM"], "dam");
$decode_blood25 = decode_sire($decode_blood12["SIRE"], "sire");
$decode_blood26 = decode_sire($decode_blood12["DAM"], "dam");
$decode_blood27 = decode_sire($decode_blood13["SIRE"], "sire");
$decode_blood28 = decode_sire($decode_blood13["DAM"], "dam");
$decode_blood29 = decode_sire($decode_blood14["SIRE"], "sire");
$decode_blood30 = decode_sire($decode_blood14["DAM"], "dam");

//リンクの生成 blood_listは上で得た繁殖馬コードをキーにして、繁殖馬のデータへのリンクタグを生成する自作の関数
$blood1 = blood_list($sire_in);
$blood2 = blood_list($dam_in);
$blood3 = blood_list($decode_blood3);
$blood4 = blood_list($decode_blood4);
$blood5 = blood_list($decode_blood5);
$blood6 = blood_list($decode_blood6);
$blood7 = blood_list($decode_blood7);
$blood8 = blood_list($decode_blood8);
$blood9 = blood_list($decode_blood9);
$blood10 = blood_list($decode_blood10);
$blood11 = blood_list($decode_blood11);
$blood12 = blood_list($decode_blood12);
$blood13 = blood_list($decode_blood13);
$blood14 = blood_list($decode_blood14);
$blood15 = blood_list($decode_blood15);
$blood16 = blood_list($decode_blood16);
$blood17 = blood_list($decode_blood17);
$blood18 = blood_list($decode_blood18);
$blood19 = blood_list($decode_blood19);
$blood20 = blood_list($decode_blood20);
$blood21 = blood_list($decode_blood21);
$blood22 = blood_list($decode_blood22);
$blood23 = blood_list($decode_blood23);
$blood24 = blood_list($decode_blood24);
$blood25 = blood_list($decode_blood25);
$blood26 = blood_list($decode_blood26);
$blood27 = blood_list($decode_blood27);
$blood28 = blood_list($decode_blood28);
$blood29 = blood_list($decode_blood29);
$blood30 = blood_list($decode_blood30);

//表示
print "

<table class=\"regist\" >
<tr>
<td rowspan=\"16\" class=\"sire\" >{$blood1}</td>
<td rowspan=\"8\" class=\"sire\" >{$blood3}</td>
<td rowspan=\"4\" class=\"sire\" >{$blood7}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood15}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood16}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"4\" class=\"dam\" >{$blood8}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood17}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood18}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"8\" class=\"dam\" >{$blood4}</td>
<td rowspan=\"4\" class=\"sire\" >{$blood9}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood19}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood20}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"4\" class=\"dam\" >{$blood10}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood21}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood22}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"16\" class=\"dam\" >{$blood2}</td>
<td rowspan=\"8\" class=\"sire\" >{$blood5}</td>
<td rowspan=\"4\" class=\"sire\" >{$blood11}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood23}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood24}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"4\" class=\"dam\" >{$blood12}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood25}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood26}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"8\" class=\"dam\" >{$blood6}</td>
<td rowspan=\"4\" class=\"sire\" >{$blood13}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood27}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood28}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"4\" class=\"dam\" >{$blood14}</td>
<td rowspan=\"2\" class=\"sire\" >{$blood29}</td>
</tr>
<tr> </tr>
<tr>
<td rowspan=\"2\" class=\"dam\" >{$blood30}</td>
</tr>
<tr> </tr>
</table>
";
}


3.系統検索

むしろ難しいのは、逆の検索だと思います。 つまり、「系統検索」。

ある繁殖馬からその直仔を検索するところまではそれほど難しくはないのですが、上のデータの持ち方で「ノーザンダンサー系」、「ヘイロー系」などの系統を検索するのは難しいです。問題は以下の二つ。(1)何代先まで検索を繰り返せばいいのかがわからない、(2)大きなテーブル相手に大きな検索をかけるので、非常に重くなる。TARGETでも系統検索が可能になりましたが、「セントサイモン系」なんぞ検索しようものなら、えらい時間がかかります。

検索を軽くするためには検索を絞り込むためのデータを「繁殖テーブル」持つ必要があります。会計のシステムでも、「予算科目」、「勘定科目」の細目とかつける場合には、ツリー構造のデータのもち方をします(RDBでのデータの持ち方はややこしいので割愛)。

階層構造をもったデータの管理に適してるのがXMLDBだと認識していますので、基本的には血統データの管理には向いてるとは思います。


4.XMLDB

ただ・・・。

お勉強がてらXMLでDBを構築することも一瞬頭をよぎりましたが、やめました。データの作成・更新はまだいいにしても(といってもデータ設計のイメージは湧いてない)、データ検索・表示のところを作るのが大変そうなのと、パフォーマンスチューニングに至っては見当もつかなかったのが理由です(=スキルがない)。セキュリティも少し心配でした。まぁ、いったんMySQLでデータを持ってしまった以上、同じデータをXMLで持つのは正規化の観点から合理的ではないので、XML化をする予定は当面ありません。まだまだバグもありますし(笑)。しかし・・・・。

XMLDBでの開発にはなかなか踏み切れないのはなぜだろうか。これには、XMLのツリー構造でデータを定義した経験がなく、なんとなく覚えるのが大変そうだといった、いわゆる「食わず嫌い」が大きく影響しているようだ。これなら簡単 RDBからXMLDBへのデータ移行より

これはあたりw まさに「なんとなく大変そう」。効率性の高いデータの持ち方を考えるのにはとても頭を使います。その点、RDB&SQLは慣れてしまえば頭使わないでいいんですよね・・。


5.UMASQL

あれは基本的にJRA-VANのデータをRDBMSにぶち込んでるんだと思います。血統表の穴がある部分が同じですし、カバーしてる期間も同じなので。整形されたデータを処理すればいいだけなので、一回インターフェースとってしまえばわりと管理は楽なんじゃないかなと思います・・・。大量のアクセスに対応するのが大変でしょうけれど。


6.セッション

senchouさま@四号館ご紹介のdev.ishinao.netさまの記事の中では、セッションを使ってみたいと思いました。現在のところセキュリティを全然考えていないので、ろくな入力画面をつくれていないのです。


ほとんど参考にはならないと思いますが、こんな感じです。それにしても自分の書いたヘボソースを出すのは恥ずかしいな・・。
2005年04月03日

国別ページ完成

【1】国別ページ@あさ◎DB

国別のページを作りました。検索で「国」を選んで検索をするか、トップページの左下で国を選択してください。とりあえず、現在国マスタテーブルに存在するのは以下の国です。

国名
日本 アラブ首長国連邦
アルゼンチン
アメリカ ウルグアイ
カナダ オーストラリア
クウェート
アイルランド サウジアラビア
イギリス シンガポール
イタリア チリ
チェコ トルコ
ドイツ ニュージーランド
フランス ブラジル
  ペルー
  マカオ
  香港
  南アフリカ

調教師マスタのメンテをする時にクウェートやチェコなんかを加えたので、これらの諸国のレースデータは当然のごとくありませんが、トラックバック用に使ってください。ジンバブエ、とか中米諸国、ロシアとか北欧の諸国あたりは時間があるときに加えておきます(追加してほしい国があれば、BBSにお願いします)。それほどの議論の広がりやアクセス数の向上は望めないかもしれませんが、もしよろしければ、トラックバックを送って使ってみてください。送られるトラックバックの件数が増えてくるようであれば、表示を少し工夫しようと思います。

【2】トラセン関係

senchouさまにいろいろご意見をいただきました。ありがとうございます。

新着レースRSSについては、表示できると、うれしいと思いますです。
国カテゴリが出来るのであれば、さらにカテゴリ別も、、、とか図々しい妄想を、、、
ついでにトラックバックと投稿のも、、、いえ、何でもありません。
トラックバックの場合RSSの更新のタイミングというのは難しい問題かも、です。
トラセンαの場合はトラバ受信と同時にRSS生成をしてしまっています。
これはトラックバック受信時くらいしか、cgiに負荷をかけないから出来る事で、あさ@DBでは難しいのかもしれませんね。

(1)新着トラックバック
更新の負荷もそうなのですが、あんまりごてごてとRSSを持ってしまうとせっかくデータをDBに入れた意味が薄れてしまうので難しいところですね・・。あと、トラックバックの生成はPerlで行い、表示はPHPで行なっているのですが、トラックバック受信のタイミングでRSSを作るとなると、私がPerl詳しくないという大問題が生まれます(笑) ちょっと考えてみます。

(2)新着レース
これは、更新をPHPでやってるので、一番最初にできるかも・・。出馬表へのアクセスがもう少し増えたらいいなと思っていますので(+10程度で十分ですが)、これはいいかもしれません。

(3)国カテゴリ
今は作ったばかりでどう運用されるか謎なので、後回しで。 盛り上がってくるようであればという感じでしょうかね。

2005年04月02日

アクセス数

アクセス数。自分のアクセスと予想されるものを除く。PHPのテストをすると恐ろしい勢いでPVが回るので。
移転前にアクセス解析のログが飛んでしまったので、これ以前はわかりません。
予想大会などをやってるので、 基本的に1アクセスあたりのPV(PV/Access)が多いサイト。
Accessが増える一方、PV/Accessが落ちてきたのは、おそらくコラムを紹介してくださる方&外から見てくださる方が増えたから。
ということで、今後ともご愛顧のほどをよろしくお願いいたしますm(_ _)m

Access
PV
PV/Access
2005年3月
8,394
46,312
5.5
2005年2月
5,749
34,926
6.1
2005年1月
6,234
43,749
7.0
2004年12月
3,933
38,598
9.8
2004年11月
4,394
33,876
7.7
2004年10月
3,695
48,812
13.2
32,399
24,6273
7.6

2005年04月01日

DBのトラックバック機能

【1】トラックバックテーブル(MySQL)
・mySQL、PHP、Jcode.pm、tb-standalone・・とそれぞれに文字化けに苦しみましたが、
一応トラックバックのデータをデータベースで持たせることに成功しました。
・ローカルの環境作りにほとんどの時間を費やして、機能追加は一瞬で終わってしまったのがかなり切なかったですが。
・さっそくですが、mySQLからデータを引っ張って新着トラックバック一覧を出してみました。
・いったんデータで持ってしまえば、あとの抽出の仕方はそんなに難しくないので、いろいろできます。
<ルール(仮)>
・レースや競走馬など関連する項目に対してトラバを打つことができる。
・一つのエントリのトラバが複数の項目と関連する場合、(たとえば、[ディープインパクト]と[皐月賞])
複数の項目に対してトラバを打っても構わない。今後こういったケースが多いようであれば、新着一覧の表示を工夫する予定。
・項目とまったく関係のないトラバは削除対象にする。
・予想トラバも歓迎

【2】海外記事のトラックバック
・DBは国、競馬場のマスタテーブルを持っているので、[国]×[年月]、または[国]×[年]くらいでカテゴライズして(例:トラックバックID=usa_200505)、表示用のページを一つ作れば、現在の[レース]、[競走馬]、[調教師]、[騎手]、[種牡馬・繁殖]の6つのカテゴリで分類できない記事も、ある程度は網羅できるとは思います。例えば、[クールモアの話題]はアイルランドに、[騎手の保険問題]はアメリカに投稿してもらうという感じです。 ひとまず、海外に関しては全体の記事数が多くないので、今のところこれ以上のカテゴライズは不要だと思います。
・国別のページはいずれ作る予定でしたので、作った時に追加してみます。

【3】RSS
・大きな問題は(1)何をRSSで持つか、(2)更新のタイミング。
・(1)RSS配信、特に現在開発が進められているトラックバックセンターに情報をご提供することじたいはやぶさかではないのですが、何をどのタイミングでお渡しすればいいのかがイメージが湧きません。トップページの更新RSSがあればいいのかな・・。なお、DBの投稿欄の記事については、まだ投稿者が少ないのと、「電波上等」な運用にしたいので(笑)、RSSでは持たない予定です。新着トラックバックについては未定。
・(2)DBの更新プログラムが走る、[レース登録]、[枠順確定]、[結果確定]のタイミングがいいかな・・。

【4】トラセン
・ノイズの排除ならSlashdotで採用しているようなモデレーションシステムがありますね。JSEの管理人さんもかつて導入を検討されたことがありました。まぁ、かなり繊細に運用ルールを決めないといけないシステムですし、競馬関係の話題でモデレータになりうる人がどれだけの数存在するのか私にはわかりませんし、なかなか難しいかもしれません。

【5】その他、DBで予定している機能
・各種ランキング:騎手、調教師、種牡馬ランキング。いずれ国別に出したいところですが、とりあえず地域別に出してみました。
・賞金(Purse)をデータとして持っていないので、ポイントの割り振り方を考える必要あり。

G1−1着:10pt 2着:6pt 3着:4pt
G2−1着:6pt 2着:4pt 3着:2pt
G3−1着:4pt 2着:2pt 3着:1pt
OP−1着:2pt 2着:1pt 3着:0pt
こんなところ?
» 続きを読む
Made with dreamweaverMade with fireworksPowered by Movable Type 3.2-ja-2Powered by Wandering Wind
Copyright : [Articles] (C) 2004 あさ◎別館. All Rights Reserved.
[Comments/Trackbacks] ... Authors of those have rights.