DB設計を語るスレ 3at DB
DB設計を語るスレ 3 - 暇つぶし2ch59:NAME IS NULL
10/07/08 19:50:03
create table Locale(
LocaleID int,
Language char(3),
Message nvarchar(100)
)
select jpn.Message, eng.Message
from Locale as jpn
inner join Locale as eng
on jpn.LocaleID = eng.LocaleID
and eng.Language = 'eng'
and jpn.Language = 'jpn'



60:NAME IS NULL
10/07/08 19:57:54
商品名の対訳表なら、商品の主キー+言語コードで主キーにするな、俺なら


61:NAME IS NULL
10/07/08 20:48:47 mgDV/kGB
>>59 >>60
なるほど。これなら言語増えても列増やさなくて済むんですね。
こういうの自己結合って言うんですね。
自己結合って知らなかったので調べてみます。
いま全く知らない状態だと select Message, Language from Locale where LocaleID = 3
の方が速いんじゃないの?とか
行数増えると結合してるから遅くなるんじゃないの?とか思ってたりします。

62:NAME IS NULL
10/07/08 21:24:44
自己結合知らんような初心者がパフォーマンス考えるとかムダだから

63:NAME IS NULL
10/07/08 23:34:03 mgDV/kGB
>>62
はい。ベテランの方々が提示したものが初心者の私が考えるより確実にいい設計だと思うので、
そのまま使おうと思います。

64:NAME IS NULL
10/07/09 00:55:58
create table locale (
localeid int,
jpn nvarchar(100),
eng nvarchar(100),
doitu nvarchar(100),
china nvarchar(100)
)

65:NAME IS NULL
10/07/09 01:07:19

メンテしやすい

66:NAME IS NULL
10/07/09 01:15:13
それはないわ

67:NAME IS NULL
10/07/09 01:27:27
俺はその形大好きだがw

68:NAME IS NULL
10/07/09 01:38:57
>>66
なんでないと思うのかな。必ず全部の言語のデータを一対一で作るという前提なら、ありだろ。

69:NAME IS NULL
10/07/09 03:42:13
だってdoituだよ?

70:NAME IS NULL
10/07/09 11:37:32
>>66
将来にわたって言語の追加変更削除がないことが担保されるならありだと思うが

71:NAME IS NULL
10/07/10 00:23:34
add columnしとけ。

72:名無しさん@そうだ選挙に行こう
10/07/10 10:24:04
>>64
要件変更時に悲惨なことになりそうな予感しかしない。

73:名無しさん@そうだ選挙に行こう
10/07/11 10:24:03
chinaだけちゃんとしたフルネーム

74:名無しさん@そうだ選挙に行こう
10/07/11 10:25:47
あ、フルネームって前に付くあれは無しで

75:NAME IS NULL
10/07/12 22:21:49
ごく基本的なテーブル設計の話なんですが。

例えば「プレイヤーは複数の村を所持、村は複数の家を所持する」場合って

こういうのが↓依存リレーションで
playerテーブル:primary(player_id), player_name, ...
villageテーブル:primary(player_id, villege_no), village_name, ...
houseテーブル:primary(player_id, villege_no, house_no), house_name, ...

こういうのが↓非依存リレーションって言うんですよね?
playerテーブル:player_id(primary), player_name, ...
villageテーブル:village_id(primary), player_id(foreign), village_name, ...
houseテーブル:house_id(primary), village_id(foreign), house_name, ...

どちらを採択すべきか、っていうのは何を基準に考えたらいいんでしょう?
(もしくはどちらでもない別のがあるとか)
雑談程度に前者の設計について話してたら「20年前の設計だろ」なんて言われてしまって
ちょっと気になっています。(その人は言い捨てて消えてしまったので聞けない)

またそれぞれのメリットデメリットなんかもあれば教えて頂きたい
(もしくは参考URLでも)。わりと調べたつもりなんですがイマイチいいのがHitせず。

76:NAME IS NULL
10/07/12 22:27:59
実際に両方で作ってみたらいいじゃん。
どっちもhouse_name village_nameを何度も書くはめになることに気づくよ。

それでもいいんだ!っていうなら1テーブルで作っちゃえばいいと思う。
「いちいち」player village houseを分ける必要ないでしょ。

77:75
10/07/12 22:29:29
あ、各テーブルの関係は1:Nです。情報後出しで申し訳ない。

あと設計のケースとして一個忘れてた、
player, player_villege, villege, villege_house, house と作るケース。
なんて呼ぶのかわかりませんが。

一応自分の考えを書いておくと、
1:Nで、それこそ子の存在が親の存在に依存する場合は依存リレーション、そうでなきゃ非依存
ってだけの話かと考えているのですが。古いとかじゃなくて。

↑に追加で書いたのは、N:Nのときに使う、と。
(逆に言うと1:Nのときに使うメリットは特に無いと思う)

78:NAME IS NULL
10/07/12 22:32:53
ごめん見落としていた。
>>75の後者って、一つの村は一つのユーザしか所有できないという制限になると思うけど
それはそういう仕様?
ならそれでもいい。

前者は正規化すべき対象がある(かつ、それが煩雑になりすぎない)のに
やらないというところが20年前なんじゃないかな。

79:75
10/07/12 22:45:14
>>78
そこは(遅れましたが)1:Nなので仕様です。

前者のほうが、「家IDから所有プレイヤーを逆引きするのが楽」だとか、
「親が存在しないのに子が存在しうる」といったデメリットがありますが
それでも後者にすべき?

今挙げた二つのデメリットは、最悪冗長なカラムを持つとか、
制約をしっかり設定すればいい話だけど…
パフォーマンスとしては前者の方がいいような気がするのですが。

…いや、それこそ両方組んで実データぶっこんでテストしなきゃわからないか。
結局どちらが是かは要件次第、なのかなぁ。

80:NAME IS NULL
10/07/12 23:07:09
1:Nなら前者にする必要がないんじゃ?
> villageテーブル:primary(player_id, villege_no), village_name, ...
に、unique(village_no)をつけて1:Nであるとアピールしてもいいけど。

「親が存在しないのに子が存在しうる」
これを避けたいなら外部キー制約でいけると思う。

パフォーマンスはこの情報だけだと環境によるとしかいえないかと。

あと、誰も所有していない村や家はどうなるの?

81:75
10/07/12 23:25:03
あれ、俺疲れてんのかな…

よく考えたら子があるのに親がないリスクは前者も後者も同じですよね。
とにかくこれは制約でどうにでもなると。

誰も所有してない村や家は存在してはいけないので削除…いや、
件数がかなり多い(数千万レベル)のでdelete_flag式にするから制約できないや。
そこはPGの責任でしっかり組むことにします。

やっぱり前者に拘る理由は「逆引きが楽」くらい?
indexによる検索性能…も正しくIndex作れば同じ?か?
だんだん「そもそも依存リレーションの存在価値って何」って考えになってきた。

ちなみに質問では親ー子ー孫の3層にしましたが実装は4層。
前者にするとキー長が長くなって検索にはむしろ不利なのか?

82:NAME IS NULL
10/07/12 23:35:48
後者は外部キー制約あるんだから、家があるなら村はあるはずだし、
村があるならプレイヤーはいるはずになっているよ。

キーが長くなるというか、インデックスが肥大化するんでないかね。
そのへん詳しくないけど。

依存リレーションという言葉も知らなくてなんだかごめん。

83:NAME IS NULL
10/07/12 23:42:05
で、今依存、非依存について調べたわけですが、

前者は存在しないplayer_idをvillageに登録できるし、
villageがなくともplayerを登録できるので、互いに非依存

後者は>>82で書いたように、playerがいなければvillageに
登録できないが、villageがなくともplayerは登録できるため、
villageはplayerに依存し、playerはvillageに非依存である

ということなんじゃないのかなーと。

