DB設計を語るスレ 3at DB
DB設計を語るスレ 3 - 暇つぶし2ch150: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開発に苦労はしても)要求仕様を
満たせるだろうから、どっちでもいいし、どうでもいいんだけどね。

398:NAME IS NULL
11/02/27 00:15:40.50
>>396
ふむ。「設定」が>>389の意味だとするならば、言っていることはだいたいわかる。
#本当は「存在しうる」とか「エンティティ」と「属性」の違いなんかは明確ではないが、
#ここではそれを措いても特に問題ない。

その上で反論だ。
(1)1:Nならば無条件でBに外部キーを設定することになっているが、こここそ、Bが
Aから独立して存在するかどうかで変わる部分だろう?そうでなきゃ、対応するAの
レコードが存在するBの外部キーはNULLになってしまう。
(2)一意性が必要かどうかは要件で決定されるって自分で書いていなかったか?
自分は必要ないケースはめったにないと思っているが、どちらにしても、エンティティ
ABの関係とは関係がない。
(3)ここは言葉の問題。候補キーは(1)の外部キーを含む場合と含まない場合が
あるが、どちらにしてもそのまま主キーになり得る。だから、外部キーを含まない
候補キーとの複合キーなどというものは考えなくていい。

399:389
11/02/27 00:22:38.04
>>395
>「主キーも設定する」という短い一文からそのような推測を期待するのは、
>ヒジョーに厳しすぎるんじゃないかと

「一般的なSE/PGのRDB設計」ならそう思うのが普通だと思うが
純粋な設計と言うよりは、実装方法論だがな
だからあえてRDB設計とかいう言葉じゃなくて、RDBMS上のテーブル設計って言葉をつかったんだ

400:NAME IS NULL
11/02/27 01:01:50.65
>>397
なんか例がおかしくない?優待値引きとか個別値引きとかあるのになんで論理値なの?

それはそれとして、値引きテーブルに一意性が必要ない(=同じ値引きが複数存在してもよい)
と言うことであればそれはそれでありだと思うが、特定の値引きを削除するとか変更するなんて
要件があった場合は一意性が必要となる。
一方で、ここに1商品1レコードの在庫テーブルがあったとする。これはここで言う「属性」には
当たらないと思うが、一意性の要否については上の値引きテーブルと変わらない。
つまり、一意性の要否を判断する上で「エンティティ」か「属性」かは関係ない。

401:378
11/02/27 01:49:22.13
>>398

(1) AとBが 1:N の関係であるなら、N側であるBから見ると1側であるAは必ず「ただ一つだけ(only one)」
 存在しているはずだと思います。だから、Bの外部キーがNULLになるケースが想像できないのですが?

(2) まず(2)では(一意性ではなく)存在性について述べているので、自分には論旨が不明です。
 ただし一意性については指摘のとおり、(存在性と同様に)その必要性を決めるのは要件(要求仕様)です。
 この点については、>>396への追加記述が漏れていました。

(3) この候補キーというのは、>>364の「子の主キーも設定する」というところのプライマリキーを
 指しているのですか?もしそうであり、なおかつプライマリキーが人工キーである、
 たとえば hoge_id のようにデータ型が自動インクリメントされる整数(つまり)であるなら、
 自動的に一意性は保証されるから複合キーは考えなくていいでしょう。
 自分は(なるべく)人工キーは作らず複合キーで実装する立場ですが、それはまた別の話です。

402:386
11/02/27 02:16:30.65
>>397
値引きオプションだって修正や削除の必要が発生する可能性はあるから、
当然主キーつけるに決まってるよ。
そもそも実務的には値引き伝票切るケースが多いけどな。

その例えはお前の主張したいことからして全く適切じゃない。
もっとちゃんとした例を出せ。

> プライマリキーを設定するのかな。もちろんそれでも(AP開発に苦労はしても)要求仕様を
> 満たせるだろうから、どっちでもいいし、どうでもいいんだけどね。

