- - PR -
主キーの設定について
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-11-08 17:25
vincentさん、ご返信いただきましてありがとうございます。
> 30回もデータベースアクセスするのは効率悪いんじゃないですか? ごもっともでした。 vincentさんのご指摘のもと、30回のデータベースアクセスではなく、一度取得したものをプログラムで処理させると、すごい早くなりました。 // やっぱり、無謀でした・・・。 データベースの接続処理ってわりとコストがかかると再認識しました。 | ||||||||||||||||
|
投稿日時: 2005-11-08 17:57
うむむ・・・ 別に用意したら「年+月のフィールド」(仮称 yearMonth)と day は 関数従属(day → yearMonth)という状態になりますよ? 二次正規化すらできていない表が出来上がります。 日付はRDBの日付型で保持するのがお勧めです。 postgresqlを含め多くのRDB実装で日付型は内部では数値として 扱われるので、上記のような範囲を指定するような場合も インデックス(PK)がとても有効に作用します。 そして何より「2005-02-99」とかプログラムで異常値の チェックをしなくてもよいことがメリットだと思います。 異常値は絶対無いことをRDBMSが保障してくれるのです。 だから、RDB"MS"なんですよ〜。 | ||||||||||||||||
|
投稿日時: 2005-11-09 01:38
日付加減算が楽にできるという理由で、がるがるさん同様、日付型を支持しますが・・・。
日付型の場合に 2005年だけ抽出 where ymd >= '2005/01/01 00:00:00' and ymd < '2006/01/01 00:00:00' 数値型の場合に 2005年だけ抽出 where ymd >= 20050101 and ymd < 20060101 処理コストに有意な差は見出せません。 | ||||||||||||||||
|
投稿日時: 2005-11-09 10:57
どもです。がるです。
ちっと言葉足らずでした。
んっと。テーブルレイアウト年と月と日で別々に持つと WHERE year=2005 で確認できるので、<>をもちいた、且つifが二つの演算よりは 多少違うだろう、という点で「処理コスト」って話をしたの ですが。 もっとも「どの程度体感できるか」はかなり疑問です(苦笑 # というか、最適化されていることを少しは期待したい。 | ||||||||||||||||
|
投稿日時: 2005-11-09 12:06
timestamp と numeric( の処理コストの比較ではなく、numeric( と numeric(4), numeric(2), numeric(2) の処理コストの比較でしたか。それでも、フィールドを 年、月、日 に分けた場合でも複合主キーとして設定する場合には、時系列に物理データが格納されるのが一般的ですから、やはり処理コストは変わらないでしょうね。
問い合わせクエリの記述量や複雑さは、直接、処理コストとは関係ないです。year=2005 であっても start < year and year < end であっても、テーブルが範囲スキャンされるのは一緒ですから。 | ||||||||||||||||
|
投稿日時: 2005-11-09 12:50
Java僧さんへ
未記入さんへ がるがるさんへ ご返信が遅くなってしまい、大変すみませんでした。 また、ご返信ありがとうございます。 皆様のご返答にGoogle先生にご協力いただきながら、ぎりぎりつい ていってます。m(_|_)m // 情けないです・・・。 > 日付加減算が楽にできるという理由で、がるがるさん同様、日付型を支持しますが・・・。 なるほど。 そうですね。 今回、皆様からご教授いただきまして、 year numeric(4), month numeric(2), day numeric(2) char(8) timestamp 明確にどれを主キー設定として用いるかについて、プログラム側や データベース設計側などから様々な見解があり一概には判断できな いと恥ずかしながら認識しました。 僕も皆様からのご意見を伺いしまして、今回は最終的に year numeric(4), month numeric(2), day numeric(2) primary key(year, month, day) をしました。 // 日付というデータ型をRDBに持たすという意味で、timestamp // と非常に迷いました。 皆様についていけるように、またがんばろうと思います。 皆様からは、多くのご意見、またわかりやすく説明していただけて、 本当に助かりました。 // 3ページへ突入するとは思っていませんでした。m(_|_)m そして、データベース設計の難しさを改めて実感しました。 本当にありがとうございました。 | ||||||||||||||||
|
投稿日時: 2005-11-09 12:58
がるです。
ちと興味があるので深めに。
なるほど。 ちとDBMSのソース解析とかしたわけではないので想像の域を超えない のですが。 なんとなく
と
ということを最終的にやっているような気がしてまして。 この場合 if (data->get_yy() == '2005') と比較して if ((data->get_ymd() >= '20050101') and (data->get_ymd() < '20060101')) { は「ifによる比較が常に2回行われる」事から、走っているCPU命令数が 増えるので処理コストもかさむのかなぁと思いまして。 # 正確には「左辺でfalseなら右辺の評価は行われない」事も多いので # 単純に二倍ではないと思うのですが。 いやまぁ実際には色々最適化されてるんじゃないかと期待は しているのですが & CPU命令で多少の増加があったとして 「体感できるか」ってのはまた別問題だと思うんですが。 もしかすると上述の前提が根本的に違うのかと思ったので、 もしなにかご存知ならとても興味がありまして。 | ||||||||||||||||
|
投稿日時: 2005-11-09 13:13
範囲スキャンの場合は、そもそも各レコードに対して該当するかどうかというチェックが行なわれません。レコードごとの合致検査に使われる if 文の複雑さという発想が、まずズレています。 もちろん、すべてのデータベースの実装がそうだとは言い切れませんし、あなたのいうようなシンプルな構造のデータベースも存在するかもしれませんが、パフォーマンスを考えると一般的ではないと思います。 |