84:NAME IS NULL
10/07/13 00:03:57
PG的には村や家に確実にユニークなIDが振られてる方が楽だと思うが。逆引きするにしても。
「前者のvillege_noやhouse_noも実はユニークなんです(キリッ」なら糞設計と呼ばれても仕方ないと思うけど。

85:NAME IS NULL
10/07/13 00:16:17
どう考えても後者の設計だな。前者のが古いかどうかは知らないが、親子関係が変更になった時に主キーに触らないといけないのが気持ち悪い。

86:75
10/07/13 00:47:25
うーむ…。よし、ここは経験と思って、後者で実装することにします。
すでに前者で組んでる最中の、取り返しが付かない段階のシステムがあるので、
違いを肌で感じることにします。

ありがとう御座いました。肌で感じたあとブログにでもまとめようと思います。

87:NAME IS NULL
10/07/13 00:52:30
てかもっと新しい(?)というか安全なのは、「プレイヤー-村」関連テーブルと「村-家」関連テーブルを別途作ることじゃないかね。

88:75
10/07/13 00:58:41
>>87
それが>>77で追加したやつのことなんですけど、
N:Nならそうせざるを得ないとして、
1:Nでもそこまでします?

その形にすると、子要素1件の増減につき必ず2テーブル触らないといけないので
パフォーマンスが気になります。

1:Nなので、「プレイヤー村」関連テーブルと「村」テーブルの
件数って完全一致で、「なんのために2テーブルに別れてんだ?」って考えてしまうのですが。

89:NAME IS NULL
10/07/13 01:16:13
その程度でパフォーマンスが気になるほど更新が頻繁なのか?

90:75
10/07/13 01:30:31
更新はそれなりに頻繁、件数が億単位を想定。
パフォーマンスのために多少の開発効率を落とすのも辞さないレベル。

91:NAME IS NULL
10/07/13 01:34:22
んな条件を後出しすんじゃねぇよwww
億単位レコードのテーブルは非正規化されてる方が普通なくらいだろw

92:75
10/07/13 01:41:34
で、ですよね。すいません。

それを先に出すべきとか言うところに頭がピンと来ない人間が
億単位システムのDB設計をしているという…。

93:NAME IS NULL
10/07/13 01:43:50
ていうかそれ何のDB?

94:75
10/07/13 01:53:46
MySQLです。

まぁ最初はよほど負荷が見えてるところ意外は基本的に正規形で考えて
後から発覚した負荷について非正規形にする感じで考えてる。

95:NAME IS NULL
10/07/13 02:29:42
それがもしモバゲとかグリーとかブラゲならDB以外にも抑えておかないといけない点がいくつかあるんだけど
その辺は大丈夫なのかね。

96:75
10/07/13 02:37:20
そのへんは肯定も否定もしないでおくけど
memcache使うとか基幹システムAPIは極力叩かないとかは抑えてるつもり。
まぁスレ違いにもなって申し訳ないのであくまでDB設計の話を、と。
ご忠告感謝。


97:NAME IS NULL
10/07/13 02:46:23
そっか。それなら、だいじょうぶかな。DBも分散を検討してね。
うまく行くことを願っているよ。

98:75
10/07/13 03:59:17
MASTER、SLAVEの分散もありました、忘れてました。
あとコネクションを極力短く、少なくとか。状況次第じゃいったん切るとか。

で、報告までに。
「複合キー」とか「サロゲートキー」とかでググりまくったら、
「古い」なんて言われたのもぼんやりと納得できてきました。

階層構造に複合キーを使うなんてのは2秒で否定されるレベル、
といった感じが伝わってきました。
(それでも「必ずしも」ではない、ケースバイケースなんだろうけど)

取り返しがつく今のうちに修正に入ることにします…。

99:NAME IS NULL
10/07/13 10:25:55
今どき複合キーはないわ。
オブジェクト指向とかORM(Object Relational Mapping)とか考えるとサロゲートキー一択っしょ。

あと、1:Nなら関連テーブルは不要だね。

100:NAME IS NULL
10/07/13 11:55:11
俺なら前者にはしない。
なぜなら、playerが所有しない村も(今は無くとも)存在するだろう(かもしれない)し、家も同様。
また、所有者が変更になるとき、pkeyの更新になるのはいただけない。

101:NAME IS NULL
10/07/13 22:17:58
複合キーとサロゲートキーって、
具体的にどう違うの?


102:NAME IS NULL
10/07/13 23:08:29
サロゲートは完全なキーであるためだけのキー。


103:NAME IS NULL
10/07/14 13:04:15
>>102
単独か複合かは関係ないんですね?
ユニークと同じ意味と思っていい?


104:NAME IS NULL
10/07/14 13:13:29
>>103
何で調べないの?
Wikipediaでもある程度わかるのに。
URLリンク(ja.wikipedia.org)

105:NAME IS NULL
10/07/14 22:43:21
サロゲートキーは「本当はいらないはずだけど、どうしても作らなければいけない」
というイメージがあります。
ダミー列がprimary keyのような感じ。

106:NAME IS NULL
10/07/14 22:52:25
祇園精舎の鐘の声
諸行無常の響きあり

沙羅双樹の花の色
盛者必衰の理をあらわす

おごれる人も久しからず
ただ春の世の夢のごとし

たけき者も遂には滅びぬ
偏に風の前の塵に同じ

サロゲートキー、それは自然キーの否定。


107:NAME IS NULL
10/07/15 09:22:23
>>105
あんたの感想はわかった。それで?

108:NAME IS NULL
10/07/15 11:02:19
いやまぁ合ってるよ
業務要件上はいらないけど、システム要件上は必要なので
ダミー(ユニークネスを保証する以外に意味のない)列を追加するわけだから

109:NAME IS NULL
10/07/15 11:14:09
まーた始まった

110:NAME IS NULL
10/07/15 21:21:24
>>107
ごめんなさい。

111:NAME IS NULL
10/07/18 09:49:29
>>109
ん?まーた始まったって?

私は初めて書き込みますが、サロゲートキーは一つのデータベースで必要な部分と不必要な部分があります
必要な部分では必ず適用します
不要な部分では使用しません
何故必要な部分で使用するかというと使用しなかった時に大変困ったという経験則に基づくものです
不要な部分というのはデータベースごとで違うでしょうが、使用しなくても大して困らなかったという経験則に基づくものです
つまり必要無いと思う人は使わなければ良いし必要だと思う人は使えば良いだけじゃないでしょうか

112:NAME IS NULL
10/07/18 14:00:29
>>111
「必要なとき使う、不要なとき使わない、その基準は経験則」
そんな情報をネット上のフォーラムに残すことに何の意味がある?誰の参考になる?

どうせならその経験則を少しでも、ほんの一部でも噛み砕いて置いていってくれないか。

113:NAME IS NULL
10/07/18 14:31:12
>>111ではないが、RDB的なサロゲートキーってのはその名のとおり長大な
複合キーなど取り回しに難がある場合に代理として用いるものだろ。どのくらいで
「難がある」かはケースバイケース。
ただし、>>108の言うような「ユニークネスを保証する以外に意味のない」キー
というのは本来のサロゲートキーとは違って、OODBのIDのようなもの。
こいつらはデータモデルがそもそも違うんで、ごっちゃに議論すると発散する。

114:NAME IS NULL
10/07/18 15:17:40
顧客が決める気持ち悪いコードに対して
それと1対1になるように一見意味のなさそうなIDを振りなおすのがサロゲートキー。
(あとから仕様変更によって、1対1じゃなくなる可能性があるが)

単にテーブル設計の都合上の複合キーに対してIDを振りなおすのは
ちょっとわけが違うということか。

115:NAME IS NULL
10/07/18 15:58:36
いや、どっちかっつーとサロゲートキーというのは後者。
また、前者で1:1でなくなる仕様変更というのは、RDB的には「そんな仕様変更があったら
従属関係が変わってるからテーブル定義を変更せずに済むとは限らんだろ」となる。
これが有効なのは、OOあるいはER的に「オブジェクト/エンティティ境界はそれが持つ
属性やその関係よりも安定である」という前提でそのように設計した場合の話。

116:NAME IS NULL
10/07/18 17:20:37
サロゲートキーが必要/不必要で論じると、
複合キーを認めないという前提でないかぎり、すべて不必要だと思うが

ただ単に取り扱いが楽かどうかだけの問題以外に必要性があるなら教えてほしい

117:NAME IS NULL
10/08/07 07:48:37
ニコニコ動画とかのタグ付けって
ひとつのカラムに空白区切りとかで押しこむのが普通なんでしょうか?


118:NAME IS NULL
10/08/07 09:52:59
>>117
動画テーブルと、タグテーブルの間でN:Mの関連を構築すればいいんじゃないの?

119:NAME IS NULL
10/08/07 16:40:59
>>118
ありがとうございます
勉強してきます > <

120:NAME IS NULL
10/08/07 20:29:49
URLリンク(q.hatena.ne.jp)
仕事でやってるとこんな風に考えられるのか・・・
アマだとまったく思いつかない; ;

121:NAME IS NULL
10/08/07 22:56:44
実際の仕事ではpopular_tagsとtagsテーブルは合算されるよ
なるべくテーブル数は減らして結合処理のボトルネックを減らした方が後々いいからね


122:NAME IS NULL
10/08/08 16:59:01
減らす為にpopular_tagsを作ってるんじゃ。。

123:NAME IS NULL
10/08/09 00:27:37
え?

124:NAME IS NULL
10/08/09 12:04:21
数学

125:NAME IS NULL
10/08/09 22:23:38
>>121
>なるべくテーブル数は減らして結合処理のボトルネックを減らした方が後々いいからね
やめてくれ

126:NAME IS NULL
10/08/09 22:36:39
初心者は結合すると遅くなると本気で信じてる奴いるからな。

127:NAME IS NULL
10/08/10 02:41:55
ド素人が第三正規化にこだわるのをよく見るな

128:NAME IS NULL
10/08/10 11:17:30
> 結合処理のボトルネック
SQL書けない馬鹿の言い訳

129:NAME IS NULL
10/08/10 12:42:16
あるあるw

130:NAME IS NULL
10/08/10 13:30:12
>>120
相変わらずhatenaはレベルの低い回答が多いな

131:NAME IS NULL
10/08/10 14:07:34
SQL書けない人にJOINさせると開発工数のボトルネックになる(笑)

132:NAME IS NULL
10/08/10 15:46:06
>>120をよく読まずに>>121が反応してるので話がかみ合ってないだけじゃね?
popular_tagsはタグの種類じゃなくて集計用のテーブル。
目的は精度や時系列の一貫性を求められないが頻繁に参照されるデータの取り扱いのためであって、
正規化やそれを崩した場合のJOINのパフォーマンス云々は関係ない。

133:NAME IS NULL
10/08/10 18:31:51
集計のためのカウントアップの前にjoinする必要がある
結果を表示する時もjoinする必要がある
結論:無駄

おk?

134:NAME IS NULL
10/08/10 19:00:09
>>133
だからさ、どういう仕組みのシステムを想定してるかで変わってくるのだから、
その辺を明確にしないと話がかみ合わない。
それぞれ違うものを想定して結論だけをあーだこーだ言っても仕方ないだろ。


135:NAME IS NULL
10/08/10 19:22:10
あのさ、普通に考えてみなよ
カウントアップの時はユーザがタグを入力した時
そのタグ名を判定しつつカウントアップしないといけない
つまりjoinまたは過剰なクエリ発行を伴う

結果表示も同じ
タグ名無しで表示される事何てまずない

システムによっても糞もないだろ
id指定でカウントアップする事例ってあるのか?
id表示させて満足させる集計表示ってあるのか?
まともなシステムならねぇだろ

たのむから億単位のレコードを扱ってから物申してくれ
こんな設計をする奴は経験が浅い

136:NAME IS NULL
10/08/10 19:28:19
>>135
じゃ一つシナリオを挙げよう。
popular_tagsテーブルはいらない。tagsをgroup byすれば済む。
ただこれを人気タグの一覧を表示するごとにクエリするとコストが高い。
それで10分おき位にgroup byのクエリを行い、popular_tagsテーブルにキャッシュしておく。
場合によってはRDBではなくアプリケーションサーバー内のメモリにキャッシュしてても良い。

137:NAME IS NULL
10/08/10 22:25:31
>>121
>実際の仕事ではpopular_tagsとtagsテーブルは合算されるよ
合算って何?

138:NAME IS NULL
10/08/11 00:04:59
>>135
ずれてない?

139:NAME IS NULL
10/08/12 16:56:53
所与の条件は、タグは自由入力形式で1つのコンテンツに対して複数付けられるってことだよね。
人気タグに関しては検索数(参照数)が多いのか、付けた数が多いのか明確にされていない。
また集計期間を設けるかどうかやその期間についても明らかにされていない。
検索数の場合はカウントアップが必要になるかもしれないが、
付加数ならば>>136の方法が妥当じゃないかな。
>>135の想定しているものがいまいち分からないが、
それぞれのテーブルが1:1:1でとか考えていて、
タグ名と参照数をわざわざ3テーブルに分けるのは無駄だとか考えているのだろうか。
>>136のはコンテンツとタグが1:n、人気タグテーブルが独立して存在という考え方だろう。


140:NAME IS NULL
10/10/14 02:48:47 etNKxQCa
>>127
第三正規化が正確に出来てから言え!!
まずこだわることが大事だぞ。

141:NAME IS NULL
10/10/14 10:25:29
>>127のはできないやつのいいわけだからw

142:NAME IS NULL
10/10/14 10:45:55
121みたいな何も知らない馬鹿はおいておいて、人気タグのようなケースはデータ構造というよりアプリ依存の話だから、ごっちゃに話すと混乱するでしょ。

データ構造の話でいえば、ちゃんと正規化して最適化されたデータ構造が保持できていれば、人気タグのような集計系によるJOINも問題なし。
いまどきの商用(とほぼ同等品も含む)RDBMSならストアドにすれば高コストと言ってもたかが知れてる。(タグが毎秒何千とかで追加変更されているとかじゃない限りw)
当然、適正に正規化できているデータ構造に冗長なテーブルは存在しない(まぁ、それは理想だがw)。

アプリの話で言えば、WEBアプリのネックはページ生成と通信部分だから、サーバサイドのデータ処理よりこちらのほうが普通はデメリットになる。
なので、人気タグやそのとび先をあらかじめ一定時間毎に静的ページ(厳密には静的ページではなくてもそれと同等の負荷のものも含む)を作成するような場合もある。
検索でインデックスと展開先をあらかじめ作っておくパターン。このような場合は、そのページ生成のためのデータをどこかに当然吐き出すわけだが、
それがテーブルなのかHTMLのようなファイルなのか、とにかく出力先の違いだけ。

hatenaの回答者はそれを一緒くたに回答しているので話がややこしくなってる。

143:NAME IS NULL
10/10/14 14:33:13
ナンカワロタw
どんだけ一人の書き込みを気にしてんだよw

144:NAME IS NULL
10/10/14 17:27:43
一人の書き込みに食いつかざるを得ないほど、ネタがないw

145:NAME IS NULL
10/10/14 20:57:41
アクセスコストがストアドで解決できるとかw

146:NAME IS NULL
10/10/15 00:14:44
>>121は、元コボラーだな。

元コボラーが設計したテーブル設計って酷いのが多いんだわ。

147:NAME IS NULL
10/10/15 07:39:41
>>145
アクセスコストの話は下段だろjk

148:NAME IS NULL
10/10/15 09:10:34
121の人気に嫉妬w
たぶん合ってるから人気なんだろうなw

149:NAME IS NULL
10/10/15 10:19:56
2ヶ月も前の話題を引っ張るなよ。それにしても>>121大人気だな。

150:NAME IS NULL
10/10/15 11:14:08
いまどき一般的な規模のRDBでテーブルの結合がボトルネックになる、なんて書いたらそりゃ人気も出るw

151:NAME IS NULL
10/10/15 21:55:23
>>147
下段って?>>142本人なら解説キボン

152:NAME IS NULL
10/10/25 20:01:40
>>146
元コボラーには有償研修のSQL入門程度は行かせた方が良い。
わずかな投資で使いものにならなかった人材が使えるように
なったらもうけもの。

汎用機ではこうだったからだ、、、
と仕事を妨害することも少なくなれば一石二鳥。

153:NAME IS NULL
10/10/25 21:56:18 G/Enqt3S
COBOLにOCCURS項目があるといのがCOBOLとSQLの相性が悪いところなんでしょうかね… w

それだけではないでしょうけど

154:NAME IS NULL
10/10/25 23:29:57
SQLというより、テーブル定義の問題だがな
COBOLのようなISAM編成に向いたテーブル定義と
RDBを前提としたテーブル定義は違うってことだ

155:NAME IS NULL
10/10/26 22:28:35 BB4To3r1
ある製品を作る時に使用する部品をDB化したい。

[条件]
1つの製品を作る際に使用する部品の種類は、1個~20個以内。
データの出力時には、固定列数なフォーマットにする。
--

こういう場合も正規化ってする?
クロス集計でしか利用されないデータを正規化するのってすごい非効率な気がするんだがどうなんだろう。

[非正規化]
作成No,製品名,部品1個数1,単価1,部品2,個数2,単価2~部品19,個数19,単価19,部品20,個数20,単価20,合計,作成日,コメント

[正規化]
作成No,製品名,合計,作成日,コメント
部品No,作成No,部品,個数,単価

156:NAME IS NULL
10/10/27 00:55:32
>>155
将来、部品点数が絶対に増えないといえるのなら、
非正規化でもいいかもね。

将来、部品点数が増えたり、階層化する可能性があるなら、
正規化しといたほうが、後々潰しが効くと思う。


157:155
10/10/27 11:38:52
>>156
どうもです。

階層化は考慮外ですが、部品点数が増える事に対しても非正規化の方が
工数的(作成時、実行時ともに)に有利だと思うんだけどなー。

テーブルを修正しなくても良いという点では正規化が優れているが、
それほど加点でもなく、マイナス点の方が多く思える。

Gridに表示させたり、CSVなどで出力したりで毎回毎回別途に集計しなければならないのは面倒くさい。
制限チェックも増えるし、取りだしが必ず2度以上になってしまうからレスポンス的にもだいぶ不利だし…。
皆さんどうしているんだろうか。そういう欠点よりも将来の拡張性の為に正規化をしているのかな。

悩む…。
非正規化はテーブルの見た目がださい所も気になる。

158:NAME IS NULL
10/10/27 12:22:13
>>155
非正規化の場合、部品のステータスに修正入ったら一括変更でもするつもりか?
データ構造が変わらない(商品を構成する部品の点数や構成が将来的に変わらない)としても、表示するフロントエンド(アプリ)は色々変わったり、
他の場所で使われることがあるから、素直に正規化しておけ。
非正規化されたデータをもとに他の人間がフロントエンド作るのは非常に面倒くさい。

その程度のクロス集計のコストが高くなるというのは、そもそもの設計か実行時のSQLに問題があるだけ。

159:NAME IS NULL
10/10/27 19:46:30
>>157
>非正規化はテーブルの見た目がださい所も気になる。
開発者の感覚としては、これにつきる。
その程度のテーブルなら、どんな構成
でも実行速度は変わらんだろ。

捨てコードでもいいから突貫で、と
いうのでなければ、個人的に非正規は
ありえない。


160:158
10/10/27 19:54:11
>>157
非難だけしてもなんなので、現実的な方法を。
仮に出力の(クロス集計の)コストが高いというのが問題であるならば、部品構成の変更などが頻繁でない限りは(今回のケースはそうだと思うが)、
部品の変更や修正、追加をトリガーに出力用のデータをテーブルなりファイルなりに吐き出しておけばよい。
最終形でなくても、計算途中のデータを出力しておけば実行速度の問題はなくなるはず。

大手のデジカメの階層化されたPDMで実際にやってる。

161:NAME IS NULL
10/10/27 23:29:07
なんでこうJOIN一発するだけでレスポンスが"だいぶ"悪くなると思う奴がDB設計とかやってるんだろう。

162:NAME IS NULL
10/10/28 00:44:53
つかこれ、かならず部品1~20までを固定で取り扱うというなら
横に1~20まで並べても非正規化だとはいえない気がする....

が、俺なら絶対実テーブルを部品1~20まで繰り返したりしない
部品点数が増えたときに非正規化が工数的に有利だと思う考えが理解できん
毎回別途に集計するのがめんどくさいというのも、いまいち理解できん
ビュー使えよ。最近のDBMSなら>160の言うようなワークテーブル的に
使える実体付きビューを使えるものもあるんだぜ

163:NAME IS NULL
10/10/28 12:46:48 2nX/Ozle
テーブル名を日本語で作るのは駄目かな?

164:NAME IS NULL
10/10/28 20:12:37
出来るけどやめておけと言われるはず。
日本語が入力出来ない状態でメンテナンスするってなった場合、手段が減る。

特別な理由がない限りASCII文字で作って老いた方が無難。

165:NAME IS NULL
10/10/28 20:23:31
どっかで、日本語を推奨してる人を見たことがある。
今はO/Rマッパーやらツールやらがいろいろあり、
テーブル名や項目名を直接タイプすることが少なくなったから、
(日本人しか使わないなら)直感的な日本語のほうがいいとか言ってた。

わりと賛同できるのだが、やっぱ怖いもんは怖いよなぁ。
こんなことで変なリスク抱えたくないわ。

166:NAME IS NULL
10/10/28 21:34:07
>>165
>O/Rマッパーやらツールやらがいろいろあり

色々あるから、むしろ TBL0002345 みたいなテーブル名でも最終的にはさほど困らないと思うんだが。
テーブル名や項目名が直感的に把握できる必要があるものに関してはVIEWなりストアドで作ればいい。

167:NAME IS NULL
10/10/28 23:42:40
>>165
全く賛同できないんだが。
ていうか、何を言ってるんだ?って感じだ。
そんな奴が近くに居たら、ぶちのめしてやりたい。

168:NAME IS NULL
10/10/29 07:29:40
>>167
論理的な意見が聞きたい

169:NAME IS NULL
10/10/29 10:18:23
>>168
>>164
>日本語が入力出来ない状態でメンテナンスするってなった場合、手段が減る。
これとか
charset問題とかだろ


170:167
10/10/29 22:55:31
>>168
OSやらDBやらアプリやらで、文字コードを統一しないと怖くて使えない。
プログラムを組んでいる最中に、いちいち全角入力モードに変える必要がある。
  (絶対に、全角スペースをコードに記述してしまってコンパイルエラーとなる頻度が多くなる)
半角と全角の区別がつき難い。
  (例えば、"1"と"1"はパッと見解らない。)

あと、O/Rマッパーやらツールやらを使うことが出来ない場合のことを考えろ。

171:NAME IS NULL
10/10/30 05:46:07
コンパイルエラーなんて別に構わないだろ。その場で分かるんだから。
怖いのは潜在的なエラーとしてバグを引き起こすこと。しかも数年後とか、改修時に。
後は抽出条件が実は間違っていた、とか。

172:NAME IS NULL
10/11/08 11:58:49 wNBEtH7N
簡単な人材派遣システムを作りたいのですが、空き人材の抽出方法に悩んでいます。

タスクの開始日と終了日、跳び石や繰り返し設定等を組み合わせて検索するには
どうすればいいのか複雑でまとまりません。
単純にタスクを実稼働日の配列として展開し、日付をフラグで
埋めていくほうが明快で良いのかもしれませんが、その場合のデメリットは
あるのでしょうか?

また各人材が稼働日空き日を保持するのと、先に競合タスクを判定して
従事者を除外するのはどちらが一般的なやり方でしょうか?

173:NAME IS NULL
10/11/09 00:22:16
業務で人材派遣システムを覗いたことがある。

人のアサインはアサイン管理テーブルみたいなので運用。
基本はDELETE→INSERT、少しでも期間が被った場合はエラー、
前の予約状況をキャンセルしない限り新しいアサインは不可。

174:NAME IS NULL
10/11/09 10:36:25
管理テーブルでDeleteは乱暴なので、更新日時が最新なものをピックアップでよい。案件確定後なり一定期間後にログとして出力してクリーニング。

175:NAME IS NULL
10/11/10 11:03:03 zzwY8gI+
>期間が被った場合はエラーについては
どう判定するのでしょうか?

新規側が連続日ならば、
新規期間内に既存開始/終了日のいずれかが無いこと、または
(新規開始前に既存開始があり、かつ新規終了後に既存終了後がある)が無いことで、
競合が無い人物の抽出(または競合するタスクに関わる人物の除外)はできますが、
毎週第二火曜日や、平日土日のみなどの隔日予定が混在するとややこしくなります。

日付に従業フラグを立てる場合は新規開始~終了までの日数分ループを回して
一日ごとに競合判定することが考えられますが、せっかく規則性あるのに
200日なら200個データを持つのは実用的なのかスマートでないのか…(柔軟にはなりますが)。

176:NAME IS NULL
10/11/10 17:42:59
bitフラグ判定で言いじゃん
db問い合わせも出来るし何が不満なんだ?

177:NAME IS NULL
10/11/11 10:54:29
給与計算ソフトで「社会保険料等控除後の額」とか
日本語の述語を使いまくった身としては日本語名を支持したい。

文字コードはUnix系では怖いけど.NETならまず心配ないし。

178:NAME IS NULL
10/11/11 12:07:30
.NET言語の変数名なら問題おこさないけど
Oracleの列名で日本語はいろいろ問題あるからなぁ

179:NAME IS NULL
10/11/11 20:08:59
>>155
>[正規化]
>作成No,製品名,合計,作成日,コメント
>部品No,作成No,部品,個数,単価
遅レスだが

[正規化]
T製品:作成No,製品名,合計,作成日,コメント
T使用部品:作成No,部品No,個数
T部品:部品No,部品名,単価

実はこう?
面倒臭いな

180:NAME IS NULL
10/11/11 23:01:04
.NETもLINQが使えないVS2005あたりで開発すると、正規化は諸刃の剣

181:NAME IS NULL
10/11/13 22:34:02
>>178
> Oracleの列名で日本語はいろいろ問題あるからなぁ

なんか定期的にこういうやつ出てくるけど、具体的な「問題」とやらは
書かないんだな (w

182:NAME IS NULL
10/11/14 01:25:17
最初に入った会社のDB設計は、列名日本語でやってたな。
優秀な人はいたけどガラパゴス状態な感じで、
今になって真似しようとは思わないけど、それなりにちゃんと動いてたよ。
Windowsオンリーの環境だったのが良かったのかもしれんけど

183:NAME IS NULL
10/11/14 10:30:25
だから、クローズドの環境なら日本語だろうがドイツ語だろうがハングルだろうがサンスクリットだろうが問題ないんだってばさ。
問題がおきれば随時つぶせばいいだけだし。

環境が頻繁に変わったり、他との連携で様々なドライバ使う可能性があったり、フロントエンドがガンガン増産されるような環境なら、
動作保障内でやるのが定石。

184:NAME IS NULL
10/11/14 13:34:39
それ Oracle の問題じゃねーだろ。

そもそも動作保証云々以前に「環境が頻繁に変わったり、他との連携で
様々なドライバ使う可能性があったり、フロントエンドがガンガン増産
されるような環境なら」日本語なんか使う奴は馬鹿だろ。

185:NAME IS NULL
10/11/14 23:41:47
>>181
文字コードの問題があるだろ。
日本語にしてしまうことで、文字コードがEUCなのかUTF8なのかSJISなのかを気にする必要が出てくるんだよ。

Windowsならまだしも、UNIX上からSQL文を叩くのに日本語入力することなんてありえねぇわ。

186:NAME IS NULL
10/11/15 00:27:52
そんなん今時utfやん。
大体おまえんとこは実機で直接SQLたたいてんの?w

187:NAME IS NULL
10/11/15 08:42:27
>>185
何年前の話をしてるんだ?

188:NAME IS NULL
10/11/16 02:10:00
わかるわかる。ASCIIのDDLもってけばどんな環境の上でも構築できるよねwww

189:NAME IS NULL
10/11/16 10:57:26
試さずに聞くが、NLS_LANG=Japanese_Japan.UTF8でDB作れば
「№」とかを列名に含めても問題起こさないのか?
場合によって""で括る必要があったりなかったりで面倒なんだが・・・

190:NAME IS NULL
10/11/16 19:09:37
何か問題を起こしそうな文字コードなの?

191:NAME IS NULL
10/11/16 20:42:16
>>189
問題ない。



と言われれば信じるのか?w


192:NAME IS NULL
10/11/16 21:32:01
>>191
それ、頭悪いレスの筆頭候補だと思ってる。

193:NAME IS NULL
10/11/17 01:07:34
>>186
OSはUTF8で、DBはSJISの環境が多いだろが。
勿論、実機でSQL文を叩くことが多いね。

194:NAME IS NULL
10/11/20 14:12:23 sSrpbL1f
DBがSJIS

195:NAME IS NULL
10/11/20 14:47:12
OSがUTF8でわざわざDBをSJISにする理由がないだろw
一昔前はOSがEUCでDBがSJISなら結構あったと思うが。

196:NAME IS NULL
10/11/21 22:27:34 4MhMQRH6
得意先別の締日を登録する場合,例えばデータ型をIntとした場合,
月末締めはどのように表現するのがいいのでしょうか?
よく,月末は99として登録するなどのテクニックがありますが,
どのような方法がいいのでしょうか。

197:NAME IS NULL
10/11/22 20:47:59
31でいいと思うんだが

198:NAME IS NULL
10/11/22 21:18:08
31だと末尾を指定したかったのか31日を指定したかったのかが読み取れない

199:NAME IS NULL
10/11/22 21:26:58
31で十分
なんかの時のbitフラグ使用時もちょうどいいしな
99とか今時あるのか?

200:NAME IS NULL
10/11/22 21:30:15
それを区別する要件があるなら違う値にすればいい
俺にはそれを区別する要件は思い浮かばない
31日締めの指定って、2月とか4月とかの締めどうするんだ?

201:NAME IS NULL
10/11/22 22:01:29
>>200
2月や4月の時に32指定だったら末日だとわかる。
31だとユーザや別システムの入力ミスかもしれない。

202:NAME IS NULL
10/11/22 22:08:29
31=月末
入力ミスとかDBでやるならトリガーで見張れよ
基本だろ…

203:NAME IS NULL
10/11/22 22:34:58
>>201
それは入力ミスってるんだから別問題だろ
そんなの救ってやる必要ないと思われる
たまにそういう仕様外の動作をコードでキャッチしようとする奴がいるけど
問題の切り分けができてない

204:NAME IS NULL
10/11/22 22:37:36
>>201
入力ミスって、32でも入力ミスの可能性はあるわけだが?
結局31でも32でも、その月の末日で締めるわけだろ
わざわざ31日締めという、月末締めとは別の状態が必要か?
それを正しく区別する設計というなら、指定日ごと締めと、月ごと(月末)締めの
締め区分みたいなものを別途用意するのが正解だろうな

205:196
10/11/23 22:38:58 wQ8I8TMH
多くのレス有難うございます。31を月末締めとすればいいようですね。

206:NAME IS NULL
10/11/24 00:22:54
>>205
いやー、仕様を確認したほうがいいと思うぞー
そもそも29日締めとかって設定も入るようにする気か?
その場合2月とかどーすんだよw
本当は1日と15日と末しかねーんだろ?
もしくは日付+例外条件とかなってたら日にちで保存はヤバイかもしんないんだぞ
俺が前までいた会社は月の最期の営業日が締め日(技術者向けの)だったぞ
ただし、四半期の月じゃねーときは次の月のはじめの営業日までがセーフ・・・とかそんなんだ
複雑だろ?w

もっと実務について詳しい担当と話合えよw
こーゆーのってディスプレイといくらにらめっこしててもダメだと思うぜ

207:NAME IS NULL
10/11/24 00:39:33
それ、締め日じゃない何かと勘違いしてないか?
セーフとかなんだそれ。

208:NAME IS NULL
10/11/24 05:20:01
仕様を確認した方がいいのは確かにそうだが
>206の話は締め基準日と、稼働日とか絡んだ実際の締日は別ってだけの話だ
今問題にしてるのは、締め基準日が月末の場合にどう保持するってだけの話
そっから実際の締め日をどう算出するかはまた別の話

209:NAME IS NULL
10/11/24 17:56:36
仮に締め日が来月の1日だったときって日付保存ってダメじゃね?って言ってほしいの?

210:NAME IS NULL
10/11/24 18:09:48
>>208
すでに実務として1~31日って指定のが珍しいのに
これを継続して使うのってどうだろ?
よくある締め日と多少の例外ぐらいはサンプル集めたほうがいいと思うね

1日(先月分)、15日(先月16日~今月分)、25日(先月26日~今月25日分)、月末(今月分)

だったら折角1~31日まで入るようにしてあっても大半が無駄なわけじゃん
もうステータスでいいんじゃないの?
ステータスなら第二金曜日とか対応できるよ

211:NAME IS NULL
10/11/24 18:21:48
わかった!varchar型にして末日だったら「末日」って登録すればいいんじゃないかな?

212:NAME IS NULL
10/11/24 18:31:52
もう割り切って、テキストにすれば。


213:NAME IS NULL
10/11/24 19:52:36
>>211
素直が一番ってのは俺の長年のPG経験で学んだこと

214:NAME IS NULL
10/11/24 23:03:51
ある売上が何年何月の第何週に起算されたものか、って言うのをシステム上で
表示して欲しいとか言われて、馬鹿正直に作ったら、
お盆期間は必ず8月の1週めに含む、とか、年末年始は~
とか色々なルールがあって結局全部コードに書いて何とかした。
今も動いてるのかなぁ、あのシステム。

215:196
10/11/24 23:16:33 vMmyFVn7
意外に盛り上がっているので,ちょっと驚いています。

マジレスすると,都度請求なので,単に得意先の締め日がわかればいいだけなので,
あまり複雑には考えていませんでした。確かに,複数の締め日があったり,
締め日が変動するケースもありそうなので,まじめに考えると頭が痛いですね。


216:NAME IS NULL
10/11/24 23:17:29
売り上げの起算日とお盆期間がどう関係あるのかよく分からないや。
今年だったら、8/1-8/7がお盆になるとして、8/3の売り上げはそのまま
8月の第一週に起算されたものなんじゃないの?

217:NAME IS NULL
10/11/24 23:43:33
こういう仕様は日本のSヨの飯のタネだからな。

218:NAME IS NULL
10/11/25 00:59:50
いやだから8/13~15に立った売上は8月第一週換算とかそんな感じ。
8月12日はお盆期間じゃないから第二週換算だけど、とか。

219:NAME IS NULL
10/11/25 02:30:12
あ。
お盆期間を8月1週とする、かと勘違いしてたorz
スマンカッター。

>>217
サマータイムとか旧正月とかあるし日本に限らないような気も。

220:NAME IS NULL
10/11/29 17:50:54
得意先マスタに訪問履歴1、訪問履歴2、訪問履歴3というカラムが。
何がしたいのか聞いてみたら、1回目の訪問時の内容を~、とのこと。
俺「3回以上訪問したら。。。?」
相手「その辺は運用で何とかします。大抵は3回分保持できれば十分ですので。」
だとさ。

221:NAME IS NULL
10/11/29 19:39:04
>>220
なんとでもなるのに何を難しく考えているんだろうな?w
素直に訪問履歴xN回になっても大丈夫なように作ってくれって言えばいいのにw

222:NAME IS NULL
10/11/29 20:59:11
履歴とかいうから全部残さなくていいのおおおお?と思っちまうけど、要は「初回3回までの訪問日時」だろそれ。
最初の数回の挨拶とか紹介だかの日時のメモ書きであって、4回以上は捨てて問題ないってこと。
RDBとしてはうんこだけど実運用考えればそれはそれでありだろう。

223:NAME IS NULL
10/11/29 23:16:49
ほんとにメモ的な情報で良ければそれでもいいのだけど、
あとからとんでもなく重要な情報であることが発覚して、
大改修を迫られることになる。
さらに下請けの悲しさか費用は込みこみで;;

224:NAME IS NULL
10/11/29 23:29:58
大改修よりも運用で何とかしていたものを移行するのが死にそう。
過去データ登録機能を作って客に入れてもらうかw

225:NAME IS NULL
10/12/02 01:57:55
SQL質疑応答スレから誘導されてきました。
スレリンク(db板)

PHP+MySQLなんですが、できるだけDBで処理しようと思っています。

お買い上げに応じて、n%分を顧客にポイントを付与します。
これにはキャンペーンが存在して、水曜と日曜はポイント5倍、
7の付く日(7日、17日、27日)もポイント5倍、1日はポイント10倍などあります。
1日が水曜日の場合は、倍率の大きい、ポイント10倍が適用されます。
また、たとえば、クリスマス期間12月01日から12月26日まではポイント「さらに」1.5倍、三が日は一律10倍などもあります。

こんな感じで、キャンペーンの曜日や期間、パーセンテージを自由に設定できるようにしたいです。
来月からは、水曜はポイント10倍にしよう!なんてのもありえます。

よろしくお願いします。

226:NAME IS NULL
10/12/02 02:14:52
追加です。あんまり関係ないかもしれませんが。
先月の購入金額に応じて顧客にグレードがあり、
1万円以上の購入者は基本ポイントがn+1%、
5万円以上の購入者は基本ポイントがn+2%などとなります。
これもDBに格納させたいです。

227:NAME IS NULL
10/12/02 02:40:04
いや
肝心のなにが聞きたいのかがわからんし

228:NAME IS NULL
10/12/02 03:51:09
どういったテーブルの設計をすれば最適か伺いたかったのですが。。。

229:NAME IS NULL
10/12/02 04:02:27
「倍率が高いほうを優先」と「さらに」の2パターンしかないのかな。

230:NAME IS NULL
10/12/02 04:08:27 QCxu6itD
>>225
せめて誘導元の議論ぐらい貼れよ

656 655 [] 2010/12/01(水) 19:43:16 ID:0WLtPE6T Be:
現状、
・日別キャンペーンテーブル
・曜日別キャンペーンテーブル
・期間キャンペーンテーブル
とバラバラに作って、PHPで処理しています。

1か月分のパーセンテージ一覧を作るのに、1日ごとにSQLを複数実行して
かなり重いので、その辺も簡略化できる設計だと助かります。

657 655 [] 2010/12/01(水) 20:21:55 ID:0WLtPE6T Be:
自己レスだけど、こうゆう場合は
カレンダーテーブル(日付、計算済み%をカラムに持つ)を作ってあげて、
各種キャンペーンテーブルを更新するたびに1か月分とかカレンダーテーブルを更新する設計がいいんだろうか?
それだと、売り上げの度に%を取得するのが1回のSQLで済む。
ただし、時間帯別のキャンペーンが作れない(作りにくい)のと、設定忘れなどで、昔の期間にキャンペーンを設定するのが面倒な点が変わらない。。。

658 NAME IS NULL [sage] 2010/12/01(水) 20:43:49 ID:??? Be:
ビュー作れ

660 NAME IS NULL [sage] 2010/12/01(水) 21:01:28 ID:??? Be:
曜日があるからビューはかなりムリゲーだったわ・・。

1,2,3-31の日付だけ持つダミーテーブルを作って指定月の一ヶ月の一覧を取得するSQLをまず作る。
(SQLは多少メンドクサイが)単純な計算なのでこのまま使っても重いとは思えないが、
もし重ければ>>657の通り、月初なりキャンペーンテーブル更新時なりに別テーブルにinsert ~ select すりゃおk

661 NAME IS NULL [sage] 2010/12/01(水) 22:05:00 ID:??? Be:
キャンペーンごとのテーブルが必要な理由が分からない
カレンダーだけ作ってバッチ更新でいいだろ

663 NAME IS NULL [sage] 2010/12/01(水) 22:10:19 ID:??? Be:
>>661
そのバッチは何テーブルを見て更新するつもりだ?

665 NAME IS NULL [sage] 2010/12/01(水) 22:28:26 ID:??? Be:
>>663
そんな変なキャンペーンルールなんかバッチ側にもてばいい

666 NAME IS NULL [sage] 2010/12/01(水) 22:48:24 ID:??? Be:
>>665
例えばドトールのような不定期なキャンペーンを展開してるシステムとかどうするんだよ間抜け
毎月バッチリリースすんのかよw

667 NAME IS NULL [sage] 2010/12/01(水) 22:55:45 ID:??? Be:
水曜日のパーセンテージ変えようぜってやったら指定日以降の水曜日だけ変わってほしいよねきっと。
今曜日キャンペーンテーブルに期間もたせてるの?ないなら持たせないといけないんだよねぇ。

カレンダー的なメンテナンス画面作るのが楽だと思うなぁ。

668 655 [] 2010/12/02(木) 00:26:41 ID:u5kOJKQ0 Be:
曜日キャンペーンに期間は必要ですねぇ。
いまはまだ付けてないです。
参考にさせていただきます。

それでは、スレ違いだったようなので、別スレにて再度、投稿してきます。

231:NAME IS NULL
10/12/02 04:43:33
それぞれのキャンペーンで、パーセンテージを「5%に置き換え」「3%加算」「n倍にする」といった種類をつけたいです。

キャンペーンで、決算キャンペーン12月は+5%、クリスマス期間は「さらに+5%(計10%)」「10%に置き換え」といったような、
期間が重複する場合も、期間の範囲が広いほうから狭いほうに順に計算したいです。

232:NAME IS NULL
10/12/02 07:16:56
キャンペーンテーブル作って
買い物ごとに適用されたキャンペーンID入れておけばいいだろ
±Xが%なのか○円以上で~なのかは多分ルールが変わるだろうからその辺は
その都度でいいんじゃね?(f(x)の形)

233:NAME IS NULL
10/12/02 16:41:21
複数のキャンペーンが適用される場合は?

234:NAME IS NULL
10/12/02 17:43:45
>>233
>>232に対してのレスだろうか。別途テーブル起こせってことじゃないかと思うんだけど、
そもそもの主眼は適用されるキャンペーンを楽に取得することだからなぁ。

235:NAME IS NULL
10/12/02 18:33:50
別テーブルかぁ。
12月3日になって、「そういえば今月は決算キャンペーンだと発表してたのに、システムの設定忘れてた」
って場合はどうする?


236:NAME IS NULL
10/12/02 18:50:16
いまキャンペーンテーブルは日別、曜日別、期間別の3つに分かれているわけだけど、
これを1つにまとめちゃうスマートなアイディアは無いの?


237:NAME IS NULL
10/12/02 18:53:48
まとめればいいじゃん
開始日付,終了日付,キャンペーンID
そういう~別とかいうのは月次処理でやりゃいい


238:NAME IS NULL
10/12/02 18:55:13
発表した時点でキャンペーン情報を登録しておくべきだよねぇ。

忘れてた時どうするといわれても、どちらかというと別テーブルで保持したほうがバッチつくりやすそうには思うぐらいで、
めんどくさい作業が待ってることには違いないかな。

239:NAME IS NULL
10/12/02 18:56:21
このスレ質問者はIDを出す文化がないのか、とおもったけど質問スレじゃなかったな

240:NAME IS NULL
10/12/02 19:01:35
そもそもDB設計なんざ枯れてるんだから迷う要素なんてないだろ
設計というのも恥ずかしいぐらい簡単

241:NAME IS NULL
10/12/02 19:22:27
簡単すぎて書く気にもならないってレスはまだか?

242:NAME IS NULL
10/12/02 19:23:31
>>233
複数登録できるようにしたらいいんじゃない?っていうしなきゃダメだな
なんのキャンペーンが適用されてこの値段になったのかわからないとか最悪の結果だ
計算によって%だけ出して会計すませりゃいいって問題じゃないだろ
下手したら脱税で訴えられそう

243:NAME IS NULL
10/12/03 00:26:26
売り上げテーブル
+ID
+売り上げ金額
+ポイント額

キャンペーン適用テーブル
+売り上げID
+キャンペーンID

みたいな感じ?


244:NAME IS NULL
10/12/03 01:11:56
しらね
どういうDB作りたいのか詳しく知りたくないからよく読んでない
キャンペーンは確実にその日すべての買い物に適用されるとかなるのか仕様がよくわかってない
タイムサービスとかないんだろか?とか結局なんの統計とりたいの?とかよくわかんねーし
やっぱ、この辺は担当者とお話してちゃんと仕様決めないとね

一般的な~ってないと思うよ

245:NAME IS NULL
10/12/03 02:02:02
え、今日ポイントどれくらいつくの?ってのを取得しやすい設計を知りたいんじゃないの?
俺はそれに応じたレスをいくつかしてはいるんだけれど。

統計とか何の話だろうって思うわ。

246:NAME IS NULL
10/12/03 07:27:23
>>245
追記で購入金額に応じたポイントまであるんだから全売上の詳細まで管理したいような感じもするけどね

247:NAME IS NULL
10/12/03 07:31:51
買い物客ごとにデータを保持しておいたほうがいいね
実運用では商品によってキャンペーン対象外商品がきっとある(でないと転売屋天国になるからな)

まあ、教科書的な答えだけほしいってんならテキトーでいいと思うけどねw

248:NAME IS NULL
10/12/03 09:57:47
キャンペーン複数適用するのに
たとえばAキャンペーンが1000円引き、
Bキャンペーンが1割引だったとしたら
正価から1000円引いてから1割引するのか、
1割引してから1000円引きなのか、とかも考慮する必要あるし
もっと仕様を詰めないといけないんじゃない?
逆に言えば仕様が固まればおのずとDBは決まると思うけど

249:NAME IS NULL
10/12/03 09:59:50
ああ、値引じゃなくてポイントか
まぁ話としては変わらんけど

250:225
10/12/04 02:47:21
>>248
それもPHPコードで決めうちじゃなくて、
計算順をDBに入れて、利用者が設定できるようにしたいですね。

251:225
10/12/04 03:04:53
例えば、キャンペーンにプライオリティカラムをつけて、
その順番に適用していくとか。

252:NAME IS NULL
10/12/04 07:05:44
結局どこで詰まってるんだか。

> 1か月分のパーセンテージ一覧を作るのに、1日ごとにSQLを複数実行して
> かなり重いので、その辺も簡略化できる設計だと助かります。
3テーブルあって、月次バッチ処理をしているとして、1日ごとに実行したとしても、90回の抽出と30回の挿入だよね。
なんでそんなのが重くなるんだ?
DB今のままでちょっとチューニングしたら終わるんでないの。

253:NAME IS NULL
10/12/04 07:58:31
IPアドレスの管理表をおこしたいのですが、IPアドレス毎に、使用者情報、inbound接続ができる
(=開いてる)ポート番号のリストを持たせようと思っています。
使用者情報まではいいのですが、開いてるポート番号の情報はどのように持てばいいでしょうか?

この開いてるポート番号情報は例えば 22,80,443,3024-3054 といった情報になります。
そして、このポート番号情報にからめて「xx番が開いている未使用のアドレス」という検索がで
きるようにしたいと考えています。

扱うIPアドレス数はたかだか1000件も扱えれば充分なのですが、「0-65535(ポート全開)」とい
うアドレスも扱わなければならないので、悩んでいます。

テーブル1(ip_table)
|ID|IPアドレス|使用者情報など|
テーブル2(opned_tcp_port_table)
|ID|ip_table.ID|ポート番号|
と割っておいて、select 時には join してから select する手もありますが、(ポート全開)な
アドレスの扱いがえらいこと(65536行に膨らむ&opned_tcp_port_tableに65536行分入れておか
ないといけない)になりそうで、ここが悩みのポイントです。


254:NAME IS NULL
10/12/04 08:18:26
テーブル2
ID ip_table.ID ポート番号下 ポート番号上
1 1 0 65535
2 2 22 22
3 2 80 80
4 2 3024 3054

select ip_table.ID from テーブル2 where xx between ポート番号下 and ポート番号上

255:NAME IS NULL
10/12/04 09:30:17
>>254
between何てのがあったと!
それをip_tableにjoinすれば使いたいポートが開いてるアドレス一覧が取れると。

ありがとうございました。

256:NAME IS NULL
10/12/04 12:08:16
>>255

開いてる)ポート番号が飛び飛びだったらどうすんの?

257:NAME IS NULL
10/12/04 12:18:45
16ビットで表現できるな。

258:NAME IS NULL
10/12/04 15:10:22
IPアドレスマスタ
IPAddress(PK) , ValidFlag

IPアドレス使用者テーブル
IPAddress(PK),SeqNum(PK),UserAccount,ValidDate,InvalidDate

こんな感じじゃダメなんか


259:NAME IS NULL
10/12/04 19:14:51
給与の締め日と支払い日を管理するDB設計は、どういった形がよいでしょうか?

月ごとに25日締め翌月5日払いとか、
週ごとに締めて、翌水曜日払いとか、
2週ごとに締めて、翌水曜日払いとか。

こういった要件を自由にカスタマイズできるようにしたいです。

260:NAME IS NULL
10/12/04 19:23:23
タイプ:月、週、日
締日
支払日

こんだけ

261:NAME IS NULL
10/12/04 19:25:38
二週ごと、とか無理だろ。
DBでやるのは無理だから、ビジネスロジックでやるもんじゃね?

262:NAME IS NULL
10/12/04 20:02:41
給与の締め日ってどんな感じで色々かわんのかね?
パッケージ向けってつーことかい

263:NAME IS NULL
10/12/04 20:31:05
>>256
偶数番号のみ全開とかは泣ける…

>>258
IPアドレスマスタの ValidFlag はもしかして、65536bitのポート開いてる閉じてるフラグ?


264:NAME IS NULL
10/12/04 20:43:27
>>253
悩むのは6500万件のテーブルが「えらいこと」かどうか確認してからでいいだろ。

265:NAME IS NULL
10/12/04 20:46:42
65536bit・・・ だめだこりゃ。

266:NAME IS NULL
10/12/04 22:41:40
>>255
betweenじゃなくても、
ポート番号下 <= xx and xx <= ポート番号上
で同じことになるよ。

267:NAME IS NULL
10/12/05 08:23:47
>>259
DBに計算式のスクリプトを直接突っ込んでる

268:NAME IS NULL
10/12/06 01:27:26
>>263
ああ、外部公開用WANじゃなくて、クライアントのIPアドレスの話か
ならLANが前提だろからIPアドレスは主キーには出来ないのでFQDN見るしかない
NICの複数差しも考慮しなくちゃいけない

クライアントマシン公開ポートテーブル
FQDN(PK),NicNum(PK),SeqNum(PK),IPAddress,Protocol,StartPortNum,EndPortNum

ユーザーは別テーブルでFQDNと紐付けて、ポートの重複とか論理整合はストアドで取ればいいんじゃね?


269:NAME IS NULL
10/12/06 02:57:25
なんだこの展開

270:NAME IS NULL
10/12/06 10:05:28
しばらく見てなかったらえらい複雑な展開になっているみたいで申し訳ない。
後出しで申し訳ないんだけど、やりたいアプリは/24程度のFWの裏にいるグロー
バルアドレス持ちなネットワークのアドレス管理なのですよ。
FWでアドレス毎にinboundの接続設定が異なっているので、それの管理用アプ
リに、と思った次第。
基本 アドレス、利用者、開いてるポート番号 の要素を管理しておきたくて、
このネットワークの利用者からは「××番が開いてるアドレスなーい?」とか
「全開のアドレス空いてない?」いう問い合わせが多いので、ポートの状況で
検索というのが要件に挙がったと。

ここまででいくつかアイデア頂いてるので、それぞれ試作して検討してみます。
なので一旦closeということで。

271:NAME IS NULL
10/12/24 18:04:55 CmCii1Ay
誘導されました

記事が著者、カテゴリ、タグとそれぞれ多対多の関係になる場合次のどっちが使いやすい、パフォーマンスがいい、ですか(検索など)?
記事の分類が増えることはなく、著者はただの分類でログイン等は持ちません。

記事: id, body
著者: id, name
カテゴリ: id, name
タグ:id, name
著者関係: 著者id, 記事id
カテゴリ関係: カテゴリid, 記事id
タグ関係: タグid, 記事id

記事: id, body
taxo: id, name, type
taxo関係: taxoid, 記事id
※taxo.typeは著者、カテゴリ、タグのいずれか
スレリンク(db板:888-889番)

272:NAME IS NULL
10/12/24 23:16:31
>>271
前者じゃないかな。あと、気持ちの問題だけど、記事idを先頭に持って行きたい

273:NAME IS NULL
10/12/26 07:58:53
個人的にば、一つの事象を一つのエンティティとして切り出すほうが好きなので、前者で作って、
著者名、カテゴリ名、タグ名から透過的に検索するために、taxo関係をビューにするかな。

274:271
10/12/26 15:36:39 xB/ukp6t
>>272-273
ありがとうございます。

> taxo関係をビューにするかな。
これのやり方がわからないんで教えてもらっていいですか?

275:NAME IS NULL
10/12/26 15:56:32
>>274
単にJOINしたSQLをビューにしておくっていう意味以上のものはないと思うぞ

276:NAME IS NULL
10/12/26 15:58:15
あ、つまり↑の作りの場合のデメリットはテーブルが増えすぎてわけわかんなくなるかも、ってことだから
ビューをあらかじめ作っておこうという嗅覚が働いたという話かと。

277:271
10/12/26 16:11:28
テーブル数は気にならないのでとりあえず上で行って見ます。
ありがとうございました。

278:NAME IS NULL
10/12/29 19:53:07 7r5KYmdf
テーブルAのある列の値がXのときだけ、テーブルBに対応するレコードが存在する。X以外では存在しない、
っていう制約がある場合、アプリ側だけで制御してる?トリガーとかでDB側でも制御してる?

279:NAME IS NULL
10/12/29 21:56:30
>>278
その制約が破られたときの金銭的損失、瑕疵として損害賠償請求されたときの想定金額次第

280:NAME IS NULL
10/12/30 04:15:29
>>278
俺的にはDB側にあんまり制約つけるの好きじゃないんだが
そのDBが一つのアプリ(システム)からしか利用されないならそのアプリで制御する
複数のシステムで共有されるようなDBなら、DB側になんらかの制御を入れる
ぐらいの基準かな

281:NAME IS NULL
10/12/30 09:39:51
あるDBが複数のアプリから利用された場合を想定して、DB側でも制御、だなぁ。
とあるシステムで、顧客情報をWebアプリからも登録されるし、
オフラインのFaxやハガキからも登録される、っていうシステム見たんだけど、
オンラインからはメールアドレス必須なのに、Faxなんかには入ってなくって、
オンライン側でバグる、みたいなことが立て続けに発生してた。

282:NAME IS NULL
10/12/30 11:07:18
個人的には仕様書がないときにバイナリしか残ってないアプリからじゃなにも分からないけど、
DB側に実装しておいてもらえれば、最悪でも仕様だけは知ることが出来るからDB側で実装してほしい。

283:NAME IS NULL
10/12/30 13:24:19
新任の後任者が仕様変更で一方のロジックしか直さず
顧客をブチ切れさせるのが通過儀礼となる図

284:NAME IS NULL
10/12/30 13:27:35
そもそもそんな設計が悪い、とか言い出す奴がそろそろ登場する悪寒。

285:NAME IS NULL
11/01/01 06:48:29 ZTfqWojz
・ユーザ情報テーブル(画像1枚)
・店舗情報テーブル(画像複数)

上のような複数のテーブルに、
それぞれアップロードされた画像の情報を持ちたいんですが、どうするのが一般的/スマートでしょうか。
それぞれ画像が1枚だけなら、そのテーブル自体に画像情報フィールドでもつくればいいのですが、
複数の場合があるので悩んでいます。

自分で思いついたのは、
・画像情報テーブル
を作って
そのテーブルに
foreign_id INT UNSIGNED /* 外部キー */
forein_type enum('user', 'shop') /* どのテーブルの外部キーかの値 */
てな感じで、外部キーをもたせつつ、その外部キーがどのテーブルのものかを判断する値も持たせれば
良いかなと思ったのですが、
もっと良い方法ありますか?


286:NAME IS NULL
11/01/01 10:29:45
>>285
・ユーザ画像テーブル
・店舗画像テーブル
をもっちゃいけないの?
画像テーブル一つにまとめて画像データすべてに対してなんらかの処理をしたいなら
一つにまとめるのもアリだと思うけど・・・
普通はint情報テーブルとかもたないよねw・・・

287:NAME IS NULL
11/01/01 11:30:36 ZTfqWojz
>>286
それだと、今後別のテーブルにまた画像が必要なときにまた画像テーブルをつくるはめになるので、、、
1つのテーブルに画像情報がまとまっていれば、
そのテーブルに対するモデルさえあれば、
今後どんなテーブルに画像が必要になっても対応できるので、
なるべく1つのテーブルで管理したいんですよね

288:NAME IS NULL
11/01/01 11:48:57
画像情報テーブルにユニークなキーがあれば、
それがユーザーのものか店舗のものかは気にしなくていいんじゃない?

何のために、どのテーブルのものかを判断するの?

289:NAME IS NULL
11/01/01 12:05:43 ZTfqWojz
>>288
例えば店舗情報を表示するページで店舗画像を取ってくるわけですが、
画像テーブルの外部キーが店舗のIDなのか、ユーザのIDなのかがわからないためです

290:NAME IS NULL
11/01/01 12:21:08
ダメだこりゃ。

291:NAME IS NULL
11/01/01 15:40:51
その「画像データ本人」が自分が店舗画像下ユーザ画像なのかを知ってる必要はないよね。

292:NAME IS NULL
11/01/01 18:42:11 ZTfqWojz
>>291
すいません、完全に理解できないです・・・。申し訳ない。

画像データが店舗のものかユーザのものか判断するのは
どのテーブルのフィールドが担うんでしょうか?
画像が必要なテーブルに、
画像IDを外部キーとして保持するとしても、
複数画像に対応できない気がしますが、認識が間違ってますか??

293:NAME IS NULL
11/01/01 19:00:55
・画像情報関連テーブル
ユーザか店舗のキー 画像のキー

これでなんか問題あるの?

294:NAME IS NULL
11/01/01 19:04:06
>>292
画像がユーザーあるいは店舗に従属するのであれば、ユーザーと店舗の
テーブルを分けた時点で画像の方も分けなければならない。
どうしても画像テーブルを一つにしたいのであれば、手としては2つある。
・ユーザー・店舗の共通エンティティを用意する
→ただし、ユーザー画像は常に1つ、店舗画像は複数可、などは表現できない
・ユーザー―画像、店舗―画像という連関エンティティを別に用意する。
→場合によっては素直にユーザー画像テーブル、店舗画像テーブルの方が簡単

295:NAME IS NULL
11/01/01 21:28:19 ZTfqWojz
>>293
店舗とユーザのIDは別テーブルなので重複する可能性がありますね。わかりづらくてすいません

>>294
> 画像がユーザーあるいは店舗に従属するのであれば、ユーザーと店舗の
> テーブルを分けた時点で画像の方も分けなければならない。
うーんやはりそうかぁ。
素直に
・ユーザ画像テーブル
・店舗画像テーブル
を作ろうかな。

ありがとうございました。

296:NAME IS NULL
11/01/01 21:36:49
店舗とユーザのどっちかを判別できるキーにすりゃいいだけだろ
アプリ側からしたらユーザか店舗かはJOIN時に分かりきってるんだから
解決したならもういいけどさ

297:NAME IS NULL
11/01/02 13:20:56
>>295
教科書的な作り方なら

・ユーザ&画像関連テーブル(ユーザ識別+画像ID)
・店舗&画像関連テーブル(店舗識別+画像ID)

・画像テーブル

の3つが必要

298:NAME IS NULL
11/01/03 04:07:50 5FnD8U9u
>>297
あ~こっちのほうがいいですね。
これでいきます!
どうもです

299:NAME IS NULL
11/01/08 17:11:01
今Excelに以下のような形でデータを保存しています

A列 保存場所 e.g F:\data\~\~
B列 ファイル名 e.g [xxxx] dddddd.doc
C列 作者名 B列ファイル名のxxxxの部分
D列 タイトル名 B列ファイル名のdddddd.docの部分
E列~G列 ジャンル D列の作品がどういうジャンルに属しているか
H列 コメント

E列~G列のジャンルについては現在最大3つ(別にそれに縛られる必要はないのですが)で、最低限1つは必ずあります。
H列についてはあれば記載

で、勉強も兼ねてテーブル化しようと思っているのですが。

作者テーブル
作者名
読み
ジャンルテーブル
ジャンル
は思いついたのですが、
メインのデータテーブルはどのように持てば?という事で
教えていただけたら m(_ _)m
※データテーブルにはファイルをバイナリで入れる事はせずA列の保存場所を
持っていれば良いと思っています



300:NAME IS NULL
11/01/08 17:17:20
メインは↓みたいな感じでいいんじゃね?

ID、タイトル名、保存場所、ファイル名、作者ID、ジャンルID、コメント

301:299
11/01/08 19:59:44
有難うございます
まぁそういう形になるのかなぁと。
それで試しに作ってみます。


302:NAME IS NULL
11/01/09 09:23:28
・ひとつの「タイトル」は、3つ(?)の「ジャンル」を持つ
・ひとつの「ファイル」に、「タイトル」はひとつ
・ひとつの「タイトル」で、複数の「ファイル」がある
・「タイトル」が同じでも、別のファイルなら、作者名、コメントは別?

タイトル { タイトルID, タイトル名 }
ファイル { ファイルID, タイトルID, 保存場所, ファイル名, 作者ID, コメント }
タイトルジャンル { タイトルID, ジャンルID }

303:299
11/01/09 10:28:16
・ひとつの「タイトル」は、3つ(?)の「ジャンル」を持つ
現在はジャンルを3つにしていますが、3つに限定しないといけない理由は
ないです。ただ最低限1つはかならず持つという事で

・ひとつの「ファイル」に、「タイトル」はひとつ
  タイトルは1つです

・ひとつの「タイトル」で、複数の「ファイル」がある
・「タイトル」が同じでも、別のファイルなら、作者名、コメントは別?

 複数の作者で同じタイトルという可能性はあります。ただしその場合
ファイルは別々ですが。



304:NAME IS NULL
11/01/11 17:00:09 3vuTbP2k
すんごい基本的な事なんだけど、毎回悩む。
たとえば、男、女 の様なマスターが欲しいとき、IDはふった方が良いんですかね?

男、女 をそのままデータテーブルで保存するようにしても欠点が分からない。
容量の削減にはなるとは思うが、クエリなどでわざわざマスターからリンクしなくてもよい
という利点もあるし。

ただ、マスターテーブルが不恰好な気がするが…。


うーん、、


305:NAME IS NULL
11/01/11 17:06:04
最近は性別も更新される可能性のある属性ですwww

306:NAME IS NULL
11/01/11 18:10:31
マスターの方を変えたらジェンダーフリーすぎだろw

307:NAME IS NULL
11/01/11 18:16:12
性別欄が必須でないデータってのもよくある話で、
男性、女性、中性、(未選択)
くらいはあってもよい気がする。

308:NAME IS NULL
11/01/11 18:20:43
JISで性別のコードって規定されてなかったか

309:NAME IS NULL
11/01/11 19:23:54
男 男性 M Male のように表現がいろいろあるから残念な気持ちになりつつ、男と女の2レコードを作っておくといいんじゃないかな

310:NAME IS NULL
11/01/11 23:41:02
>>304
どっちでもいいんじゃない?
プログラム組んでてもそういう問題ってあるじゃない

311:NAME IS NULL
11/01/12 10:09:47
>>304
自分の個人的な判断基準は、その値が表示するだけ(帳票に出ればいいだけ)なのか、検索やグルーピングで使うかかな。
後者なら一応IDにしておく。

312:NAME IS NULL
11/01/12 23:24:06
二つだから気になるんだ
オカマとオナベもつけておけば気にならない

313:NAME IS NULL
11/01/12 23:55:36
>>308
JISは廃止された(はず)だけど、ISO/IEC 5218:2004 はまだ生きてるかな。

314:NAME IS NULL
11/01/13 15:55:10
外部テーブルにすれば外部キー制約が使えるが生データだと使えない
検索はインデックス張っておけばIDもvarcharも大差ない。

315:NAME IS NULL
11/01/13 17:26:19
キー=データになるんだから外部キー制約は使えるんじゃないか?

316:NAME IS NULL
11/01/14 03:55:41
>>314
チェック制約じゃまずいの?

317:NAME IS NULL
11/01/14 08:43:52
MySQLはCHECKねえじゃん

318:NAME IS NULL
11/01/14 11:53:52
MySQL前提だったとは。

319:NAME IS NULL
11/01/15 12:11:14
標準はティムポウェアだよ

320:NAME IS NULL
11/02/09 06:46:45
目指してる 未来が違うwwwwww byシャープ
URLリンク(twitter.com) 

321:NAME IS NULL
11/02/15 06:01:04
使用DBはOracleです。

■生徒テーブル
1.生徒NO→表の中で一意かつnullを許さない
2.クラスNO→nullを許さない
3.出席番号→クラス内で一意かつnullを許さない
4.生徒名→nullを許さない

1番にはPK、2,4番にはnot null制約をつければいいとして
3番はどうすれば良いのでしょうか?

322:321
11/02/15 06:08:14
解決策として、「クラスNO」と「出席番号」を結合した「クラス別出席番号」という列を作り
ユニーク制約を付けようと思ってます。

もう少しスマートな方法があれば教えてください。

323:NAME IS NULL
11/02/15 06:10:40
check制約でもいいと思うけどね

324:NAME IS NULL
11/02/15 06:42:00
>>323
チェック制約だと他の列を参照することはできても、他の行を参照することはできないので
要件を満たせないんじゃないですか?

325:NAME IS NULL
11/02/15 07:07:42
普通にout_of_line_constraintでunique制約つければいい

326:NAME IS NULL
11/02/15 08:35:30
>>325
ユニーク制約は複数列指定できたんですね。
1番スマートな方法ですね。
ありがとうございます。

327:デフォルトの名無しさん
11/02/19 16:24:44 rzbDbHjB
汎用マスタとか名称マスタとか呼ばれてるごった煮管理なOTLTなテーブルって
いまだに現役?


328:NAME IS NULL
11/02/19 16:45:15
現役のところ知っているけど
聞いてどうするの?

329:デフォルトの名無しさん
11/02/20 13:11:42.68
その手のマスタにもサロゲートキーをつけて、
ジャーナルデータにはサロゲートキーを埋める形にするべきなのか迷ったので。
あと、適用期間をもって世代管理をしているマスタで親子関係があった場合、
子側のマスタには親のコードを要素として持つべきか否かで迷ってる。


330:NAME IS NULL
11/02/20 14:15:42.10
サロゲートキーを使っている現場に出くわしたことない。
サロゲートキーを使おうとしていた現場はあったけど、
キーマンの一言「意味わからん」でお蔵になった。

331:NAME IS NULL
11/02/21 16:11:30.78
だいたいどのページ見ても、総合的に見てサロゲートキーは良いみたいに書いてあるけど
実際はそこまでサロゲートキーを使ってるところが多くないのはなんでだ?

332:NAME IS NULL
11/02/21 22:04:24.48
この間は複合キーの方が自然だからって押し切られたな。
変更に強い->そんな変更はあり得ない。あったらどうせ大改修だから意味がない。
ORMで楽->フレームワーク側の都合で設計するのは如何なものか。

333:NAME IS NULL
11/02/21 22:11:50.75
実際なくてもいい類のものだからな。冗長になることで面倒事も増えたりするし。
流行とか嗜好、メンバーのレベルで臨機応変に変えて問題ないものだから、
その押し切ったリーダーや「意味わからん」つったキーマンが無能というわけではない。

334:NAME IS NULL
11/02/21 22:55:57.34
>>331
設計上不自然な値がキーになってしまうから直感的に避けられてる

335:NAME IS NULL
11/02/21 23:43:07.58
>>332
そこは説明のしかた次第なんだろうけど、条件をつけずに「変更に強い」とか、
あたかも万能みたいに言ったらそりゃ眉唾で見られるだろうな。

336:NAME IS NULL
11/02/21 23:52:10.02
>>334
なんか気持ち悪い・・・ってやつか。

webや書籍で、サロゲートキーについて触れてるのないかな?
具体的にテーブルの定義情報がいくつかあって
どこがどうゆうふうに変更された場合、サロゲートキー使ってる場合は
こうゆう手順で改修ができる。

複合PKを使ってる場合は、こうゆう手順で改修を行う必要があるみたいな
具体的な作業内容が見たい。
できれば筆者の経験談を元に書いてるのがいいな。

337:NAME IS NULL
11/02/22 00:24:45.79
SQLアタマアカデミー:第3回 テーブル設計のグレーゾーン~毒と薬は紙一重 (4)サロゲートキーVSナチュラルキー|gihyo.jp … 技術評論社
URLリンク(gihyo.jp)


338:NAME IS NULL
11/02/22 00:51:45.64
サロゲートキーと何でも一括りにするのって良くないと思うんだ。
人工キーを導入するにしても場面場面でその理由は異なるはずで、
そこを個別の事例ごとにきちんと区別して捉えないと、何でも
サロゲートキーマンセーとかいう困ったちゃんが出てくる。

改修に強くするためという理由でサロゲートキーを導入するのは
元々のデータモデルに時間不変な一意キーが無かったからだよね。
この場合サロゲートキーとはいっても元のデータモデルに修正を
入れているし、下手すりゃビジネスフローのところまで戻って
考え直した方が良いのかもしれない。
でも例えばパフォーマンス等の理由で複合キーを回避するために
使うという場合はサロゲートキーを導入するとはいえ、やりたい
こと自体は元のデータモデルと等価なことだよね。この場合既に
正規化されたスキーマに新たにキーを追加することで大抵は
第三正規形が崩れる。そこを意識して制約とかを加えないと後で
ハまる。

流行とかじゃなくて、ケースバイケースで丁寧に検討する必要が
あると思う。

339:NAME IS NULL
11/02/22 15:36:28.74
>>337
なぜか図11では開始時点と終了時点のカラムの値が編集されていないが
これだと商品ID001で検索すると2つhitして
一応代理キーの値が大きいほど新しいということである程度わかるが
いつからいつまで001がガムテープだったのかがわからんよね。

さらにこのサロゲートキーの使い方だと、商品IDにユニーク制約付けられないから
アプリでミスったらどうにもならなくなるな。
怖すぎるんだが。

おれんとこは、得意先の合併とかで、得意先マスタの得意先NOの使い回しが行われるような場合に備えて
トランザクションのデータを作った時の名称も同時にトランザクションのテーブルに埋め込んじゃうんだが。
サロゲートキーも使ってない。

■受注明細
商品NO
商品名称
得意先NO
得意先名称
日時

上記のようなテーブルにしといて、検収まで終わった「過去」の受注明細を「参照」するときは
テーブルを結合せずに得意先名称をひっぱってきたりする。
不細工な形だが、わかりやすいんだ・・・

340:NAME IS NULL
11/02/22 16:12:26.97
履歴的なテーブルならまぁそういうやり方のとこが多いんだろうね
過去に遡って洗い替えとかあると死ねるけど


341:NAME IS NULL
11/02/22 18:41:41.93
ちなみに商品IDの付け替えってありなの?
なにかと面倒だし、大した手間でもないから必ず新しいの作ってもらったほうがいいと思うんだが。

得意先は合併とかあるからお客さんの要望次第って感じだが。

342:NAME IS NULL
11/02/22 20:54:07.27
顧客要望によってはないこともない
正確には商品IDじゃなくて商品コードの付け替えだがな

343:NAME IS NULL
11/02/22 21:13:38.22
コードの桁数が3桁固定とか決まってる場合はどっかでリセットする仕様な場合はあるね。
ただ3桁のみがキーになることも滅多にないと思うが。

344:NAME IS NULL
11/02/23 04:06:56.64
DBは初心者です
テーブルA,Bの関連が1:1?または1:N*なテーブルは、相手が存在しない可能性もあるので
1.AとBに主キーを設定し、テーブルCにAとBの関連を入れる
2.Bの主キーをAの外部キーとして持たせ、Aの外部キーにnull値を許容する
のとどちらが良いと思いますか?

また、他のケースについて、今のところ
1:N*の場合は1を選択
1:1の場合と1:N+の場合は2.でnullを許容しない
N*:N*やN*:N+、N+:N+はA,Bどちら側からも検索する可能性があるなら1のみ(にこ動のタグとか)
そうでないなら検索する可能性がある項目を持つ側に外部キーを持たせる設計も検討する
という指針を考えてるのですが、大丈夫でしょうか
速度よりも修正容易性を重視したほうがよさそうな環境なので、基本サロゲートキーを付けてます

345:NAME IS NULL
11/02/23 05:47:09.64
どういうことだ?

346:NAME IS NULL
11/02/23 06:29:33.66
>>344
テーブルA,Bの関連が 1..N(Nは0以上) の基本を以下に書くよ。

o テーブルAに主キーを設定し、テーブルBには(テーブルAを参照する)外部キーを設定する。
o テーブルBに主キーが必要か否かは、エンティティA無しにエンティティBが存在しうるか否かで決める。

テーブルBの外部キーとしてNULL値を許容するとか、関連テーブルが必要かとかを検討する必要があるのは、
エンティティAも存在しないこともあるという関連 M:N(M,Nとも0以上) の場合だけだよん。


347:NAME IS NULL
11/02/23 14:48:31.30
テーブル名やカラム名にマルチバイトの文字って使う?
とんでもなく長いsqlとか書いてるとわけわかんなくなるから、マルチバイト使いたいような気もするし
もしかしたら今後のアップデートとかでマルチバイトが祟ってエラー吐くかもしれないから
あんまりマルチバイトを使いたくないって気持ちもある。

カラム名はシングルバイトでコメントの部分だけにマルチバイトってありかな?
これなら多少ましにはなると思うんだが、中途半端感が否めない。

348:NAME IS NULL
11/02/23 16:39:26.64
オラクルだと結構日本語テーブル日本語カラム見かける気がする

349:NAME IS NULL
11/02/23 19:20:11.70
客先でコンソールでデータとろうとしたときに詰むのが怖すぎる

350:NAME IS NULL
11/02/23 19:23:18.26
確かにリモートでつなげないような環境でデータを見る可能性があるならシングルバイトのほうが良さそうだね。
俺んとこはそうゆう事は一切ないから気づかなかった。

351:NAME IS NULL
11/02/23 19:37:11.95 iyykSQn2
以前働いていてたとこ、DB名、テーブル名からカラム名まで全て日本語 w


352:NAME IS NULL
11/02/23 19:50:08.25
>>351
それで具体的に何が困ったかkwsk

353:NAME IS NULL
11/02/24 02:03:54.85
最近の自動生成系の機能がついたIDEなんかだと日本語変数名にもつながっていくので
規約で変数名にマルチバイト文字使っちゃダメとかやると面倒くさい。
逆に積極的にマルチバイトを使うように決めてしまえばあるいは。

354:NAME IS NULL
11/02/24 02:14:58.82
MySQLの公式ツールが落ちるからマルチバイトは使わないなぁ
コメントの日本語だけで詰むw

supplier.id ほげ.仕入れid hoge.siireid
こんなDB見た事がある

355:NAME IS NULL
11/02/24 03:46:34.08
>>354
MySQLってそんなにマルチバイトに弱いの?

一昔前までは、世界的なシェアで見ると、MySQL>PostgreSQLだが
日本ではMySQL<PostgreSQLだった。
PostgreSQLに比べてMySQLは、最初のころはマルチバイトに弱いとかで人気が出なかったが
だんだんそのへんが良くなって来てるから、PostgreSQLとトントンくらいのシェアになってるとか
どこかで読んだ気がするんだが。

公式ツールで扱えないんじゃMySQLではマルチバイトでカラム名を付けるなんてことは考えられないなw

356:NAME IS NULL
11/02/24 07:27:19.12
トントンくらいになったが、PostgreSQLの改善速度がかなり早く、MySQLはまた引き離されてしまった印象。

357:NAME IS NULL
11/02/24 12:17:16.70
>>354
公式っても、GUIツールだろ。
そりゃあしかたない。

他は全然安定してるから問題ない。
あんまり。


358:NAME IS NULL
11/02/24 12:43:23.84
サポートされてる機能を使っちゃいけないってのもおかしな話だしな

359:NAME IS NULL
11/02/24 16:58:43.49
>>357
仕方なくないだろ。
あきらかにマルチバイトは軽く扱われてるじゃん。

OracleやSQLServerですら稀に問題が起こるのに
MySQLで問題が起こらないとは到底思えないな。

360:NAME IS NULL
11/02/24 18:31:35.55
マルチバイトのテーブル名だの、項目名だの欲しがるのは、開発側じゃなくて大抵客。
だから、マルチバイトにしたビューを用意すればいいだけ

361:NAME IS NULL
11/02/24 22:29:28.02
Oracleだとマルチバイトのカラム名は""で括らないと動かん場合がある

362:NAME IS NULL
11/02/24 23:14:03.56
>>361
Oracleで""で括ってないって理由で動かないSQLを1度だけ見たことがある。

SQLServerは""で括らなくても問題ないの?

363:NAME IS NULL
11/02/25 23:38:18.25
>>346
ありがとうございます。

>o テーブルAに主キーを設定し、テーブルBには(テーブルAを参照する)外部キーを設定する。
なるほど、これが一番良さそうです

>o テーブルBに主キーが必要か否かは、エンティティA無しにエンティティBが存在しうるか否かで決める。
主キーについてまだ理解が足りてなかったみたいです
では、DB設計時は1:NやN:Nといった関連と、
単体で存在しうるか、という軸でも整理しておく必要があるってことですね
今作っているテーブルの該当部分は親子関係(子がない場合もあり、子単体は存在しない)なので
親への外部キーのみ設定して、子の主キーは設定しなくても良さそうです

364:NAME IS NULL
11/02/26 02:25:39.36
>>346, 363

訳が分からない。

> テーブルBに主キーが必要か否かは、エンティティA無しに
> エンティティBが存在しうるか否かで決める

なんでテーブルBに主キーが無くて良いことがあり得るの?

> 親への外部キーのみ設定して、子の主キーは設定しなくても
> 良さそうです

子の主キーも設定する。親への外部キーはNOT NULLで参照する。
そんだけ。あと初心者は気軽にNULL使わない。三値論理を理解して、
その面倒くささを理解してから使うこと。

365:NAME IS NULL
11/02/26 10:04:45.13
>>364
>なんでテーブルBに主キーが無くて良いことがあり得るの?

>>346で書いたように「A無しにBが(単体で)存在しえない」場合があるから。
具体的には、エンティティAの属性(attribute)としてテーブルBを表現するケース。

より抽象的に(モデル分析的視点で)、トップダウンな考え方を以下に説明する。

あるエンティティAが存在し、そのエンティティAは複数の属性を持つ。ここで各属性について、
(1) エンティティAがその属性を「ただ一つだけ(only one)」持つのなら、
 その属性をテーブルAのカラム(フィールド)として表現する。
(2) エンティティAがその属性を「いくつか(zero or more)」持つのなら、
 その属性をテーブルBとして表現し、テーブルBには(テーブルAを参照する)外部キーを設定する。
(3) エンティティAがその属性を「たかだか一つ(zero or one)」持つのなら、
 その属性をテーブルBとして表現し、テーブルBには(テーブルAを参照する)外部キーを設定し、
 更にその外部キーにはUNIQUE制約を設定する。

いずれの場合でも、テーブルBは「(単体で存在しうる)エンティティを表現」しているのではなく、
エンティティAが持つ「属性を表現」しているのだから、テーブルBに主キーは必要無い。

366:NAME IS NULL
11/02/26 10:16:03.18
>>365
BがAに依存する属性だったとしても、Bに主キーがなければ
その属性を一意に特定することができないってことだろ?
「主キー」の意味するところが違う?

367:NAME IS NULL
11/02/26 10:56:57.58
>>366
テーブルBの個々の行(ロウ)を一意に特定する必要があるのなら、
そのテーブルBは(属性ではなく)エンティティを表現していることになる。
もしテーブルBでエンティティを表現したいのであれば、当然のことながら
テーブルBに主キーは必要になるよ。

368:NAME IS NULL
11/02/26 11:18:19.70
複数存在するのに一意に特定する必要のない属性って、想像しにくいんだが。
それってたとえばどんなもの?
もしかして、BのエンティティキーをAと独立に持つかどうかという話じゃないのか?

369:NAME IS NULL
11/02/26 12:04:19.62
>>368
想像しにくいというのが理解しがたいのだけれど、要望とあれば。
たとえばエンティティAが楽曲や書籍のような著作物であるとする。
この場合、作者(作曲家/作詞家/著者/原作者/翻訳者..etc)は属性であり、
ある著作物に複数の作者が関わることがあるから、複数の属性になる。

370:NAME IS NULL
11/02/26 12:23:57.65
いや、問題は「一意に特定する必要がない」ということの方なんだが。
作曲家と作詞家、あるいは作曲家が2人いてもそれらは個々に特定
できなきゃならんのが普通だろ。
主キーを持たないということは、仮に同じ曲に同姓同名の作曲家が
2人いたとして、それを区別する術がないということだ。

371:NAME IS NULL
11/02/26 12:32:11.67
>>370
>それらは個々に特定できなきゃならんのが普通だろ。

特定する/しないという判断は、与えられた問題(要求仕様)によって変わる。
「普通だろ」というのは設計者の勝手な意図(思いつき)にすぎない。
もしも特定しなくてもいいという問題であるのもかかわらず一意性を作り込んだのなら、
それは過剰な設計(設計ミス)ということになる。

372:371
11/02/26 12:35:49.91
>>371を一部訂正する。

X: もしも特定しなくてもいいという問題であるのもかかわらず
O: もしも特定しないという問題であるのもかかわらず

373:NAME IS NULL
11/02/26 12:40:50.21
別に本人が必要ないと思ってるんならいいんじゃない?
こんな頭の固いやつにいくら言っても無駄。宗教と同じ

374:NAME IS NULL
11/02/26 12:48:42.38
あらゆるテーブルには主キーが存在しなければならないという考え方が、「頭の固い」発想だと思う。
どちらにせよ、人格攻撃に走ることしかできないのなら、漏れは議論から降りるよ。

375:NAME IS NULL
11/02/26 12:53:18.72
だからさ、そんなもの見たことがないからどんな例があるか聞いてみたんだが?
RDBでは主キーがないテーブルも許されるが、設計論としてはリレーショナル
モデルにおいて主キーがないなんてことはありえないし。

376:NAME IS NULL
11/02/26 13:02:13.25
>>371
ん?しかし>>346では「エンティティA無しにエンティティBが存在しうるか否かで決める」と言っているが?

377:NAME IS NULL
11/02/26 18:27:05.81
あまり読んでないけど、
AなしにBが存在し得ない状況では外部キーが主キーと同じ意味を成すといいたいのかな。
そんなことないけど。

378:NAME IS NULL
11/02/26 19:18:11.77
>>375
>だからさ、そんなもの見たことがないからどんな例があるか聞いてみたんだが?

重複を許す(=一意性を保証しない)属性テーブルというのは、普通に存在するよ。
なるべく分かりやすい例を挙げたつもりだし、重複の可否(=一意性の保証/無保証)を決めるのは、
DB設計者ではなく与えられた問題(要求仕様、つまり顧客)であることも書いた。
ここまで説明してもなお、自分は見たことが無い/経験した事が無いので想像がつかないと
言われたら、自分としてはショボーンとするしかない。

>RDBでは主キーがないテーブルも許されるが、設計論としてはリレーショナル
>モデルにおいて主キーがないなんてことはありえないし。

まず、関係論理/関係代数の世界においては、タプルに一意性が存在することを仮定しているから、
タプルの重複はありえない。ただし、残念ながらリレーショナルモデルというのは、
タプルの重複を許す多重集合(マルチセットまたはバッグ)なんだ。だからタプルの重複はありえるし、
従って一意性は必ずしも保証されない。必要であれば明示的な一意性制約の宣言が必要になる。

次に、RDB実装における主キー(プライマリキー)と、リレーショナルモデルにおける主キー
(行の一意性を保証する候補キーの集合)とを混同して理解しているように見える。

379:NAME IS NULL
11/02/26 19:24:09.00
>>378の続き)