お前、いつの時代の人間なの?
最近のアプリケーションフレームワークなら、むしろプライマリキーをつけないほうが
特殊な処理過ぎて苦労するだろうが。

403:NAME IS NULL
11/02/27 03:53:37.69
軽い実例を出してくれたほうが伝わりやすいことは業務をやってればわかることだと思うんだけど、
いつまで文字でがんばるのか。

404:NAME IS NULL
11/02/27 07:35:09.08
>>401

(1)確かに、1:0..Nと書いていたな。それを前提としているならばここはその通り。
(2)この文章は存在性を述べているわけではなく、存在性を条件に一意性の要否を
述べているんだろ?その上で、前提が(1)の通りであるならばBは常にAなしに存在
し得ないわけで、その条件は意味がないことになる。つまり「(2)Bにはプライマリー
キーは不要」とだけ書いても同じこと。
(3)やっぱり具体例がないと伝わらないか。
例えばテーブルBが{X,Y,Z}だとして、XがAへの外部キーだとしよう。
ここで候補キーが{X,Y}の場合、それをそのまま主キーとすることができる。
また、候補キーが{Y,Z}だとした場合であっても、主キーをXとの複合キー{X,Y,Z}と
する必要はない。
つまり、「外部キーと候補キーの複合キー」はいずれの場合でも必要ない。
候補キーの定義からして自明のはずなんだが。

405:NAME IS NULL
11/02/27 10:13:02.26
うざいから、ER図付きでやってくれ

406:NAME IS NULL
11/02/27 10:17:07.66
もともとの話は>>346に対する>>364の反論から始まってるんでしょ?

例えばブログの記事にタグ付けするような場合、
記事テーブル(記事IDがPRIMARY KEY)と
タグテーブル(記事IDがFOREIGN KEY)を作るとして、
364氏はタグテーブルでは何をPRIMARY KEYにするんだろう?

「子の主キーも設定する。親への外部キーはNOT NULLで参照する。」
と言っているからサロゲートキーを作るって話なんだろうな。

それだけの話だった(ように見える)のに、
以降の議論はただ話を難しくしてるだけのような。

407:NAME IS NULL
11/02/27 11:23:29.66
なぜサロゲート?タグテーブルには候補キーが存在しない前提なの?

408:406
11/02/27 11:37:17.75
どういう候補キーがあると思う?

記事IDとタグの組み合わせを主キーにするってのは考えられるけど
それだと「親への外部キーはNOT NULLで参照する」っていうのを
わざわざ書く必要がない。(主キーなら必ずNOT NULLだから。)

わざわざ書いてるってことは364氏の言ってる主キーには
外部キーを含んでないっていう前提があるんでしょ?
(あくまで推測ね。俺は364氏じゃないから。)

409:NAME IS NULL
11/02/27 13:07:55.88
>>364の真意は知らんが、「主キーに外部キーを含めない」と限定していたようには
俺には読めなかったな。含んでいようがいまいがNOT NULLということだろ?

1. わざわざNOT NULLと書いたから主キーには含まないんだろう
2. だとすると候補キーもないんだろう
3. じゃあ何をPRIMARY KEYにするんだろう?
4. たぶんサロゲートキーを作るんだな

3.の疑問を持った時点で自分の推測を疑えよって話だな。

410:406
11/02/27 13:22:03.68
うん、まあ、そうかもしれんしそうじゃないかもしれん。
どっちにしろ、364氏の真意が分からんことには議論はできないよね。

411:NAME IS NULL
11/02/28 15:56:49.49
364だけど、

>>406
「タグテーブル」が記事に対するタグ付けを表す(記事ID, タグID)、かつ
タグの順序に意味はないとして、同じタグを同じ記事に複数回付けられ
ないのであれば(普通の仕様だと思う)主キーは(記事ID, タグID)。
「[これはすごい][これはすごい][これはすごい]...」みたいに、同じ記事
に同一タグを複数回認める酔狂な仕様なのであればサロゲートキーも
必要。

