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制約が付けづらいというのはサロゲートキーのデメリットとして覚えておいた方が良さそうですね。
441:デフォルトの名無しさん
11/03/04 22:32:56.51
商品IDがダブらないなら本質的にサロゲートキーは不要かと…
やばいのは商品IDというか商品コードがメーカーによって使いまわされて、
ある製造日より別商品に割り当てられたが、
販売店の在庫管理としては商品コードと入荷日でしか
管理していなかったため、同一商品コードの違う製品が混在してしまって
何を販売したのか管理できず混乱するなどですよね。
442:NAME IS NULL
11/03/04 22:45:47.53
>>441
得意先のマスタなんかは在庫とかって概念がないからどうゆうふうに設計してもなんとかなりそうなもんだけど
商品に関しては商品IDを使いまわす可能性があるならサロゲートキーは必須になるのか
443:NAME IS NULL
11/03/04 22:50:32.51
すごーーーーく根本的な話になるんだけど
商品IDの使い回しを行いたい時ってどうゆう時?
得意先や部署はわかる。
合併やら統合やらあるもんね。
商品IDはわからん。
444:デフォルトの名無しさん
11/03/04 23:00:00.52
桁数だろう?
どれだけ必要になるかわからないからって
たとえば20桁のコード体系をあらかじめ用意するのかってこと。
覚えられん…
445:NAME IS NULL
11/03/04 23:10:09.40
>>443
古いシステムならコードのMAXが5桁とか普通に有り得るだろう。
446:NAME IS NULL
11/03/04 23:18:26.31
えー・・・
447:NAME IS NULL
11/03/05 00:12:24.71
くるくる回る商品IDなんてよくある。
ある時点においてユニークであれば、それで現場は回っていくんだよ。
なもんで、こっちとしてはサロゲートキーを作って、商品IDガン無視する。
たとえ今はいらなくとも、商品IDで検索したいってなったときに困らないように、
ある時点で有効な商品IDがどれかを特定できる情報を保持しておく。
448:NAME IS NULL
11/03/05 00:39:28.99
俺の場合、
自社に決定権がないコード体系のマスタ(商品など)は、サロゲートキー
自社に決定権があるコード体系のマスタ(得意先マスタ)はナチュラルキー
ジャーナルのヘッダはサロゲートキー、
ジャーナルの明細はヘッダのID+明細番号の複合主キー
とすることが多いが、これって古臭い?
449:NAME IS NULL
11/03/05 01:22:17.28
雑誌コードなんか桁が足りなくて新規発番が出来なくなって使い回してるよな
450:NAME IS NULL
11/03/05 01:28:21.09
そうゆうことか。
周辺システムが古くて桁数が少ないので
商品IDを使いまわさずを得ないと。
>>441みたいな場合ってどうなるの?
頻繁に商品IDが付け替えられて、古いほうの在庫も残る可能性がある。
同じ商品IDで、商品そのものも名称もまったく違う商品が存在する。
Web画面で商品を入力するためのボタンがあって、ポップアップで検索ボックスみたいのが出てきて
IDで検索すると同じ商品が複数出てくる。
それを選択してもらう。
Webの入力画面でコードを手打ち入力した場合の動作は?
ajaxとかで名称ひっぱりたいとこだけど、複数出てきた場合は新しい方を出したりするのかな?
なんにせよ恐ろしい・・・
こうゆう運用ならサロゲートキーは必須だ・・・
451:NAME IS NULL
11/03/05 02:15:11.10
>>448
その得意先マスタのキーって得意先IDみたいなの、つまりサロゲーとキーでは?
ナチュラルキーになりうるのってなんだろうとぐぐってみたところ、
上場企業限定ならISINコードというものがあるようだけど、これなのかなぁ
>>449
休刊して番号温存だね。あるある。
>>450
客から見て、在庫も含めると異なる商品に対して同じ商品IDがついているけれども、
業務を滞りなく行えているのであれば、何も悩む必要はないよね。
こちらとしてはサロゲートキーで処理をしてしまえばいいだけだよー
452:NAME IS NULL
11/03/05 02:17:08.29
>>450
加えて、商品IDでの検索結果が複数出てきたなら複数出せばいいんだよ。
それで業務がまわっているということが不思議だなぁと思うことはあれど、
それを正としなければいけないしねw
453:NAME IS NULL
11/03/05 02:30:08.03
>>451
>上場企業限定ならISINコードというものがあるようだけど、これなのかなぁ
>>448の言う「自社に決定権があるコード体系」というのは、
そういった業界標準コード体系を意味しているのではなく、
業務の中で自然に発生する自社特有のコードを指していると思う。
たとえば、紙の受注伝票に記入する得意先コードや受注商品コードというのは、
自社特有の(自社で決定できる)自然キーである可能性が高い。
逆に、発注伝票に記入する発注商品コードというのは、
(自社では決定できないから)人工キーとせざるを得ない可能性が高い。
454:NAME IS NULL
11/03/05 16:14:51.45
お前ら、商品ID商品ID言ってるけど、使いまわした時点でIDとしての役割を果たしてないだろうが
商品コードを使いまわす、が正しい用語だ
455:NAME IS NULL
11/03/05 17:59:31.77
まぁ目安だよな。あくまでも、自分が定義したエンティティに対してそのコードが
一意であるがどうかで判断すべきであって。
・よそで定義されたコード→一意でない「可能性がある」
・自分で定義するコード→当然一意に「できる」
極端な話、実際の商品の品種と商品コードの一意性が一致しない場合であっても、
「商品」ではなく「商品コード」エンティティを作る分には商品コードをそのままキーと
してもぜんぜんかまわないわけだ。
456:NAME IS NULL
11/03/07 20:06:48.91
>>453
>自社特有の(自社で決定できる)自然キーである可能性が高い。
純粋な意味では、自然キーではないよね。w
457:NAME IS NULL
11/03/07 20:11:28.00 OIEGkLgo
>>440
>MySQLでcheck制約がきかないのは初めて知りました・・・なんと恐ろしい。
こわくないよ?
つーか、それっておいしいの?
MySQLしか使わないオレには、よく
わからん話なんだよな。
458:NAME IS NULL
11/03/07 20:53:11.82
>>456
システムの外で定義されるのが自然キーだろ?コードが人工的かどうかじゃなくて。
そんなこといったら、人名とか市町村名なんてどっちか判断つかん。
459:NAME IS NULL
11/03/08 05:36:45.40
>>457
知らない者にとっちゃ恐ろしいだろ。
定義できるのにまさか動かないとは思わないだろうし。
460:NAME IS NULL
11/03/09 01:13:08.54
>>454
このスレでのID、コードの使い分けって一般的に通用するものなの?
いや、自分もそういうふうに使い分けてるんだけど、他の人がそんな風に気にしてるの見たことがないので。
461:NAME IS NULL
11/03/09 01:47:19.22
>>460
基本的には普遍でユニークな社員番号(商品ID)と、変更可能な姓名(商品コード)、
みたいな形で一般人も接してはいる。
462:NAME IS NULL
11/03/09 15:48:40.12
>>460
まあ、大概の人は混同してる。このスレでも混同してる人もいるしな
一般の人にとって、コード振ってあるのに別にIDとるのは無駄に思えるんじゃね
463:NAME IS NULL
11/03/09 20:21:29.21
「混同」っていうと、まるで使い分けないのがおかしいみたいだな。
2行目をみるとそれぞれ別物のなにかを指しているというのはわかるんだが…
464:NAME IS NULL
11/03/10 06:07:06.59
IDでもコードでも俺はどっちでもいいな。
使い分けてないプロジェクトがあっても、sql書く時に項目名間違えづらいなぁ程度にしか思わない。
465:NAME IS NULL
11/03/10 09:17:01.62
>>458
システムの外で「独立して」定義されるのが
自然キーだろ?
顧客コードなんかデータベース以外に
ほとんど用途がないんだから。
466:NAME IS NULL
11/03/10 15:38:23.73
>>463
ID=コードなシステムもまあよくある
というか、IDとコード別にもつシステムの方が少ないと思うけど
IDとコードもつシステムの例はコード使いまわされるようなやつとか
「その他」とか「一般小口」とかのコードもってるシステムとか
IDっていう用語の意味を考えると、厳密に区別できないとIDじゃないからな
467:NAME IS NULL
11/03/10 22:58:24.84
>>465
この場合の「独立して」ってどういうことを意味しているのかな?
ここで挙げられた顧客コードってのは、「システムの外で定義されるけれども独立してない」例?
468:NAME IS NULL
11/03/11 04:29:35.90
独立していない可能性がある、または随時変更される可能性があるコードなんじゃない?
客から見えるコードだと、コードを振りなおしたい要求って結構くるよね
469:NAME IS NULL
11/03/11 07:32:25.94
>>465
>顧客コードなんかデータベース以外に
>ほとんど用途がないんだから。
ええぇっ!!、それが常識なの?
自分のいる世界とは別の異次元な世界の住人さんらしい.... hahaha
470:NAME IS NULL
11/03/11 11:13:05.74
「データベース」の意味をどう捉えてるかによるだろうな
471:NAME IS NULL
11/03/11 11:34:03.00
「データベース」でくくるとさすがにちょっと狭いと思うぞ
ほとんど「情報処理」とか「システム化」と同じぐらいまで解釈を広げればまあ納得しなくはないが
472:NAME IS NULL
11/03/11 13:15:03.35
台帳をデータベースと呼ぶかどうか
473:NAME IS NULL
11/03/11 13:18:57.55
>>469
そんな反応しなくてもw
そこだと、顧客コードは恒久的に変わらないことが前提で、顧客コードで会話等がされてるんでしょ。
その業務であればそのコードはIDであり、自然キーといっていいと思うよ。
474:NAME IS NULL
11/03/13 03:34:25.71
どのスレが適当か探してみたんですが、スレ立てるまでもない質問スレが見つからなかったので、ここで質問させて下さい。
病院で働いているんですが、今、上司からの依頼で、内視鏡検査の画像をデータベース化する作業をしています。
現在のシステムに以降する前の約2年分、件数にして4000件ぐらいのデータです。
データ形式ですが、約3ヶ月分ずつのデータがDVDにまとまっていて、DVDの中に入っている.exeファイルを起動して閲覧する、というものを、何とか一つのデータベースにまとめたいと悩んでいます。
各データは一件あたり数十枚で、たとえば34枚だとすると、フォルダ名00001、その中にjpeg画像00001から00034が34枚格納されていて、つぎの件はフォルダ名00035となり、その中にまた画像一枚ずつに数字でファイル名がふってある形でした。
閲覧ソフトに患者名かIDか検査日を入力すると、画像が閲覧できます。
DVDに入っているのは画像フォルダ、恐らく画像とひも付けしたログファイルのフォルダ、あと閲覧ソフトです。
こういったデータを、Windows上で現在のシステムに移植するには、(オリンパスの出入り業者に確認した話ですが)一件一件検査オーダーを立てて、画像を指定する必要があるとのことでした。
自動でデータを読み出して全ての過去データDVDをデータベース化するか、現在のシステムに移植するには、どういうソフトを使えば可能でしょうか?
軽く調べたところ、SQLとやらいうスクリプトの話がでてきましたが、ド素人なので厳しいかと正直諦めかけてますorz
よろしくお願いします。
475:NAME IS NULL
11/03/13 03:48:10.98
>>474
多分この内容だと情報が足りなすぎて誰もアドバイス出来ないと思う。
ファイルの格納の仕方は「なんだそれ」という感じではあるけれども
サルベージ出来ないわけでもない。多分ネックは、
>恐らく画像とひも付けしたログファイルのフォルダ
の中身と
>Windows上で現在のシステムに移植するには
の「現在のシステム」が分からないと、どうにもならないかと。
ただ間違ってもログファイルの抜粋をこのスレに貼り付けたりは
しないでね。
いずれにしても出来合いのソフトで出来そうな作業じゃない。
専用のマイグレーションのためのプログラムを書く必要はある。
476:NAME IS NULL
11/03/13 04:30:03.11
>>475
レスありがとうございます。
やはり専用のプログラムが必要ですよね…
現在のシステムは、内視鏡サーバーに全て検査内容が直接スタックされるもので、オリンパスのsolemio というものです。
検査一件一件のデータをログから指定して、画面上の場所指定でオートクリック、ログ入力、画像指定が出来るソフトというと、オンラインゲームのチートソフトくらいしか思い付かず、それにしたってログを読み出すプログラムが別に必要になりそうな予感はしていました。
ちなみにログの抜粋がアウトなのは個人情報の関係ですか?
477:NAME IS NULL
11/03/13 04:37:50.27
>>476
医療情報流出~匿名掲示板でアドバイスを装って診察データを入手か~
・・・なんてニュースになりたくないでしょw
オリンパスにデータインポーター提供してもらうしかないんじゃない
のかなぁ
478:NAME IS NULL
11/03/13 05:08:53.69
>>474
画像の格納方法に規則性があるなら、画像を取り出すことは出来るかもしらんが、
「患者名かIDか検査日を入力すると~」がネック。おそらくこの他にも情報があるんだろうけど、これらのサルベージ方法が問題。
フォルダの中にテキストで埋めこまれてるとか言う間抜けな作りなら個人PGでも解析出来るだろうけど、さすがにそんなことはないだろうな・・。
そもそも元システムのライセンス的にどうかとかなりかねないし。
逆に解析を諦めるなら、最終手段で人がPC2台使って手入力でやれば出来る(つまり出入り業者の言う、「一件一件検査オーダーを立てて、画像を指定する」)。
この最終手段の可能性コミで、オリンパスに見積もってもらうのがベストだと思う。ただ人海戦術は安くないけどね。
479:NAME IS NULL
11/03/13 06:48:05.90
>>474
ざっと読んでみて、まず基本的な課題を挙げてみる。
(1) ストレージ管理
4000件のデータで各データが数十枚のDVDに格納されているというデータ量が膨大なケースだけど、
それらコンテンツのカタログ(目録)だけをデータベースすればいいのか(= カタログDB化)?あるいは
すべてのコンテンツをストレージ(要はハードディスク)内に格納するのか(= 画像DB化)?という判断。
もし前者であればソフトウェア(アプリケーション開発)だけ対応できるけど、
後者の要求を叶えるとすれば専用のストレージハードウェア導入も検討対象になる。
(2) 遺産データのデータ形式仕様
DVDに格納されている過去データについて、そのデータ形式仕様を把握する必要性があるという課題。
データ形式仕様には、(a) DVDボリューム構成、(b) DVD内のディレクトリ/ファイル構成、
(c) ログファイルのデータ構造などがある。この課題を、より具体的な副課題に分解してみる。
(2-1) その遺産データの作成者から仕様書を入手
作成した外部の業者(あるいは院内の担当者?)に問い合わせて入手できるのが理想。
もし入手不可であれば、自力で分析する、いわゆるリバースエンジニアリングという作業が必要。
(2-2) 入手した仕様書と(DVDに格納された)実データに一貫性があるかを検証
理想的には、すべての実データが仕様書に従って作成されていれば、
(相対的に)単純なスクリプト(プログラミング)でデータ移行処理が可能になる。
最悪なのは、手作業でDVDボリューム名/ディレクトリ名などを決めて焼いていたケース。
(2-3) ログファイルのデータ構造について機械可読性を確認
理想的なのは、XMLのような形式的なテキスト形式で保存されている場合。
もしも独自のバイナリ形式であれば、(2-1)のデータ形式仕様書の入手が必須になる。
最悪なのはフリーなテキスト形式のケースで、一件ずつ手作業で編集しなければならなくなる。
(3) 新規アプリケーション開発の必要性
理想的には、(2)の作業を経て準正規化(機械処理可能化)された中間データを、現行の(OLYMPUS?)
システムへ移行する(相対的に単純な)変換プログラムを作成することで、課題が解決できるケース。
もしもそれが不可であると判断されたなら、その中間データを元に新規DBの開発を検討する。
その場合には、どのようにDBを設計すべきか?という、このスレ住人向きの話題にようやく辿り着く。
480:479
11/03/13 07:23:59.19
>>479の課題(3)で新規DB開発を決定した場合に限定される話だけど、
医療関係者が(外部の業者に頼らずに)自力でデータベース化を図るとしたら、
FileMaker Pro というDBアプリケーションがよく知られている。
FileMaker Pro は、Microsoft製であればAccessに相当するデスクトップDBソフトだけど、
SQLを憶える必要は無いし、テーブル設計/画面デザインからスクリプト作成まで
すべてGUIで操作できるから、簡易なDBであれば専門家でなくても開発できるのでお勧め。
(個人的にはシステム分析初期段階のラピッドプロトタイピングに活用している。)
たとえば以下の医療画像管理アプリはソースも公開されている。
・マイコミジャーナル:ファイルメーカ選手権(第一回)月間優秀賞:患者画像記録
URLリンク(journal.mycom.co.jp)
FileMaker Proは試用版が無償で利用できるから、まずダウンロードして触ってみるのがいい。
質問等はビジネスsoft板に専用のスレがあるから、そちらへドーゾ。
481:NAME IS NULL
11/03/13 16:43:53.66 UrDSEA55
「はてな」や楽天のポイント履歴を見ていて思ったのですが、
ああいう頻繁にレコードの追加が発生するコミュニティサイトって
1テーブルのフィールド構成をどうしているのでしょうか?
単純に「日付|ポイント数|対象ユーザID|対象動作ID」
で分けてるだけでしょうか?
でも、そう考えると、ユーザ数×履歴数で倍々に増えていくので
万単位の会員数があるサイトでは、ポイント履歴テーブルに
レコードが溜まりすぎるのではないか?と言う懸念があります。
ポイントというお金と変わらないものですから、
「○件まで保存。後は削除」と言うことはなかなか出来ないと思いますし・・・
482:NAME IS NULL
11/03/13 17:03:45.55
ヒント:それらのケースでは厳密なACIDは要求されない。
(もちろん楽天の商品注文処理には厳密なACIDは要求される。)
483:NAME IS NULL
11/03/18 16:34:48.59 N3L942K+
ショッピングサイトでのDB設計について
・注文テーブル、
・会員テーブル
があります。
会員が注文した場合は会員IDを外部キーとして注文テーブルに入れればいいのですが、
会員じゃない人からも注文が入るので、
注文テーブルに会員テーブルと同じようなフィールド(名前、送り先住所など)を入れて、
注文レコードに、会員ID(外部キー)が無い(NULLの)場合は、同じ注文レコードの名前や住所を参照しようと思っています。
もう1つは、会員テーブルと同じような、非会員テーブルをつくり、
会員じゃない人の住所情報などはそこに入れようという方法です。
後者の方が個人的にきれいな設計だと思うのですが、
この場合注文テーブルに入れる外部キーをどうするかがまた問題になって困っています(外部キーが非会員IDなのか会員IDなのかわからなくなる)。
これを解決するために、
非会員注文テーブル、
会員注文テーブル
と2つに分けることも考えていますが、
ここまですると逆に注文テーブルが2つになってしまうのできれいじゃなくなる気がします。
どうするのが一番良いでしょうか
484:NAME IS NULL
11/03/18 16:40:17.60
無駄すぎ
注文テーブルと会員テーブルだけでいいですがな
485:NAME IS NULL
11/03/18 17:21:13.97
>>483
まず最初にモデル分析について。
前者は論外。注文テーブルでは注文に関する情報だけを定義すべき。
残る後者について、「会員の人」と「会員じゃない人」という概念は、
人に関する集合を意味するわけだけど、これら両方を包含した全体集合を考えなさい。
たとえば「取引先」という概念は一般に両者を包含するからよく用いられる。
あるいは全体集合を「会員」として位置付けて、部分集合を「正会員(会員の人)」と
「会員候補(会員じゃない人)」とに分割するという、逆の発想でもかまわない。
次に実装についてだけど、これもいくつかの方法がある。
たとえばモデル分析で全体集合を「取引先」とし部分集合を「会員」および「非会員」とした場合、
テーブルとしては「取引先テーブル」だけを定義し、そのフィールドとして会員区分コードを設ける方法。
あるいは各集合に対応する3個のテーブルを定義する方法もある。この場合、「会員テーブル」と
「非会員テーブル」には外部キーとして(取引先テーブルを参照する)取引先IDを設けることになる。
どちらの方法を選ぶにしても、注文テーブルの外部キーは取引先IDだけになるから、課題は解決される。
486:NAME IS NULL
11/03/18 17:51:34.01
>>483
会員が自分の住所以外を送り先として注文することはないのかな?
487:NAME IS NULL
11/03/18 18:02:59.08
>>485
前者は論外、とも言えないんじゃないのかなぁ。
会員IDがNULLの時だけ名前や住所の値を参照するという運用には
とても疑問があるけれども。
483は取引後に会員の名前が住所や変更される可能性と、その場合
も過去の個別の注文に関してはその当時の住所や名前を保存して
おく必要性(普通は必要だと思うけど)を考えるべきだと思う。
その場合には注文テーブルにも名前や住所などのカラムを作って
注文毎に会員情報から転記する方法と、少し前に散々議論された
会員情報をサロゲートキー使って管理する方法がある。
488:NAME IS NULL
11/03/18 18:55:00.36 vy9E5dGG
論理キー(複合キー)があるのに、わざわざID列を主キーに作るの勘弁してくれ。
489:NAME IS NULL
11/03/18 20:32:06.47
単にSingle Table Inheritanceの典型的なケースではないの?
この辺を参考にすれば
URLリンク(capsctrl.que.jp)
490:NAME IS NULL
11/03/18 21:45:08.46 vy9E5dGG
典型的なプログラマー脳orパッケージ屋さんか?
491:NAME IS NULL
11/03/18 22:02:10.77
ではDB屋さん的な回答どうぞ。
492:NAME IS NULL
11/03/18 22:16:11.36
・注文テーブル
・顧客テーブル
・会員テーブル
に分ければ良いだけじゃん。
注文テーブルの顧客IDと顧客テーブルのIDをJOINして
顧客テーブルのIDと会員テーブルのIDをJOINする。
会員テーブルには、ID/パスワードなど、ログイン専用のデータだけを保存する。
こうすれば会員じゃない人は顧客テーブルの参照で済むし、
会員なら会員テーブルまで参照すれば良いだけのこと。
493:NAME IS NULL
11/03/18 22:26:40.26
・注文テーブル (送り先の名前・住所入り)
・会員テーブル (会員の名前・住所入り)
かな。送り先の名前や住所は会員IDではなく注文IDに関数従属
するものだから、別のテーブルに分ける理由がない。
もちろん会員テーブルを過去の更新分も含めてサロゲートキーで
管理して、非会員の情報についても別の顧客テーブルなんちゃら
に分ける方法もあるけれども、無駄にスキーマが複雑になる。
判断は会員/非会員の注文の割合とか(非会員の注文が例外的か)
とかにも依存するけれども、単に注文毎に送り先を保存したい
場合は上のやり方が一番シンプルで良いと思うんだけど。
494:NAME IS NULL
11/03/18 22:29:31.66 N3L942K+
>>484
会員テーブルに、非会員フラグなどのフィールドを入れるということですね?
>>487
> 483は取引後に会員の名前が住所や変更される可能性と、その場合
> も過去の個別の注文に関してはその当時の住所や名前を保存して
> おく必要性(普通は必要だと思うけど)を考えるべきだと思う。
それは全然考えてなかったですね・・・たしかに必要かも。
ということは、
>>492
の方法が一番良さそうですかね?
この>>492の顧客テーブルというのは、注文の住所や名前情報などがはいるんですよね?
注文レコードの数=顧客レコードという認識ですが正しいでしょうか
495:NAME IS NULL
11/03/18 22:33:01.55 N3L942K+
>>493
この方法も良さそうですね
496:NAME IS NULL
11/03/18 22:42:31.73
>>494
・注文テーブル → 注文日時、ステータス、商品合計金額
・(注文商品テーブル) → 注文した商品のIDと価格
・顧客テーブル → 名前や住所
・会員テーブル → ログインIDやパスワード
こう考えてみたらどうだろう
497:NAME IS NULL
11/03/18 22:53:33.73
>>490
?
めちゃくちゃDB設計の話だと思うけど
498:NAME IS NULL
11/03/18 23:00:42.16 N3L942K+
>>493の方法でいいかなと思っているのですが、
>>493の方法と比べて>>496の方法(顧客テーブルをはさむ)のメリットはなにがありますか?
499:NAME IS NULL
11/03/19 00:18:10.77
>>498
>>493の方法の場合、例えば会員から注文があった場合には会員テーブル
から会員の名前や住所を送り先として注文テーブルに転記する必要がある。
会員の名前や住所はそうそう変わらないだろうから、同じ情報がテーブル
中に繰り返し現れるわけで、そういう意味では冗長でストレージの無駄。
>>496の場合は、これがない。
ただ>>496の方法で会員テーブルの結合に会員IDを使ってしまうと、ある
会員の名前や住所が変更になると過去の注文分に関しても送り先の情報が
変更されてしまう。注文履歴の正しい管理という意味でこれは拙い。
なのでこういう場合は会員テーブルに代理キーを立てて結合条件にはこれを
用い、会員情報を変更する場合も古い行はそのまま残して新しい行を会員
テーブルに追加する方法で対応する場合が多い。
言葉だと説明し難いので、過去ログを参照するかサロゲートキーで検索して
欲しい。
いずれにしても、会員/非会員の注文頻度の割合(非会員の注文も多い場合は
>>493のデメリットは相対的に小さくなる)、会員情報の更新頻度、あと
は注文データの件数によると思う。
ストレージの無駄さえ許容できれば>>493は一番シンプルな解だと思う。
500:NAME IS NULL
11/03/19 00:27:12.05
そうか。顧客情報が変更になると注文情報も変更になるから
>>496だと整合性がとれなくなるよな。
>>493の方法は重複が出るけど、「過去○ヶ月のデータまで保存」
みたいな感じで、期限切れのデータは削除するかバックアップすれば
レコードの肥大化も極力抑えられる。
501:NAME IS NULL
11/03/19 01:53:20.02
>>497
しかし>>489は回答にすらなっていない。
要件についてツッコミも考察も入れず「○○パターンで出来るよね~」
なんて真っ先にのたまうのは典型的なプログラマ脳だ。手元の技術しか
見えていない。
502:NAME IS NULL
11/03/19 06:59:20.11
「住所」が顧客の現住所(連絡先)なのか配送先なのか、はたまた配送先の
デフォルト値なのか、そういう分析がしっかりされないまま設計に入っても
議論がワヤになるといういい例だな。
503:483
11/03/19 13:14:35.62 jv8AI/hU
みなさんありがとうございました。助かりました。
会員の注文時の送り先住所は、
会員の住所が変わっても、変えてはいけないというのは盲点でした。
>>493の方法でいこうと思います。
これなら注文毎の住所が保存され、
会員の住所も保存できそうです。
会員の注文のときは、会員テーブルから住所をコピーして注文テーブルへ。
非会員の注文は、そのまま記載された住所を注文テーブルへ格納する。
という実装でいきたいと思います。
504:NAME IS NULL
11/03/19 13:40:41.51
>>502
それは設計しながらでいいんじゃねーの?
仕様書作りながら「これはこういう可能性があるからこうしよう」
みたいな意見が生まれるじゃん。483のやりとり見ても生まれてるわけだし。
505:483
11/03/19 14:55:37.30 jv8AI/hU
まてよ、
>>493
> ・注文テーブル (送り先の名前・住所入り)
> ・会員テーブル (会員の名前・住所入り)
この方法だと、例えば新たに「電話番号2」カラムを追加したいときに、
2つのテーブルをいじらないといけないので、保守性の面であまり良いと言えないかもしれませんね。。。
なので、
・テーブルX
名前、住所などを入れるテーブル(名前が思いつかない。顧客情報テーブル?)
をつくって、
注文テーブルや、
会員テーブルからはテーブルXのIDを外部キーとして保存するという方法を考えました
(それが>>492の方法でしょうか?)
これなら新しい項目が増えても、テーブルXを1つ編集すればいいだけなので解決しそうです。
実装方法は>>503の方法と基本的に同じで、
新たに注文が発生した場合は、
・会員の場合
テーブルXに保存されている会員情報を、
新たにテーブルXのレコードとしてコピーして、このIDを注文レコードの外部キーとする
・非会員の場合
テーブルXに入力値を保存
このような形でつくろうと思います。
またご意見をくださいますでしょうか。
>>504のおっしゃるとおり、一人で開発しているので、
つくりながら仕様も決めていくような方式をとっているので、小出しになっていたら申し訳ないです
506:483
11/03/19 15:04:27.95 jv8AI/hU
まとめると、
- 注文テーブル
・テーブルXのID(外部キー)
- 会員テーブル
・テーブルXのID(外部キー)
- テーブルX
・名前
・住所
・電話番号
:
:
この、テーブルXで名前住所などはすべて管理して、
あらたに会員が「届け先住所2」を追加したい場合は、
テーブルXに新しいレコードを追加して、そのIDを
会員テーブルの「届け先住所2」カラムに外部キーとして保存する、といった形になります。
507:NAME IS NULL
11/03/19 16:00:36.14
そもそも規模によっては住所2が必要ない場合あるぞ。
小規模、顧客1000人以下程度ならいらないと思うけどな。
必要な時に追加したら良いんだよ。
508:NAME IS NULL
11/03/19 16:18:47.06
会員と非会員の注文比はどれぐらい?
非会員の注文数が多いようだと住所項目等を別テーブルに
切り出すメリットはかなり減るよ。
509:483
11/03/19 17:23:23.64 jv8AI/hU
>>508
現行のショップは会員という概念がなかったので、
今回会員を実装してどれぐらい会員になるかは未知数ですね。
ただ、非会員で買い物をするメリットというはあんまり無いので、
(会員になってもパスワードという入力項目が増えるだけ/会員になると今後の住所入力不要)
会員になる人が多くなると予想はしています。
ただ本当に具体的な比率は未知数です。
510:NAME IS NULL
11/03/19 18:10:41.88
会員になる人が多いか否かは商品によるんじゃね?
Amazonのように購入ペースが多いなら会員登録するだろうけど、
電化製品や服とかは、会員登録しなくても買いそうだけどな。
511:NAME IS NULL
11/03/19 18:12:40.61
>>509
まず、
・会員情報に書かれる住所や名前や電話番号
・注文票に書かれる送り先の住所や名前や電話番号
ははっきり区別して考えた方が良いと思うよ。
例えば会員情報としては複数の住所や電話番号を持つことも
あるかも知れない。でもそれを全て注文票に転記する必要が
あるかというと、そうでもないと思う。
書かれている「新たに電話番号2カラムを追加したいときに」
の場合も、会員テーブルは変更する必要はあるかもしれない
けど、注文票にまで複数の電話番号を書き込む必要があるか?
というのは一度精査してみた方が良いと思う。
512:483
11/03/19 20:12:44.29 jv8AI/hU
>>511
たしかに。
やっぱり>>493がシンプルで良さそうだなぁ。
ぶれまくりですが、とりあえず先に進んでみようと思います。
また問題が発見してから考え直します。
みなさんありがとうございました。
513:NAME IS NULL
11/03/19 21:26:29.97
プログラマ脳はどこへ行った?
514:NAME IS NULL
11/03/20 22:16:51.93 77T4BkwY
エンティティとか主キーの概念がなくて
なんでも1テーブルに押し込む、キーはID列のみみたいなのはマジ勘弁
515:NAME IS NULL
11/03/20 22:26:24.40
>>514
大福帳テーブルは意外と重宝しますよ。
516:NAME IS NULL
11/03/20 23:11:01.39
>>515
うん。する。
517:NAME IS NULL
11/03/21 08:13:31.36
NoSQLの設計はまさにそんなかんじじゃない?
518:NAME IS NULL
11/03/23 04:59:34.66
.NETのコンポーネントの制限で複合キーを諦めざるを得ない
519:NAME IS NULL
11/03/23 23:09:03.86 MVHfXd/l
複合キーは無いわ
全テーブルにid int auto_increment でおk
520:NAME IS NULL
11/03/23 23:27:16.79 pi71qtr7
まさにプログラム脳
521:NAME IS NULL
11/03/24 01:02:41.70
>>519
つけるべきUNIQUE制約を忘れるなよ。
つけなければならない理由も。
522:NAME IS NULL
11/03/24 14:48:10.96
>>519
MySQL脳か。
523:NAME IS NULL
11/03/24 22:24:42.09 G0Glp4Mc
今一緒にデータ移行の仕事してる人は業務的には複合キーのデータでも
キー値を1つにマージした列をわざわざ作ってるんだよなあ。
なんでもJOINするときにマージした列でJOINした方が早いとかw
複合キーでもINDEX張ったりすれば遅くないですよって言っても信じてくれない。
524:NAME IS NULL
11/03/25 04:20:43.76
複合キーでもサロゲートでもいいが、キー値のマージは一番アホ設計だと思うw
525:NAME IS NULL
11/03/25 04:42:34.88
とりあえず日時型をキーに追加するアホが身近にいるので困る
526:NAME IS NULL
11/03/25 04:51:01.91
正規化崩しもそうだけど、解っていない人ほど「この方が速い」とか
キリッとのたまうんだよなぁ。
527:NAME IS NULL
11/03/26 12:30:09.50
会社マスタ
CompanyID(PK) , CompanyName
01 A社
02 B社
03 C社
支社マスタ
CompanyID(PK) , BranchID(PK) , BranchName
01 01 本社
01 02 埼玉支社
01 03 神奈川支社
(略)
例示した支社マスタみたいな複合キーが使えない場合、
どういうキーを振るのが普通なの?
CompanyID+BranchIDの連結でやってるけどダメ?
528:NAME IS NULL
11/03/26 17:27:46.83
ダメってことはないけど、CompanyIDとBranchIDを残してunique制約付けるなら
サロゲートキーは別に本来のキーと関係ある値にする必要はない。
529:NAME IS NULL
11/03/26 19:35:25.40
>>527
なぜ複合キーが使えないのかわからん
その例なら、CompanyIDとBranchIDの複合キーじゃないのか?
その例なら単にBranchIDを支社マスタ内で一意になるように振れば良いだけだと思うけど
530:NAME IS NULL
11/03/26 22:15:51.71 Ib5l6n2v
Companyコードはどこにあるの?
531:NAME IS NULL
11/03/26 23:17:25.27 U28l837d
>>527
システム以外の都合でIDが決まる場合が少ない確率ながらある
(ID=1を本社にしたいとか、支社IDを使い回すとか)から、
やっぱり複合キーじゃなくて
全テーブルにIDを振るのがいいと思うんだがなぁ
なんでこのスレの人は否定するのかね
532:NAME IS NULL
11/03/26 23:50:53.54
>>531
いや、普通に脳みそ足りなさそうな発想だから否定されて当然。
別に誰も代理キーを絶対に使うななんて言っていないでしょ。
要件をスキーマ設計に落とす過程で必要になった時に用法に注意
して使えば良いだけの話。
そのあたりをすっ飛ばしてトップダウンに「全テーブルにID振る」
なんて単細胞なアイデアを持ち出すから叩かれる。
533:NAME IS NULL
11/03/27 05:15:34.98
支社マスタ
BranchID(PK) , BranchName
0101 本社
0102 埼玉支社
0103 神奈川支社
複合キーが使えないケースならこうせざるを得ないだろ
無関係なサロゲートキーでどうやって会社マスタとの紐付けを取る気だ
534:NAME IS NULL
11/03/27 07:04:25.57
サロゲートキーを使うならこうだろ。
BranchKey not null,
CompanyID not null,
BranchID not null,
primary key ( BranchKey ),
unique( CompanyID, BranchID )
「複合キーが使えない」というのが複数カラムのUNIQUEも使えないという
意味なら別だが。
535:NAME IS NULL
11/03/27 15:12:06.00
複合キーが使えないってのがどういうことかわからんが
おそらく
CompanyID(PK) , BranchID(PK) , BranchName
01 01 本社
02 01 本社
みたいなことを想定してるんだと思うが、それなら
支社マスタって書いてるテーブルが、支社のマスタと
会社と支社のリレーション持ってるテーブルを兼用してるのが間違いだろ
536:NAME IS NULL
11/03/27 15:41:43.57
それのどこが間違いなのかわからん。
537:NAME IS NULL
11/03/27 15:45:16.49
多分どっちでもいいんだよ。
どっちかしか駄目という人が間違ってる
538:NAME IS NULL
11/03/27 16:19:08.97
>支社マスタって書いてるテーブルが、支社のマスタと
>会社と支社のリレーション持ってるテーブルを兼用してるのが間違いだろ
なんで間違いなん?
539:NAME IS NULL
11/03/27 17:25:52.72
>>535
それが間違いだとして、テーブルを分けたとしても、その場合
会社支社リレーションのテーブルで同じ問題が起こる
そこが間違ってるかどうかは本質じゃない
じゃあ本質は何かっていうと
>複合キーが使えない場合、どういうキーを振るのが普通なの?
ってことだ
複合キーが使えない理由がよくわからんが、複合キーがダメなら代理キー作るしかないわな
代理キーの値をどうするかだが、ぶっちゃけ一意になれば何でも良いわけで
システム的に一意な連番振る機能があれば、それが使われることが多い
その場合は一意であることをシステム側で保障できるから
CompanyID+BranchIDの連結とかでもいいけど、その場合、それが一意かどうか
自分でチェックしないと保障されない
まあどっちにしろ要件的にCompanyID+BranchIDで一意チェックは必要だと思うから
この二つで主キーにしとけばシステム的に一意性が担保されるわけだが
540:NAME IS NULL
11/03/27 19:55:32.48
たいていの場合CompanyID+BranchIDが一意になるとは思うが
仮にCompanyIDないしBranchIDを変更することになった場合
キー値も変更しないと気持ち悪いことになる
541:NAME IS NULL
11/03/27 20:09:12.32
連番使った場合はCompanyIDとBranchIDから代理キーの値を得るのに
支社テーブル上で逆引きをする必要があるけれども、CompanyIDと
BranchIDの連結をキーにした場合はアドホックに文字列処理でキーの
値が手に入るという利点は一応あるw
ただそういう設計や運用はあまり見ないよなぁ。やはり勘所は複合キー
が使えないという理由がよく分からん事だと思う。
ORMマッパー使っているからとか、DBMSの実装上の制約とか、上司の
オッサンが決めてしまったコーディング規則でそうなっているとか、
理由ごとに必要とされる答えも微妙に違う気がする。
542:NAME IS NULL
11/03/27 20:17:45.17
>上司のオッサンが決めてしまったコーディング規則でそうなっているとか
これに500点
543:NAME IS NULL
11/03/28 02:42:35.68
いや、単純にコンボボックスのデータソースに出来ないからだよ
544:NAME IS NULL
11/03/28 02:51:30.55
CompanyIDを先に選択させりゃいいだろ
545:NAME IS NULL
11/03/29 11:09:24.60 1gjc3MDS
>>532
無知で悪いけど、
「全テーブルにID振る」
これのデメリットってなにがあるの?
546:NAME IS NULL
11/03/29 13:14:53.99
>>545
何の解決にもなっていないから。
連番をカラムとして追加してそれをテーブルの主キーにしたところで
「要件によって決まる」候補キーは歴然として存在するわけであって
そこに制約をつけたりアプリケーションのロジックを書いたりしないと
結局はデータの整合性は保たれないから。
「全テーブルにID振る」は実装上の方法論にすぎず、その前段階として
要件の分析をすっ飛ばすことは出来ない
ちゃんと分析をやった上で全テーブルに代理キー振るのなら、いいん
じゃない? ただその場合は当然分析の結果として必要な代理キーと共に
冗長な代理キーも見えてくるはずで、その評価は出来るよね。
547:NAME IS NULL
11/03/29 16:32:09.66
もう少し馬鹿にもわかりやすく答えてくれ
548:NAME IS NULL
11/03/29 17:11:30.69
全テーブルにID振ること自体は「無駄」以外にデメリット無いよ。
OracleのROWID疑似列みたいな例もあるわけだし。
ただそれを無批判に主キーとして用いるのにはデメリットというか
危険性がある。例えば自然キーが存在するのを忘れてUNIQUE制約
を付け忘れたため危険な重複タプルが発生したりとか、変更の可能性
が無い自然キーに対しても代理キーを用いることでトランザクション
表の更新時に自然キーから代理キーの値を得る無駄な逆引きが必要に
なったりとか。
代理キーを持ち込むことで検索はともかく更新は一般的に複雑に
なりやすい。
個人的には要件の見落としを防ぐ意味でも、まず初めに自然キーを
主体にしたスキーマ設計に落として、そこから必要に応じて代理キー
を導入するのが一番安全だと思う。
何度も言うけれども、自然キーはまず要件から決まるものだから。
549:NAME IS NULL
11/03/29 17:54:47.01
>表の更新時に自然キーから代理キーの値を得る無駄な逆引きが必要
いや別にいらんだろ
自然キーのユニークネスが保証されてるなら
550:NAME IS NULL
11/03/29 22:02:11.24
外部キーとして持つ場合なんかの話だろ
551:NAME IS NULL
11/03/30 01:03:54.95
CREATE TABLE tablename (keyid VARBINARY(50) , columnid VARBINARY(50) , value BLOB , PRYMARY KEY(keyid , columnid));
ですべてことたりる
552:NAME IS NULL
11/03/30 01:56:16.14
その分アプリのロジックで苦労するわけだけれどもね。
553:NAME IS NULL
11/03/30 18:31:30.02
>>551
ガリレオ・ガリレイ
554:NAME IS NULL
11/03/30 23:04:14.47
このスレと
【より良い】データモデリング【モデルを】
スレリンク(db板)
こっちのスレって何が違うの?
上流の作業の違いがいまいちよくわからん
モデリング後に設計?設計後にモデリング?
555:NAME IS NULL
11/03/30 23:57:39.00 1ro9g/Hl
住所の項目ってどうしてるよ?
都道府県と住所1と住所2(マンション名など)
って分け方が多いみたいだけど、
都道府県以外分ける必要ないよね
556:NAME IS NULL
11/03/31 00:09:50.64
>>555
たとえばタックシールや送り状を作成する業務を考えると
住所が適当な長さで2行になってる方が都合がいいだろ
業務要件で住所が2行必要ならDB上も2項目でもつのは普通
つまり分ける必要があるかどうかは要件次第
557:NAME IS NULL
11/03/31 00:18:34.96 P2ST+s4H
2行かどうかなんてアプリケーション側の問題なんじゃ?
558:NAME IS NULL
11/03/31 00:40:24.56
要件に二行で折り返すことが含まれているのであれば、どこで
折り返すのか区切りが解らないと困るじゃん。
改行入りの文字列を住所として突っ込むのもありだけど、住所と
マンション名その他に分けて二つのカラムに分けて入れることが
多いと思う。
559:NAME IS NULL
11/03/31 00:40:37.54
アプリケーション側の問題?
データモデルが常にそれらから独立していられるわけでもないだろう。
560:NAME IS NULL
11/03/31 01:27:27.86
>>555
+--id--+--henji--+--syugo--+--dousi--|
| 1 | YES | I | DO |
+----------------------------------+
561:NAME IS NULL
11/03/31 20:36:43.35 WO6NrX3S
>>555
> 住所の項目ってどうしてるよ?
郵便番号が取得できるなら郵便番号DBを利用する
できないなら総務省の地域コードを使う
コード変換できない番地以下は各レコードに持たせる
最低でもこうしないと話にならない
562:NAME IS NULL
11/03/31 20:53:20.54
DB的には住所をコード化するのが先決だわな
2行でタックシール(キリッ)とか馬鹿じゃねえの
563:NAME IS NULL
11/03/31 21:52:14.51
単に土地住所と建物住所じゃないの?
564:NAME IS NULL
11/03/31 22:57:25.26
タックシールの馬鹿を見るだけで、全角英数は馬鹿という定説が正しいことがよく分かる
565:NAME IS NULL
11/04/01 00:06:20.96
DB的には氏名をコード化するのが先決だわな
566:NAME IS NULL
11/04/01 00:35:02.02
「コード化する」ってなに?
567:NAME IS NULL
11/04/01 00:42:28.28
たっくんおかえり
568:NAME IS NULL
11/04/01 00:48:36.32
(国)、都道府県、市町村、町域、建物その他で分けるだろ
569:NAME IS NULL
11/04/01 07:05:20.44 QNKMILe9
郵便番号検索とかどうしてる?
新しい市町村増えたり、メンテが面倒そうなんだけど
570:NAME IS NULL
11/04/01 07:09:15.74
そうだよ。
だから郵便番号検索機能が仕様にある場合はメンテ分も見越して金額が跳ね上がらないといけない。
現実は「簡単でしょ?付けてよ」でプロジェクト終わり。
571:NAME IS NULL
11/04/01 07:25:43.06
要件確認せずに、「だろ」って決め付けてもねぇ。
地番は?住居表示はどうすべきだと思ってるの?
572:NAME IS NULL
11/04/01 10:02:49.85
初心者ですDBの勉強もかねて、簡単なユーザ登録のできるBlogサイト作成しようと思っています。
日記のデータを保存するテーブルについて質問なのですが、一般的(他のサイトなど)に日記を保存している
テーブルというのは、1つのテーブルで全ユーザの日記のデータを保存しているのでしょうか?
例えば一般的には、ユーザID,日付,日記本文,(その他省略)という構造なのでしょうか?
この場合、ユーザ数が増えれば相当なデータサイズになり、1ユーザの日記を数日分、selectするのに時間が
かかるような気がします。(この辺が初心者で、時間がかかるのかもよくわかってないのですが・・・)
573:NAME IS NULL
11/04/01 11:09:31.44
まぁそのためのデータベースだ
適切な設定なら100万レコードからでも一瞬で目的のレコードを探せるよ
574:NAME IS NULL
11/04/01 22:51:49.57
それだと、日記が一日ごとにしか書けないな。
575:NAME IS NULL
11/04/01 22:54:03.22
適当な質問には適当な回答しか無いだろ
576:NAME IS NULL
11/04/02 02:10:35.17
お前ら、こういうDB設計の要件定義って、
仕事でやる場合どのくらい時間かける?最低1ヶ月はかかるよね
577:NAME IS NULL
11/04/02 02:18:13.66 SR6eBDqn
>>570
そういう情報ってどっかにAPI公開されてないのかな
もしくはデータが簡単にダウンロードできたり
578:NAME IS NULL
11/04/02 02:41:31.19
>>577
データは郵便局サイトに
コンポーネントもググれば簡単に見つかる
大概↑データを使用する前提
579:NAME IS NULL
11/04/02 09:09:49.55
つーか、ろくすっぽ調べず「郵便番号メンテが面倒」とか、「住所は二行でタックシールだ!」
とかその手の足りない子を見ると、正規化だのサロゲートキーだのを熱く語る前に、他にやるべき
ことあんじゃねえのって感じだな
580:NAME IS NULL
11/04/02 12:53:38.07
なんか、面倒だな
581:NAME IS NULL
11/04/03 15:32:48.21
それでも地球はまわっている
582:NAME IS NULL
11/04/03 17:10:43.94
そして原発は冷却中である
583:NAME IS NULL
11/04/03 23:20:21.80
>>568
そんなの、実データ使った解析でいかようにもできる。
客が入力したままの文字列を一つだけ保持しておけば、あとは正規化した住所を都度アプリ側で吐き出せばいい。
584:NAME IS NULL
11/04/04 00:39:15.82
>>583
アプリに全部任せてDBは設計もクソもなくていいって聞こえるが・・・
585:NAME IS NULL
11/04/04 00:47:44.84
座標保持するのが流行り
586:NAME IS NULL
11/04/04 06:56:16.69
>>585
ダイレクトメールという文化はやがて滅びるから
企業の視点では、住所や所在地情報の地位は
低下し続けるに違いない。
587:NAME IS NULL
11/04/04 07:51:03.48
>客が入力したままの文字列を一つだけ保持
こんなこと書いてるエセ設計者の言うことは無視でよろし
588:NAME IS NULL
11/04/04 19:32:50.57
エセというか、ただの馬鹿だろ
せっかく公共団体の統一コードがあるのに文字列で持たせるとか正気か?
どうせAccessあたりで糞アプリ作ってる底辺プログラマだろけど
589:NAME IS NULL
11/04/04 20:51:35.27
DM用や顧客用のデータなんだろ?
正規化用のデータを、持しても客が使うデータは、たとえ間違っていても入力のママで使うんだよ。
現場も知らない馬鹿が教科書通りに設計すると回らないから気をつけろw
590:NAME IS NULL
11/04/04 22:22:53.14
正規化と言いたいだけの中小企業Access使いとか、底辺を見ても何の参考にもならないし、
時間の無駄だから、まともな知能を持った人は郵便番号DBや地方公共団体コードを使いましょー
591:NAME IS NULL
11/04/04 22:23:08.98
馬鹿にしてるつもりなのかな?拙い日本語使って煽られてもねぇ・・・
592:NAME IS NULL
11/04/04 22:54:36.58
ハンマーを持った子供には何でも釘に見える
地方公共団体コードなんて覚えたての子供は、「住所」と出てきたらコードを
使わなきゃ気が済まないんだよ。
593:NAME IS NULL
11/04/04 23:40:02.69
まあ、要件も確認せずに何とかコードでOKとか言うやつは
まともな知能を持ってないってのは解る
あと底辺の人ほど他人を底辺だって決めつけるよな
バカっていうやつがバカ的な感じ
594:NAME IS NULL
11/04/04 23:46:14.17
たっくんおかえり
595:NAME IS NULL
11/04/05 00:53:48.93
>>590
名寄せのロジックの一部には郵便番号DBも使うが、あくまでも一部。
おまえ、日本全国の何百万という重複する住所の名寄せなんてしたことないだろ。
したことがあれば、あんな不完全なデータを錦の御旗にドヤ顔出来る訳がない。
596:NAME IS NULL
11/04/05 07:29:40.55
>日本全国の何百万という重複する住所
具体例どぞ
597:NAME IS NULL
11/04/05 07:33:04.51
>>596
どこそこ区の青葉台となになに市の青葉台で一例。
この組合わせを合計するとそんな数になりそう。
598:NAME IS NULL
11/04/05 08:24:56.02
>>597
そういうのは都道府県が違うので重複とは言わない
もっと例示するにふさわしい具体例を挙げるよろし
599:NAME IS NULL
11/04/05 08:53:52.43
>>596
数十万単位のユーザーが十数年にわたって複数回入力する住所の名寄せだよ。
当然ユーザーからしてみれば同じ住所でも入力パターンは間違いも含め多岐に渡り、市町村合併や郵便番号も変わるからね。
600:599
11/04/05 09:10:15.59
他にも英語表記やカタカナ、ひらがな表記も含む。
市区町村の区分も守られておらず(特に町と村。そもそものインターフェースが郡で区切ってたりする)、都道府県が空白なんてざら。
複数のインターフェース、複数の時代を経た巨大な住所データなんて蓋を開ければこんなもん。
入力時に住所が正規化される単一のシステムならなんの問題もないけど、そうでない上記のようなデータなら、住所は一旦すべて連結し、解析掛けるのが正確で早い。
601:NAME IS NULL
11/04/05 09:13:12.42
だからコードにしておけば手入力を解析だ名寄せだとかキチガイじみた発想にならんのだって
ためしに通販サイトかなんか見てみろよ
大抵、プルダウンから選択か、郵便番号から選択だろが
逆に手入力のメリットがあるなら出してみろや
602:599
11/04/05 09:24:48.43
>>601
日本語分かるか?
入力時に正規化出来るなら問題ないがと書いてるだろ。
新規で開発するような話をしてるんじゃなくて、手書きも含め、複数のインターフェースが存在することが前提のデータ処理の話をしているんだが。
603:599
11/04/05 09:28:14.95
>>601
そして、コード化の一番のデメリットは過去の住所はにたいおうしづらい
604:599
11/04/05 09:37:39.53
>>601
失礼、途中で送信してしまった。
コード化のデメリットは過去のデータに対応しづらいという事。購入、決済データぐらいじゃそこまで気にする事はないし、下手すればそもそもの住所の正規化すら要らないケースが多いけど、
過去にさかのぼる名寄せみたいに、コード化よりも解析のほうが現実てきなケースがある事を知っておいて損はない。
605:NAME IS NULL
11/04/05 18:49:22.35 Ge8zwV8y
>>602
> >>601
> 日本語分かるか?
> 入力時に正規化出来るなら問題ないがと書いてるだろ。
名無しIDなしでお前のレスがどれだかわかるわけねーだろw
つーか、DB設計の話をしてるのに名寄せだ解析だとか言い出すから、
頓珍漢に拍車がかかるんだっての
データ移行が要件なら、その解析とやらに使う労力を変換に割り振れよww
言ってることが支離滅裂だっつーのw
606:NAME IS NULL
11/04/05 19:31:24.00
>>605
要するに何の話をしているんだい。
607:599
11/04/05 20:05:05.66
>>605
わざわざ599と入れてるのも分からない馬鹿かw
だから、DB構造としては、住所は一つまのカラムしかもってない(まあ郵便番号くらいは持つが)と言う事だよ。
一応、入力時は分割されてるが、それを連結したものが正式なデータとしてつかわれる。
正規家した住所は複数のカラムを持つが、それは都度都度の最新住所を吐きだすワークテーブル扱い。
高言う実例もあるんだよ。
608:NAME IS NULL
11/04/05 20:20:17.47 Ge8zwV8y
>>606
・住所をまんまの文字列で持つメリットは全くない
・文字列を保持して解析とか言ってるのは池沼
・名寄せとかいきなり言い出してるのは馬鹿(同じやつだろうけど)
・タックシール(キリッ
ちなみに文字列解析が現実的とか、噴飯ものの物を知らない子
みたいだけど、世の中にはコンバータってのが売っていてだな、
それで変換できないのは、対象外にするか、客先マターにするか、
その辺は契約にもよるけど、少なくとも俺らが住所と関わるって
のはそういうもんなの
いくら底辺プログラマで単価が安くても、アホな設計の尻拭いに
工数かけて解析とかありえねーよw
コンバータ買ってもらえって
とここまで書いたらタックシールが性懲りもなく現れた
もはや解読困難で相手にすんの面倒くさいから、他の人に任せる
といことで逃亡
609:NAME IS NULL
11/04/05 20:22:29.70
大変だなぁ。で、設計の話はどこ?
610:599
11/04/05 20:50:16.33
>>608
コンバーターは、それぞれの企業が自社で使う必要があって開発したものなことも知らないのか。
どんだけ小さな現場しか知らないんだよw
入力データを正規化して保持して、オリジナルを破棄出来るなら苦労はないんだよ。
自分の知らないしくみがあることは恥でもなんでもないのに、実例紹介してるのに信じないなら勝手にしろw
611:NAME IS NULL
11/04/05 20:50:39.64
変換ソフトの稟議書作成じゃね?
612:NAME IS NULL
11/04/05 20:53:18.81
>>610
設計の話しないなら帰れよ。
613:NAME IS NULL
11/04/05 21:00:32.80 r6xQc+hf
コンバータってこれか
URLリンク(www.addressmatch.jp)
昔住んでいた埼玉県大宮市高鼻町で検索したら、一発で変換できた!
オラ良いこと知ったぞ
でももう埼玉は住みたくない
614:NAME IS NULL
11/04/05 21:20:38.76
正直、なぜこんなのでこの人たちがここまで熱くなれるのか疑問ではある
615:NAME IS NULL
11/04/05 21:28:27.96
かつてクラス名簿を頼りに好きな娘の家の住所を探し歩いた経験からです
616:599
11/04/05 21:31:55.96
>>612
一応、設計上、住所がひとつの構造の実例もあるよ、という話だったが...
まぁ、確かにそろそろスレチだな。失礼。
617:NAME IS NULL
11/04/05 21:37:41.55
スレチ以前になんの参考にならないからもう出てこなくていいお(^^
618:NAME IS NULL
11/04/05 23:55:16.74
厳密に言えば設計じゃないのかも知れんが、要件定義、モデリングの話題としては興味深い。
619:NAME IS NULL
11/04/06 00:54:23.79
市町村コードと住所正規化コンバータの存在は確かにためになった
サロゲート談義よりよっぽど
620:NAME IS NULL
11/04/06 09:28:28.56
このスレ市町村コード知らない人が見てたのか
621:NAME IS NULL
11/04/06 09:29:53.92
>>620
私は公的なものは大嫌いだから。
622:NAME IS NULL
11/04/06 09:42:58.98
よくわからんけど、話題終了した方がよさそうなのはわかった
623:NAME IS NULL
11/04/06 09:50:12.87
>>621
ねっこのおりん
624:NAME IS NULL
11/04/06 20:40:10.84
「都道府県がなぜ北海道始まりなんだ!」と言われたらJISを参照する
625:NAME IS NULL
11/04/07 16:18:49.41
>>621
ただの馬鹿ですね
626:NAME IS NULL
11/04/07 20:22:35.53
まあ市町村コードなんて、馴染みのない人には全くない系統の知識だからね
いつなんどきどういう案件が降ってくるか分からないんだから、普段から
色んなことにアンテナを張っておくことが大切だってことさ
627:NAME IS NULL
11/04/08 01:02:53.18
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
> 色んなことにアンテナを張っておくことが大切だってことさ
628:NAME IS NULL
11/04/08 04:33:07.53
それで結論として、
住所はユーザが打ち込んだひとつの欄でいいね。
エラーがあるかとか、いろいろ解析するのが楽しみでね。
629:NAME IS NULL
11/04/08 08:59:30.25 UUNyLKi3
はいはい、タックシールタックシール
630:599
11/04/08 09:52:11.62
>>628
結論は、色々なケースがある、だろ。
住所一つ厨も、自分のケースは特殊と言ってたろ。
631:NAME IS NULL
11/04/08 12:25:56.73 UUNyLKi3
その場かぎりのアンケートみたいなのは使い捨てでいいんさ
顧客情報が絡んで将来的にDWH的な使い方がありえるんなら、
コード化にコストを費やすことを考えなくちゃならない
つか、そう提案すべき
632:NAME IS NULL
11/04/11 17:06:53.99 9HYaTenG
ちょっとご相談というかむしろどのような方法が一般的なのか判らない状態での質問です。
DBはSql鯖2008R2 アプリはC# WinFormで作成しています。
現在開発中物件で 営業時間・毎週休業日・祝祭日・臨時休業・臨時営業 の設定が必要なシステムを作成する事になりました。
今考えているのは各設定を年度毎にもち
確定された時点で1年分のカレンダーデータを一気に作成(1年分のレコードを作成)
修正された場合、修正日以降のカレンダーデータを変更する
ような感じで設計してみようと考えています。
カレンダーデータは
年月日
営業開始時間
営業終了時間
種別(0営業 1臨時営業 2定休 3祝日 4臨時休業 )
のような感じで1年分を作成し保持しようかと・・・
伝えたいことがうまく伝えにくいのですが、休日を柔軟に設定する事が出来て、
営業時間・休日のデータが簡単に取り出せる・判定できるようなテーブル設計を行いたいのです。
なんらかの定石的な方法があるのであればいいのですが、そのようなものは社内にないようでして・・・
何らかのヒント的なものでもいいので、お手すきの方がいらっしゃいましたらご教示いただければと思います。
633:599
11/04/11 23:53:09.51
>>632
種別が一つじゃ、臨時営業だけど、実は定休でなおかつ祝日の日とかどうすんだよw
種別は全部バラしてマスタにしろ。
それぞれの重み付けは固定ならアプリで持ってもいいし、変動するならこれもマスタにする。
634:NAME IS NULL
11/04/12 00:25:33.31
>>632
今考えてみた
T/種別( ID 名称 )
T/ルール( 月 日 曜日 何週 優先度 開始 終了 種別ID )
T/カレンダー( 年月日 開始 終了 種別ID )
V/カレンダー( 年月日 開始 終了 曜日@年月日 何週@年月日 種別ID )
カレンダーをデフォルト値で1年分生成してからルールを適用する
俺ならこうするかも知れない
635:NAME IS NULL
11/04/12 07:21:40.99
>>632
例えば、毎週休業日が年に三回変更になったとして、
そのルール・ログが残らないような設計はおかしい。
毎週休業日
---------------------------
休業日起点 | 休業日終点 | 曜日
というようなテーブルを定義していくべき。
636:NAME IS NULL
11/04/12 10:01:08.49
おはようございます。
>>633->>635
お時間を割いていただきありがとうございます。
皆さんの意見を参考に考え直してみました。
結果以下のような感じに・・・皆さんから見るとまだまだ設計力が足りませんが
TM_祝日(年月日{pk}、祝日名)
※祝日は基本固定なんで年更新処理で1月n週や固定日などから生成し、変更可能に
TM_毎週休業日(適用開始日{pk}、適用終了日{pk}、曜日番号{pk})
※休日は現在毎週n曜日のみでいいらしい。毎月n日とかその他のが出たらマスタ増やして対応
TM_臨時休業(年月日、備考[理由])
TM_臨時営業(年月日、営業開始時間、営業終了時間、備考[理由])
TM/営業時間(適用開始日、適用終了日、曜日、営業開始時間、営業終了時間)
※毎週土曜は半ドンらしくこういった持ち方もあり?
TM_カレンダー(年月日{pk}、{pk}に対する曜日、{pk}に対する第hoge週,営業開始(null有)、営業終了(null有)、備考)
※開始・終了のいずれかがnullなら営業してない(片方だけnullはありえない)
※備考は祝日\r\n臨時営業とかの情報をマスタ変更時に残すようにする
上記TM系のマスタ条件でカレンダーを生成
マスタ変更時は影響範囲のカレンダレコードだけを同時に書き換え
(優先度は 臨時営業>臨時休業>定休>祝日 カレンダーデータ作成時に固定となる)
TM_カレンダーは(年月日{pk}、{pk}に対する曜日、{pk}に対する第hoge週)だけを持ち、
ビューやストアドなどで結果を返すほうがデータの無駄が無いかもしれませんが、
参照の回数とかを考慮して少しデータ量が増えますがあえてテーブルに書き込むようにしてみました。
設計て難しい、でもこれしっかりやらないとアプリがグダグダになってしまうので
妥協範囲を出来るだけあげてキッチリやっておきたいです・・・
637:634
11/04/13 00:29:50.20
曜日、何週をビューで定義したのはバグとミスオペでの変更を抑える為
634の形ではルール適用で必要になるから持ってる
636の形はよく理解できてないけどあんまり必要じゃない気がする
ぱっと見TM_祝日はハッピーマンデー対応できない気がするけど毎年修正するのか?
>>635
毎週休業日の変更とかどの業種でもかなり大きい変更だから年数回どころか数年に1回だと思うけど
638:NAME IS NULL
11/04/13 00:48:02.58
>>637
TM_祝日は基本年次処理でつどつど祝日をyymmddで保持するっぽいから、ハッピーマンデーも問題ない気がする。
639:NAME IS NULL
11/04/13 00:57:50.12
>>638
そこでやるのか~
ずいぶん高度だな
640:NAME IS NULL
11/04/13 05:27:11.25
>>639
高度というか、力技だな。単純だがそれがいい。
管理者も入れ替わり、運用がおざなりになったときに、日付の入力を忘れたり間違えたりして支障が出る可能性は高そうだがw
641:NAME IS NULL
11/04/13 09:51:31.28
>>637-640
色々なご意見ありがとうございます。
>>637
いや、正直日付から週数や曜日は簡単に出るんですが、試しに入れてみたらそのデータがあるとDBを生で見たりする場合に
判りやすじかったのでパクらせてもらいました。
祝日に関してですが
年次更新時にデフォルトできっちりデータは入れてやります。(全て入力とかは間違えるし厳しいと思うので)
その為にプログラム内で1月1日は元旦、1月の第2月曜日は成人の日などの情報を持ち
その情報からレコードを作成してやります。
基本的に祝日定義や名称の変更があるんでその部分をDLLなり設定ファイルなりにして
変更時にアップデートでファイルの差し替え、年次更新時にそのデータ利用して一覧を作る
という感じです。
祝日の定義が変る可能性が非常に高いので、もし何らかの理由でこちらの対応が間に合わない場合、
何かユーザー側での変更可能な方法が必要かなと思いベタベタな実装にしました。
(今の政府は年度開始時に年度末の休日定義とか平気で変えてきそうなので・・・)
※地方によって祝日定義変わるとかホント勘弁してください。 ほんと苦肉の策です ありがとうございました。
後他の入力に関してですが
正直オペミスはあるとおもいます。なので入力チェックとかキツキツにする必要はあると思います。
(年次更新時に定義の範囲が今年度にかぶってない場合は出来ないとか)
PS.
仕様書・設計・レビュー・PG・デバッグ・設置と納品まですべて一人でやらなきゃいけないので頭が沸いてきました。
642:NAME IS NULL
11/04/13 10:00:34.82
>プログラム内で1月1日は元旦、1月の第2月曜日は成人の日などの情報を持ち
>その部分をDLLなり設定ファイルなりにして
なぜそれをDBに格納しないのかね
643:NAME IS NULL
11/04/13 10:14:53.39
>>642
年次更新のタイミングでその情報をDBへ格納します。
定義が変る可能性が高いので年次でギリギリまで登録待ってから登録→もし年内で変更あれば手動で変更
という予定です。
644:NAME IS NULL
11/04/13 23:30:26.66
ハッピーマンデーも将来無くなる可能性がある。
祝日をyyyy/mm/ddで持つのもありだね。
645:NAME IS NULL
11/04/14 20:42:54.35 2zZWkF3S
>>643
その年が変わってから、
その年の休日が変わる可能性なんてないよw
646:NAME IS NULL
11/04/14 20:55:04.90
>>643
>定義が変る可能性が高いので
変わる可能性が高い情報をプログラム側に持たすのか?
休日の定義もDBにもたせて、その定義から年次更新でマスタ作成すればいいだろ
647:NAME IS NULL
11/04/14 21:18:24.25
休日の定義を持たせたら、その休日の定義の有効期間まで保持しなきゃならなくなる。
だったら、素直にyymmddで休日を持たせたほうが話が早い。
648:NAME IS NULL
11/04/14 22:15:42.63
過去となった祝日は絶対に不変なのだから、yyyy-mm-ddで決め打ちでいいと思うけどな~
649:NAME IS NULL
11/04/14 22:51:22.94
祝日どころか全部過去適用なしなんだから有効期間ってのがなぜ必要なのか意味が分からない
単に、ルールで持てば?展開して日付で持てば?って話のような気がするけど
650:NAME IS NULL
11/04/14 23:07:13.39
>>649
例えば、極端な話、元日が1月1日ではなく、1月10日に変更になったとする。
当然、過去の1月1日には適用できないので、いつから元旦が1月10日になったのか日付を保持する必要があるだろ。
651:NAME IS NULL
11/04/14 23:11:40.13
別にないよ。
2010/01/01
2011/01/10
って持っとけばいいだけだから。
652:NAME IS NULL
11/04/14 23:17:29.01
>>651
だから、それでいいじゃん、と言ってるわけだ。
休日のルールを定義づけして、DBで保持する必要はない。
653:NAME IS NULL
11/04/14 23:57:19.08
>>650
ごめん、>>646の解釈が全然間違ってて見当違いなレスした
生成よりも反映でやった方が色々いい気がするけどなぁ
延々増え続ける祝日テーブルとか嫌だわ、俺は
654:NAME IS NULL
11/04/15 00:20:06.76
おめーの好き嫌いはどうでもいい
655:NAME IS NULL
11/04/15 00:54:12.36
>>654
ちょっと笑ったw
それにしても、ID出ないと議論もまともにし辛いね。
IDなしでもOKの理由ってなんかあるんだっけ?
656:NAME IS NULL
11/04/15 05:30:37.26
>>653
反映ってのが、ルールを動的に適用するって言う意味なら
ハッピーマンデーや春分の日を動的に適用するのが難しい
逆に、定休日の変更とか考えると動的に適用する方がいいかもしれん
ただ、生成にしても反映にしても、過去分切り捨てないなら
延々増え続けるのに違いはないと思うが
生成あるいは反映されたカレンダーをどう使うかにもよるだろうけど
変更の頻度とカレンダーを使う際のパフォーマンスとか考えると
俺なら適当なタイミングで生成する
657:NAME IS NULL
11/04/16 00:12:24.94
まさに今度の案件で、FROM年月日、TO年月日で営業日やそれ以外を保持する必要が出た。
祝日などは FROM:2011/01/01 TO:2011/01/01 名称:正月
658:NAME IS NULL
11/04/16 16:59:35.02
夏休みでもないと1日単位の方が効率的な感じだな
659:NAME IS NULL
11/04/16 17:41:05.38
こういうテーブルは差集合を取るために使うことが多いしな。
1日1レコードの方が何かと無難に思える。
660:NAME IS NULL
11/04/17 09:08:09.05
ここのスレのひとたちのレベルとは違いすぎるんで恐縮なんですが、、、
インデックスって何に設定するのが良いんでしょうか。
たとえば、掲示板の投稿テーブルとかだとなににインデックスを設定したらいいでしょうか
661:NAME IS NULL
11/04/17 09:13:32.97
検索キーに張ればいいよ。
662:NAME IS NULL
11/04/17 09:31:24.55
>>661
検索対象となりえるフィールドってことでしょうか。
今は名前と、本文メッセージで検索できるようにしてるので、
それらにINDEXつけたらいいのかな?
663:NAME IS NULL
11/04/17 09:35:35.93
名前はアリだろうけど、本文メッセージはインデックスの意味ないだろうね。
664:NAME IS NULL
11/04/17 09:59:15.72
>>663
文章が長すぎるからですか?
あと、
postテーブル (投稿
tagテーブル (タグ
こういう2つのテーブルがあるとして、
postテーブルに複数のtagがつくような場合(多対多であってますか?)
postとtagを結びつけるテーブルが必要だと思いますが、
このテーブルの名前がいい感じのが思いつきません・・・。
みなさんこういうテーブルは何テーブルと名づけてますか?
post_tag_relation
とかかな?
665:NAME IS NULL
11/04/17 11:55:47.26
テーブル名はそのものズバリの短い名称ならなんでもいい、SQLでの記述量が全体的に減る。
短くなるならローマ字表記もありだと思う。
666:NAME IS NULL
11/04/17 12:58:08.73
>postとtagを結びつけるテーブルが必要だと思いますが、
そもそも直に結び付かないのがなぜかと問いたいが。
関係性が複数あってアナリシスパターンみたいに知識レベルと操作レベルに分けたいならともかく。
667:NAME IS NULL
11/04/17 13:26:25.07
>>665
短縮しようとすると必然的に漢字になる。
668:NAME IS NULL
11/04/17 13:58:57.30
>>666
postテーブル
id title name message
1 投稿テスト ななし てすです。
tagテーブル
id name
1 タグ1
2 タグ2
post-tagテーブル(ナイスなネーミングが思いつかない)
id post_id tag_id
1 1 1
1 1 2
↑
表にするとこんな感じです。
3つ目のテーブルがないと結びつかないと思いますが・・・できます??
669:NAME IS NULL
11/04/17 15:01:12.87
いや、あってるよ。
それと、本文を高速に検索するには形態素解析とか別の技術がいる。
670:NAME IS NULL
11/04/17 15:05:04.50
>>669
ありがとうございます。
え、%LIKE%でやってて、全く問題なく動いてるんですけど、
書き込み数が少ないからいけてるだけなのかな
671:NAME IS NULL
11/04/17 17:00:42.33
LIKE句で早いかどうかはDB側のエンジンに依ると思います。
672:NAME IS NULL
11/04/17 17:19:18.92
ネーミングは、『R_投タ』だろ?
673:NAME IS NULL
11/04/17 17:31:36.42
件数とフィールドサイズ次第じゃね?
674:NAME IS NULL
11/04/19 00:35:20.25
1 業務の区分番号で自然キー設計した
2 削除履歴も残したくて削除フラグを作った(行を複製して削除=1する)
3 削除フラグを立てた行を作るとキーが二つになってしまう!
4 履歴を沢山もてるように削除日を作った
5 (自然キー + 削除フラグ + 削除日)で複合キーに変更した
6 履歴行を除くためテーブルを結合してからwhere句で削除フラグ=0することに
7 クエリを10段階くらいネストしてモリモリ書く
8 なんかデータが欠落してると思ってたら、INNER JOINしてることに気が付く
9 手の施しようがなくなって俺のとこにお鉢が回ってきた
こんなデータベース管理したくねーよカス。だから女は嫌いなんだ
675:NAME IS NULL
11/04/19 08:28:01.29
>>674
8はたしかにバカだけど、ほかはまあ
しかたないんじゃね?
676:NAME IS NULL
11/04/19 15:53:11.76
てか別に手の施しようがなくなってもない気が
677:NAME IS NULL
11/04/19 21:02:38.78
クエリ10段階程度は、普通とは言わないけどたまにあるなー。
インデックスちゃんとはってたら結構パフォーマンスも出るし
678:NAME IS NULL
11/04/21 07:14:14.64
> (行を複製して削除=1する)
なんで複製するの?
679:NAME IS NULL
11/04/21 11:13:26.69
思うに区分番号を使いまわしたいんだろう
つまり、もともとも区分番号は候補キーじゃなかったって話で、
1から間違ってるってことだな
ただ、
>(自然キー + 削除フラグ + 削除日)で複合キーに変更した
らしいので、別にそれで何とかなるだろって話
そこは自然キーじゃなくて区分番号だろうと突っ込みたいが
>>674は区分番号がキーじゃないとちゃんと解ってるのかね
680:NAME IS NULL
11/04/21 17:50:16.56
何のテーブルとどう結合したのかよくわからんのだが、削除日だけだと
日付が絡んだ結合がかなり複雑になりそうな気が。
作成日も加えるとか、それこそサロゲートキー導入か。
681:NAME IS NULL
11/04/21 17:55:47.87
削除した事実と日付、元データのログだけなら、削除テーブルに退避させるだけでいい。
682:NAME IS NULL
11/04/21 21:31:10.43
>>678
よくわからないが、同一テーブル内に履歴があれば管理
しやすいと思った形跡がある。。テーブル開いてすぐ下に
履歴があるので、どう変更したか見やすいとか。
>>679
×(自然キー + 削除フラグ + 削除日)で複合キーに変更した
○(区分番号 + 削除フラグ + 削除日)で複合キーに変更した
書き間違い。すまそ
>>680
最初からそうしとけと
>>681
普通の人間が考えればなそうだな。考えたやつが普通の
人間じゃないから困る。
683:NAME IS NULL
11/04/21 22:10:23.27
ログ管理用のテーブル設計の難しさは異常
684:NAME IS NULL
11/04/29 00:43:58.61
DB設計のコツは、「難しく考えるな。あきらめろ!」
685:NAME IS NULL
11/05/01 01:24:07.02
>>683
何が難しいの?よければ要件を教えて。
686:NAME IS NULL
11/05/02 10:42:57.33
>>683じゃないけど、全文検索のこととか考え出して、行き詰まってんじゃないの
687:NAME IS NULL
11/05/02 17:27:10.54 Ym6L+dps
モデリングの勉強をしているのですが以下のような場合、どんなモデルになるでしょうか?
商品の卸売のようなシステムで
1.顧客からはは随時、受注がくる
2.ある時点で、受注を束ねて、顧客商品別に発注先に発注
3.発注先が直接顧客へ商品を配送して、完了報告をしてくる
という業務フローです。
自分のシステムでは、受注を受けるだけで、出荷は商品ごとの発注先任せといった感じです。
よろしくおねがいすます
688:NAME IS NULL
11/05/02 17:33:37.85
商品マスタと
発注先マスタと
受注テーブルを用意して適切に紐付け
任意のタイミングで商品別に集計出して発注アクション
その時に受注テーブルにあるレコードに発注済みフラグを立てる
おしまい
689:NAME IS NULL
11/05/02 17:46:15.64
1つの受注には、いくつかの商品があり、その商品は発注先はバラバラです。
受注:キー 受注番号 非キー 顧客番号、配送先住所
受注明細:キー 受注番号、受注明細番号 非キー 商品番号、数量、発注先
発注:キー 発注番号 非キー 発注先、顧客番号、配送先住所
発注明細:キー 発注番号、発注明細番号 非キー 受注番号、受注明細番号、商品番号、数量
リレーションは
受注:受注明細 1:N
発注:発注明細 1:N
受注明細:発注明細 1:1
発注まではこんな感じだとおもっています
690:NAME IS NULL
11/05/03 00:29:54.01 6I8m/Wta
>>689
なぜ、「配送先住所」が「受注」と「発注」の両方にあるの?
なぜ、「数量」と「商品番号」が「受注明細」と「発注明細」の両方にあるの?
よく分からない。
691:NAME IS NULL
11/05/03 00:35:37.80
>>689
一つの「顧客」は、一つの「配送先」を持つの?
それとも、一つの「顧客」は、複数の「配送先」を持ちえるの?
全ての受注は必ず発注されるの?
仮にそうだとした場合、
「商品番号」が決まれば「発注先」は自然と決まるの?
このあたりがはっきりしないと答えがだせないよ。