たとえば>>365の(2)でテーブルBに一意性が必要であるならば、設定した外部キーと候補キー
(例えば作者名カラム)との組(くみ, タプル)に対してUNIQUE制約を設定するのが正しいDB設計。
この場合、外部キーと候補キーの組を「主キーとみなす」。(「主キーを設定する」とは言わない。)

>>364のようにテーブルBへ主キー(プライマリキー)を設定した場合には、RDB実装における
テーブルの一意性は保証されても、リレーショナルモデルにおける一意性(作者名の非重複保証)は
実現できないから、誤ったDB設計であると思う。

380:378
11/02/26 20:12:53.64
>>326,327
個別にはレスしないが、二人とも「単体での存在性(エンティティなのか?属性なのか?)」と
「主キーの有無(タブルの一意性を保証するのか?しないのか?)」を混同してるように見える。

381:378
11/02/26 20:15:43.69
アンカをミスった。

>>326,327は間違いだ。>>376,377に訂正する。


382:NAME IS NULL
11/02/26 20:18:00.38
>>378
そういう一般論を言ったら、Aに関係なくBが存在する場合だって
必ずしも主キーは必要ないってなるんじゃね?

383:NAME IS NULL
11/02/26 20:25:44.02
>>380
それを混同したのが>>346だと思うんだが。