後者は純粋に関係モデル的にはそもそもこのようなキーがないとデータ
を表現出来ない(setだから)。SQL的にはsetではなくbagだから無くても
表現できるけど、大抵は無いと更新時に填る。

>「子の主キーも設定する。親への外部キーはNOT NULLで参照する。」
>と言っているからサロゲートキーを作るって話なんだろうな。

いや全然。そんな話じゃない。
外部キー参照は仮に主キーを参照していてもNULLは入れられる。
「子単体は存在しない」、すなわち必ず親を持つのであれば明示的に
NOT NULLは宣言する必要がある。

>>409
>含んでいようがいまいがNOT NULLということだろ?

正解。

412:NAME IS NULL
11/02/28 16:15:31.13
もひとつ、>>346に聞きたいのは、>>346のルールとか、そのあと
改正した>>396のルールとか、これ教科書か何かに書かれたものなの?
であれば参考までにリファレンスを示してくれると嬉しい。

413:406
11/02/28 18:47:49.98
つまり、>>364
「子の主キーも設定する。親への外部キーはNOT NULLで参照する。」
は以下の意味だってことだろうから、俺は特に異論はない。

「子の主キーも設定する。
 ただし、要件によってはサロゲートキーとすることもあり得る。
 親への外部キーはNOT NULLで参照する。
 ただし、子の主キーが親への外部キーを含む複合キーである場合は、
 明示的にNOT NULLを指定する必要はない。」

346氏(=378氏?)は、単にサロゲートキー否定派なんじゃない?

414:NAME IS NULL
11/02/28 19:49:10.77
>>413
そゆこと。ただし以下の下りはちょびっと。

>ただし、子の主キーが親への外部キーを含む複合キーである場合は、
>明示的にNOT NULLを指定する必要はない。

必要ないし意味的にはダブるかもしれないけど、それでも明示的に
指定するかな。ごくごく個人的には、単に作法として。
テーブル定義を読んでも、parent_id *** NOT NULLと直接書いて
あった方がparent_idの取り得る値の制限としては解りやすいし。

>346氏(=378氏?)は、単にサロゲートキー否定派なんじゃない?
よくわからんす。自然キーでも人工キーでも、必要な場面で正しく
使えばどっちでもよいです。

415:NAME IS NULL
11/03/01 00:15:51.62
「弱実体」でググると>>346が言いたかったことと、どこが間違っていたかがわかるかも。

416:NAME IS NULL
11/03/01 01:34:29.60
>>396
> (2) もし存在しえないのなら、テーブルBは(エンティティではなく)属性を
>  表現することになるから、テーブルBへのプライマリキーの設定は不要

逆にエンティティA無しにエンティティBが存在しうるとすればどう
するの? プライマリーキー定義するの? どう決めるの?

> (3) 候補キー(たとえば作者カラム)
それは部分キーだ。候補キーじゃない。他のレスでも間違っている。
言葉遣いの問題だが、関係モデルの超基本だ。

> (3) その複合キーに対してUNIQUE制約を設定する。
なんでUNIQUE制約? PRIMARY KEY制約だとダメなのか? だってその
「複合キー」はテーブルB中の行を一意に選択出来るんでしょ? 主キー
の資格十分じゃん。
素のUNIQUE制約はNULL許可するけど、それでも良いの?

417:NAME IS NULL
11/03/01 01:43:38.21
>>397

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

関係従属性(商品, 値引きオプション) -> 適用可能[true or false]が存在。
なので値引きテーブルは(商品ID, 値引きオプションID, 適用可能)。
主キーは(商品ID, 値引きオプションID), 商品ID・値引きオプションIDに
外部キー制約。ちなみにBCNF。完璧じゃん。

主キーつけるのに何を悩む必要があるのか、それが解らない。

418:NAME IS NULL
11/03/01 02:10:41.89
>>378氏は一生懸命頑張って主キーがいるいらないの説明しているけど、
まず純粋にスキーマ設計の立場からいうと各テーブルの候補キーを特定
しておくことはマストだよね。でないと正規化が出来ん。