384:378
11/02/26 20:36:57.54
>>382
それでも良いと思う。どこに(普通か普通じゃないかという)境界線を引くか、という話になるね。

>>383
えーと、>>346で書いた「主キーを設定する」という表現は、すべてDB実装における
主キー(プライマリーキー)のことだよ。それが読み取れないということは、やっぱり混同してるんだね。

385:NAME IS NULL
11/02/26 20:54:52.06
つまり「主キー」という言葉には2種類の意味があって、自分が意図していたのは
違う方の意味だとw
>>379では「設定する」と「みなす」なんて言い換えまでしてご苦労なこったな。

386:NAME IS NULL
11/02/26 21:41:24.92
小難しい表現の割にはどうでもいい話だったな

387:378
11/02/26 21:44:24.81
>>385
えーと、困ったな。言葉の「使い分け」はしてるけど、「言い換え」はしていないつもりだよ。
「言い換え」とは、同じ事柄を別の方法で表現するという意味だよね。

>>346のテーブルAは、RDB実装における主キー(プライマリキー)とリレーショナルモデルにおける
主キー(一意性)が一致しているから「主キーを設定する」という表現をしても誤解されることはない。
それに対して、>>379のテーブルBはリレーショナルモデルにおける主キー(一意性)は存在しているけど
RDB実装における主キー(プライマリキー)は存在しないから、誤解の無いように「主キーとみなす」と
表現方法を「使い分けた」。

日本語って難しいね。

388:378
11/02/26 21:55:30.25
>>386

>>379では、「>>363のDB設計は誤りであり>>379が正しいDB設計である」と
言い切っちまっているんだけど、これはそのまま放置しといていいのかな?
それとも、これすら「どうでもいい話」なのかな?

「いいや、....だから>>364が正しい」とか「自分ならこうする」というような
反論/異論を期待してたんだけど....。

389:NAME IS NULL
11/02/26 22:09:32.49
彼の言う「主キー」と、「主キーを設定する」という用語は
一般的なSEやプログラマがRDBMS上でのテーブル設計をする際のそれと
意味合いが違うってことです

一般的なRDBMS上のテーブル設計では、そのテーブルの行を個別に識別できる項目(の組み合わせ)を
システム的に指定することを主キーを設定するといい、その指定された項目を主キーと呼びます
そういう意味では、行を識別必要があるする全てのテーブルにおいて、主キーを設定することが推奨されます
つまり、全てのテーブルに主キーがあるべきであると言う主張が成り立つわけです

390:NAME IS NULL
11/02/26 22:11:18.60
もうどうでもいい。
T字形の論理編ぐらい、どうでもいい。

391:378
11/02/26 22:14:41.27
いけね、また間違えた。

X:「>>363のDB設計は誤りであり
O:「>>364のDB設計は誤りであり