次に正規化が完了した関係スキーマをSQLで実装するときには候補キーに
対応する属性やその組に適切な制約をつけておくことは作法だよね。
でないとデータの整合性をアプリケーションレベルで保証する必要がある。

次に、それでも更新時のパフォーマンスの問題などで制約を外したい事は
無いわけじゃないよね。でも基本的にキーに対する制約を外すとテーブル
中の各行をアトミックに更新出来ることをDB側で保証できなくなる。
なのでその部分はアプリ側で制約するとか、更新の対象や単位を詳細に
見極めて判断したりする必要がある。

ましてや>>344は初心者だといっているのだから、教科書通りER図など
から主キーも含めたテーブル定義を導出する方法で良いじゃないか。

419:NAME IS NULL
11/03/01 03:10:14.37
みんな教科書通りにやろうとしてるぜ
みてる教科書の分野が微妙に違うんだがな

420:NAME IS NULL
11/03/01 04:11:06.16
>>417
関係従属性 -> 関数従属性。
関係モデルの超基本だ・・・釣ってくる・・・

421:デフォルトの名無しさん
11/03/04 00:09:48.83 nwTUgCQG
話をサロゲートキーの話題に戻すが、

①商品マスタの商品コードが変わったときの話だが、
 サロゲートキーにしておけば、コードの付け替えが楽。

②トランザクションにてその時点のマスタ値を保障する方が安全
つまりトランザクションには、商品ID、商品コード、商品名等を
すべて保持する。

①と②は明らかに同時に成り立たないわけだが、
この矛盾はみんなどうしてる?

あと、階層関係があるマスタ、たとえば事業部マスタと部門マスタで
事業部と部門の紐付けが変更されうる。部門の名称変更がある等の理由で、
適用期間をおのおの持った場合、サロゲートキー(事業部ID)
だけでリレーションさせると、事業部マスタの世代が増えたタイミングで、
リレーションが破綻するわけだが、どうしたらいいんだろ。


422:NAME IS NULL
11/03/04 00:38:25.10
> ①と②は明らかに同時に成り立たないわけだが、
> この矛盾はみんなどうしてる?

矛盾なんかしてません。
馬鹿じゃないの?

> 適用期間をおのおの持った場合、サロゲートキー(事業部ID)
> だけでリレーションさせると、事業部マスタの世代が増えたタイミングで、
> リレーションが破綻するわけだが、どうしたらいいんだろ。

どういうシチュエーションでどういう設計をしたら破綻するのか
全然イメージがわきません。
多分サロゲートキーじゃなくてお前の頭が悪いんだと思うよ。

423:NAME IS NULL
11/03/04 00:55:03.15
>>421
サロゲートキーの使い回しをせず、商品コードの書き換えもマスタ
への追記で対応すれば(2)は本来不要なんじゃないのかな。

424:NAME IS NULL
11/03/04 01:36:28.45
まず、この例で言うなら、商品コードが変わった場合
過去に登録されたトランザクションデータをどうしたいかを考えろよ

過去データを塗り変えたいなら1が便利
過去データはそのまま保持したいなら2が便利

それだけの話だろ
違う要件に対する解決案をならべて同時に成り立たないって当然だろ

425:NAME IS NULL
11/03/04 01:39:40.34
履歴とリアルタイムデータの区別が付いてないっぽいな

426:NAME IS NULL
11/03/04 01:57:35.75
>>424
2にしてもトランザクションデータに追記する際に商品コードとか
商品名などを商品マスタの内容からコピペしているのであれば結局
1で対応出来るのだが。

商品マスタは基本追記で、最新フラグとか削除フラグとか付けて
古い商品レコードも全て保持するのは案外一般的だと思うけど。

427:NAME IS NULL
11/03/04 20:05:10.85
サロゲートキーでよくわからないところがあるんだが
本来pkになるはずだった項目の制約はどうすんの?
前に張られたこのURLの例では、制約について一切触れてないから、そんな制約張りませんってことなのか・・・?
URLリンク(gihyo.jp)