392:NAME IS NULL
11/02/26 22:19:21.49
もともと「設定する」と「みなす」を別の意味で使っていたのなら、>>346のテーブルAも
「設定する」と「みなす」場合両方があるわけだろ?
それを誤解がないからと勝手に片方だけ書いたら逆に誤解するわ。

じゃあ聞くけど、もう一度言葉の定義を明確にして>>346を正しく書き直したらどうなるの?

393:386
11/02/26 22:48:50.20
>>388
たとえば伝票と明細のケースでいえば
明細テーブルでは行を一意に識別する主キーはいらないってのがお前の立場なんだろ?

それで要件満たせるんなら別に問題ないと思うけど、
普通は明細の各行単位で修正入れたいケースとか必ず出てくるから、
現時点で必要ないように見えても必ず主キーは設定するように俺はする。
それがサロゲートキーなのか複合キーなのかは別にどっちでもいい。

ただ、現時点での要件を満たせるんなら後で修正すればいいだけだから、
別にお前のやり方でも俺はかまわない。
お前みたいなやつを説得するのは経験的に難しいとわかってるから、
機能的に不具合が出ないんなら議論なんかせずに迎合する。

要するにどっちでもいいし、どうでもいい。

394:NAME IS NULL
11/02/26 23:01:47.25
>>387
モデルの一意性は存在してるけど実装のプライマリーキーが存在しない状態ってなんだよそれ。
つか、そもそも設計段階でそんなもん考慮するのか?

395:378
11/02/26 23:28:17.16
>>389
つまり、一般的なSE/PGのRDB設計とは>>375が言うところの設計論としての
リレーショナルモデルとは意味合いが違うってことなんだな。
だから、>>379のような「主キーとみなす」という表現は普通じゃないってことか。
うん、よく分かった。これからは注意しよう。

ところで、>>364では

>子の主キーも設定する。親への外部キーはNOT NULLで参照する。そんだけ。

とあるのだけれど、この「主キーも設定する」という表現は、自分は
単純に「プライマリキーを設定する」という意味であると(勘違いして)解釈しました。
でも、これは>>389によれば「適切な候補キー(たとえば作者名カラム)と外部キーとの
組合せに対し個別に指定できるよう主キーとして(UNIQUE制約を)システム的に指定する」と
解釈すべきなのかな?

分かっている人には当たり前なのかもしれないけど、>>344,363のような初心者に対して
「主キーも設定する」という短い一文からそのような推測を期待するのは、
ヒジョーに厳しすぎるんじゃないかと思うんですが、いかがですか?(自分も勘違いしたし....。)
いや、それすら「一般的なSE/PGのRDB設計」なら普通なのかな?

396:378
11/02/26 23:29:45.71
>>392
>>346を書き直してみた。これなら誤解はしないかな?