428:NAME IS NULL
11/03/04 20:14:23.32
制約つければよくね。

429:NAME IS NULL
11/03/04 20:25:51.61
NOT NULLとUNIQUEでいいじゃん

430:NAME IS NULL
11/03/04 20:28:03.50
>>428
もともとpkにする予定だった項目には、例外なくuniqueを張りたいんだけど
>>427の例ならどうするべきですか?

431:NAME IS NULL
11/03/04 20:35:13.01
>>427
場合によるとしか言いようがない。
挙げられた例だともともと主キーだったitem_noにUNIQUE制約とか
は付けられないよね。同じitem_noを使い回すので。

沢山の属性を組み合わせた複合キーをシンプルなサロゲートキーで
置き換えるような場合は、主キーこそサロゲートキーにしたとはいえ
元々の複合キーも未だに候補キー、つまりキーに含まれる属性値の
組み合わせはユニークなはずなので、UNIQUE制約を付けた方が良い。

432:NAME IS NULL
11/03/04 20:36:53.99
>>430
item_no(商品ID)とitem_name(商品名)の組み合わせに対して
UNIQUEだろうね
しかし>>427の例って商品ID自体が自然キーじゃないよな

433:NAME IS NULL
11/03/04 20:55:19.98
>>427のように、同じitem_noを使い回すのであればテーブルには更に
最新フラグとか削除フラグをつけることが多いと思う。
[id(サロゲートキー), item_no, item_name, deleted]みたいな感じで。

で、上記の例の場合は削除フラグdeletedがfalse、つまり現在有効な
行の中でitem_noのダブりがあると困るわけなのだけど、この制約を
書くのはちょっと面倒くさい。フラグ値を工夫するとか一般制約を
使うとかすれば書けるけど。
実際はアプリケーションレベルでタブりを事前確認するロジックを
書くことが多いんじゃないのかな。

434:NAME IS NULL
11/03/04 21:06:10.73
>>431
>つまりキーに含まれる属性値の組み合わせはユニークなはずなので、UNIQUE制約を付けた方が良い。
この部分がよくわからないんですが、もうちょっとスキルが低い人にもわかるようにお願いできませんか?

>>432
名称もunique制約に含めるって、普通に行われることですか?
見たことが無いのでちょっと抵抗があるんですが。
それから、>>427の例の商品NOは、人口キーのようなどうでもいい文字列ってわけじゃなく
お客さんのなんらかの都合により使いまわされる事がある、お客さんも把握してる文字列なわけですから
自然キーの典型的な例だと思うんですが、違うんでしょうか?

>>433
変なデータができあがっちゃうとまずいんで
私が見たことのあるDBでは2重に重複チェックしてました。
具体的には、プログラム側でマスタを更新するまえにDBに問い合わせてチェック→重複してるようならweb画面にエラーを出す
プログラム側のチェックを通ったあとも、unique制約により、DB側でチェックが行われ、これも通れば更新されるといった仕組みでした。

おそらく削除フラグを付けたほうがいいというのは、期間でなくフラグを参照することで
select文を発行するときの負荷が減るというのが目的ですよね?
重複チェックはなかなかミスが出るようなところじゃないから、アプリ側できっちりやれってことでしょうか?

435:NAME IS NULL
11/03/04 21:30:12.87
>>434
プライマリキーのカラム数が5個ぐらいあって、Joinがしんどくてしんどくてしょうがないという理由から
ただの連番のカラムを作って、それをキーとするようにしてみた
という状態であれば、もともとの5カラムにユニーク制約つけたままで問題ないよ

436:NAME IS NULL
11/03/04 21:32:21.28
>>432
それがUNIQUEになるなんてただの思いこみなんじゃないかって思う

437:NAME IS NULL
11/03/04 21:35:44.50
>>435
すごくわかりやすい、ありがとう。
効果は開発効率のアップと、select文のコストが少し減るって感じかな?

その目的でサロゲートキーを使う場合
全てのテーブルにサロゲートキーを追加するんじゃなくて
pkの項目が多くなりそうなテーブルにだけ追加するのが良さそうですね。
サロゲートキーを使用するテーブルの場合、例外なく最初の列に「PK_テーブル名」というカラムを作り
それをサロゲートキーにするというルールで設計すれば、アプリチームの混乱も防げて良さそうですね。

438:NAME IS NULL
11/03/04 21:41:20.76
>>434
例えば月給テーブル(社員ID, 年, 月, 給料)を考えてみる。
主キーは(社員ID, 年, 月)ね。

で、理由はともあれ誰かさんが属性3つの複合キーなんて非効率的だ!
サロゲートキーにしろ! と叫んだとする。で、サロゲートキーSIDを追加して
月給テーブル(SID, 社員ID, 年, 月, 給料)、主キーSIDにしましたと。

で、このテーブルをよく見てみると、確かにSIDはキーですが、元々の主キー
(社員ID, 年, 月)もテーブル内の行を一意に特定出来るキーなんですね。
というか一意に特定出来ないと困る。でないと同じ社員が同じ年・月に複数回
給料もらえちゃいます。

関係モデルでは一つのテーブルが複数の「候補キー」を持つことがあります。
この場合はSIDと(社員ID, 年, 月)の二つの候補キーがあります。
その中から「主キー」を一つだけ選ぶわけですが、だからといって残った他の
候補キーがキーでなくなるわけではありません。それらも引き続いてキーです。
なので上記の例だと候補キー(社員ID, 年, 月)にUNIQUE制約を付けておく
必要があります。

439:NAME IS NULL
11/03/04 22:00:25.24
>>434
>おそらく削除フラグを付けたほうがいいというのは、期間でなく
>フラグを参照することでselect文を発行するときの負荷が減ると
>いうのが目的ですよね?

例えばサロゲートキーを使った商品マスタテーブルを使って実際に
トランザクションデータを書き込むとき、伝票に書かれた商品IDから
サロゲートキーを逆引きする必要があります。
しかし>>427のテーブルの場合、商品ID001からサロゲートキーを
逆引きすると二つサロゲートキーの値が出てきます。これはで困る。
なのでフラグを付けて現在も有効なレコードだけから検索するように
する必要があります。
もちろん特別にフラグを設けずに、例えば有効期間を表す列に「現在も
有効」を表す特別な値(>>427の例だと"9999")が仕様として定義されて
いる場合はこれを使って絞り込んでもよいわけです。

ただこの手の終了フラグを使った場合、商品IDのタブりを防ぐ制約は
やや凝った記述になりがちで、となると現状PRIMARY KEYなど基本
どころ除けばDBMS毎に書ける制約の表現力がバラバラなのが難しい。
MySQLなんてCheck制約は書けてもガン無視するとか、そんな仕様。
なんでアプリ側でチェックするロジックを書くことも多い気がします。

440:NAME IS NULL
11/03/04 22:26:37.03
>>438
丁寧な説明ありがとう。
この板はIDが無いみたいなんで、どのレスをした人がどのレスを返してくれてるのかわからないけど
>>435>>438は同じ事ですよね?


>>439
MySQLでcheck制約がきかないのは初めて知りました・・・なんと恐ろしい。
>>427の場合は、トランザクションテーブルに書き込む商品の情報は
商品IDじゃなくてsrg_key(サロゲートキー)じゃないですか?

>>427の例の仕様ではこうなってるはず
・マスタのpkはサロゲートキーを使用する。
・トランザクションテーブルの外部参照をする列に格納するキーは、参照先のサロゲートキーを入れる。
・過去に入力された名称は、その時点で入力された名称をマスタから取得する。
・unique制約は付けない。


サロゲートキーの一つの利点である、pkに指定する項目が1つになるという部分は理解できました。
どこのページを見てもあんまり紹介されてませんが
unique制約が付けづらいというのはサロゲートキーのデメリットとして覚えておいた方が良さそうですね。


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