>>>344
>テーブルA,Bの関連が 1..N(Nは0以上) の基本を以下に書くよ。
>
>(1) テーブルAにプライマリキーを設定し、テーブルBには(テーブルAを参照する)外部キーを設定する。
>(2) 次にテーブルBにプライマリキーが必要か否かは、エンティティA無しにエンティティBが存在しうるか
> 否かで決める。ここで、もし存在しえないのなら、テーブルBは(エンティティではなく)属性を
> 表現することになるから、テーブルBへのプライマリキーの設定は不要になる。
>(3) 最後に(エンティティまたは属性)Bの一意性について検討する。もしBに一意性が必要とされるなら、
> (1)で設定した外部キーと適切な候補キー(たとえば作者カラム)との複合キーをリレーショナルモデル上の
> 主キーであるとみなし、その複合キーに対してUNIQUE制約を設定する。
>
> (以下は同文なので省略)

397:378
11/02/27 00:12:42.89
>>393
いいや、その伝票と明細のケースで言えば、明細テーブルの各行は普通にエンティティだと思う。
だからリレーショナルモデルにおける主キー(一意性)は存在するよ。ただし、RDB実装における
主キー(プライマリキー)は設定せず、(明細テーブルを参照する)外部キーと候補キーとなる
行番号カラムとの組(から成る複合キー)をリレーショナルモデルにおける主キーとみなすという
違いはあるかもしれないけどね。

このケースで属性となるのは、ある行を構成する各桁の値だ。ここで、(>>365で書いたように)
行エンティティがその値を「ただ一つだけ(only one)」持つのなら、その値は行エンティティの
カラム(フィールド)として表現する。ここまでは問題無いと思う。意見が分かれるのはこの先だ。

もしも行エンティティがその値を「いくつか持つ(zero or more)」のなら、その値は
属性テーブルとして表現するものとし、属性テーブルには(行テーブルを参照する)外部キーのみを
設定し、プライマリキーは設定しない。更に、もしも与えられた問題下でその値に一意性が
必要であるのなら(=必要な場合に限り)、外部キーと値の組を主キーとみなしてUNIQUE制約を設定する。

具体的な例を挙げれば、値引きオプション、つまり「論理値の集合」で値を表現するケースになる。
ある行が商品を表現するとして、その商品に対する様々な値引き(優待顧客値引き/個別値引き...etc)を
0個以上の任意の組合せで表現することになるだろう。

この場合、>>393であれば、どのようにDB設計をしますか?やっぱり値引きテーブルにも
プライマリキーを設定するのかな。もちろんそれでも(AP開発に苦労はしても)要求仕様を
満たせるだろうから、どっちでもいいし、どうでもいいんだけどね。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch