トップページ⇒tech
988コメント337KB

データベース

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
データベース全般の話題です。
0175PG一年生NGNG
>>172
下の文の意味がちょっとわかりません。
0176PG一年生NGNG
>>174
個別に管理するのがバカらしい製品です。
0177デフォルトの名無しさんNGNG
>>175
>Delivery# is null の列はインデックスが作成されないから
というのは、DBの仕様であって、RDB一般の話しではない。
まず、その辺を理解しなさい。
0178デフォルトの名無しさんNGNG
個別管理するのがばからしい製品に出荷番号を個別に付けてしかも主キーにするな馬鹿
0179PG一年生NGNG
>>174
実際の表は174みたいな連番が主キーになっているんですが、
ユーザーインタフェースに現れない列が主キーなのが非常に
わかりにくいと思ったものでカキコしてみました。
0180PG一年生NGNG
>>178
馬鹿は余計ですが......
クレームつけられたら、どのロットの製品か特定する必要があるんです。
0181130NGNG
レコードが無い状態から、

Product# Delivery# xxxxxxxx yyyyyy
-------- --------- -------- ------
22222222 Null----- bbbbbbbb 999999
33333333 XYZ000001 aaaaaaaa 999999
33333333 XYZ000002 cccccccc 999999

に成長するまでをDMLで考えると、このテーブルには、これだけでは
わからない「ある制約」がある(隠されたビジネスロジックになっている)。

具体的に言えば
Product# Delivery# xxxxxxxx yyyyyy
-------- --------- -------- ------
22222222 Null----- bbbbbbbb 999999
33333333 Null----- aaaaaaaa 999999

という状態の次には
Product# Delivery# xxxxxxxx yyyyyy
-------- --------- -------- ------
22222222 Null----- bbbbbbbb 999999
33333333 Null----- aaaaaaaa 999999
33333333 Null----- cccccccc 999999
とは出来ないが、

Product# Delivery# xxxxxxxx yyyyyy
-------- --------- -------- ------
22222222 Null----- bbbbbbbb 999999
33333333 Null----- aaaaaaaa 999999
33333333 XYZ000002 cccccccc 999999
↓
Product# Delivery# xxxxxxxx yyyyyy
-------- --------- -------- ------
22222222 Null----- bbbbbbbb 999999
33333333 XYZ000001 aaaaaaaa 999999
33333333 XYZ000002 cccccccc 999999
とは出来る。
0182デフォルトの名無しさんNGNG
馬鹿は取り下げるよ。

ユーザーインタフェースに現れない列が主キー
になるのは、別に珍しいことじゃないよ。

>>179でいってるような意味の設計をしてるなら、
出荷済み製品のテーブルをつくって、そこに
出荷済みの製品の連番と、出荷時につけた出荷番号を対にして、
いれておきなさい。

その出荷番号は、個別の製品を管理するテーブルに
入れるべき値ではないよ。
0183デフォルトの名無しさんNGNG
だから、お前ら全員「関係モデル」から勉強しなおせって!
0184PG一年生NGNG
>>182
珍しくないのは、RDBMSの製品の多くが主キーにNullを許さない
仕様になっているからではないのでしょうか?
今知りたいのは、なぜそういう使用になっているかなんです。
0185PG一年生NGNG
>>181
そのとおりです。
181に示したとおりの状態をたどります。
0186デフォルトの名無しさんNGNG
>>184
主客転倒。
RDBMSの実装が主キーにnullを許さないから駄目なのではなく、
駄目だから実装がそうなってる。
0187PG一年生NGNG
>>184
だからなんでダメなの?
0188デフォルトの名無しさんNGNG
>>186
勘違い発言なので取り消す。
0189デフォルトの名無しさんNGNG
>>143と>>145がその根拠だって。

主キーしかないテーブルがあったとして
Nullを二つ入れようとしたとき、

両方の挿入を許す作りにすると、
同じNullなのに二つ入ってしまうという矛盾が生じる。
RDB的にダメ。

二つ目を禁止するには、
すでにNullが入っているかどうかを調べなければならない。
が、Nullは、インデックスとは別枠で管理しているので、
その比較を行うだけで莫大なコストがかかる。
製品的にダメ

というわけで
ダメなの。

OK?
0190デフォルトの名無しさんNGNG
ついでにいうと、Nullをインデックスに含める仕組みも思いつくが、
実際作ろうとすると無駄が多いのでダメ、といいうのが実情だ。

RDBでテーブル設計をする場合、キー値にNullを許すのは、
基本的にダメ、というのが常識。
0191デフォルトの名無しさんNGNG
>>189
複数の属性を複合主キーにしようとしたときに、そのうちのどの属性も
nullを使ってはならない、の説明になってないので駄目。

それから>>143も論理的な説明ではない。
つまるところ「駄目だから駄目」と言っているのに過ぎない。
0192デフォルトの名無しさんNGNG
>>189で十分説明になってるんだが、分からないかなぁ。

これ以上はきちんとした、RDBの解説書を読んでくれ。
オレは別にRDBの設計者でもないし、先生をやってるわけでもない。
0193PG一年生NGNG
>>189
システムの構造上Nullの識別にコストがかかるからと言う意味なの?
Delivery#が未発番という状態を示すのにNull以外の値を使えばいいということ?
0194デフォルトの名無しさんNGNG
>>192
わからないなら答えないでください。
0195デフォルトの名無しさんNGNG
>>192
全然十分じゃない。

>複数の属性を複合主キーにしようとしたときに、そのうちのどの属性も
>nullを使ってはならない、の説明になってないので駄目。

の説明になっていない。
なお、今の議論はこっちのほう。単一属性を主キーにしたときの話はだれもしていない。

>分からないかなぁ。
分からないよ。だって、説明してないし。
0196デフォルトの名無しさんNGNG
>>192
誰も先生をやってくれとはたのんでないよ。
0197デフォルトの名無しさんNGNG
>>193
>>182を読んでね。
どこのSEに頼んでも、だいたい>>182の設計になると思う。

万が一同じ表で出荷番号を管理しなくちゃいけなくて、
キーとして検索しなきゃいけなかったりする場合、
かわりに空白' 'をいれて、出荷番号だけで一個の
インデックスを貼ればいいよ。

一度>>182のやりかたで、テーブルレイアウトを考えてみて。
0198デフォルトの名無しさんNGNG
連番属性を主キーにするというのは逃げの手段だよな。
論理的には不要な属性だし。
0199デフォルトの名無しさんNGNG
複合キーの話しを説明しなきゃいかんとはね。

複合キーのいずれかにNull値が許されている場合、
インデックスが使用できなくなる。
Null値をインデックスとは別に管理しているからだよ。
0200デフォルトの名無しさんNGNG
>>198
同意。
>>174は駄目な見本。
>>182が正解(のうちの一つ)。

データベースがわかっている奴がいてほっとしたよ(藁
0201デフォルトの名無しさんNGNG
>>199
アホか。

そんなRDBMSの実装や技術的な話をしているのではなく、
論理的にどうなのか、という話をしているのだ。
0202PG一年生NGNG
>>197
実際には既に連番を主キーにしています。
でも、実装方法を教えてといっているわけじゃなくて
主キーのNullを許せば、そんなヘンな対応を取らずに
済むのに........
と思ったのでカキコしただけです。
「Delivery#未発番」という状態を示すには、Nullが
最もしっくりくると思うのですが。
0203デフォルトの名無しさんNGNG
Nullが不自然だから、>>182の様に設計するんだよ。
0204PG一年生NGNG
>>199
実装の話しをするなら、
インデックスが使えないんじゃなくて、
Nullの列のみインデックスの適用が除外されるだけ。
逆に、NotNullの列の検索は早くなるというメリットもあるよ。
0205デフォルトの名無しさんNGNG
>>203
PG一年生は不自然ではないと思ってるんだろう。
よって「不自然だから」では説明になっていない。

まぁ、俺も、なぜ駄目なのか理詰めの説明が出来ないから、逝ってよしなんだが(爆
0206デフォルトの名無しさんNGNG
あーあー、はいはい。
検索キーにNUllいれてもいいよ。
はいはいおわり。
0207PG一年生NGNG
>>205
そう不自然ではないと思っています。
つーか、「Delivery#未発番」という状態を表す値として
他にしっくりくる値を思いつかないんです。
0208デフォルトの名無しさんNGNG
>>206
終わったと思うなら勝手にお帰りください。
0209デフォルトの名無しさんNGNG
>>205
汎用機時代のファイルならタイプクリアっていう表現方法があったのにな。
0210デフォルトの名無しさんNGNG
>>182のように発番済みの製品を集めたテーブルを作るのが
RDBとしてもっともしっくりくる作りなんだけどね。

そのやりかたでもできるけど、
もうすこし、テーブルレイアウトの設計について考えてみた方がいいよ。

ただ、じっさいにRDBとして使うときのことをいうと、>>182の方が
性能面で有利だと思う。
未発番のレコードを処理するとき、どうするか?って問題があるよね。
0211デフォルトの名無しさんNGNG
説明が出来ないことにやっと気がついた>>206は、
捨て台詞を残して逃げていった。

カッコワルー。
0212デフォルトの名無しさんNGNG
206=182だよ
0213デフォルトの名無しさんNGNG
>>210
わかります。
表を分けるというのは、RDB的にはしっくりくるのですが、
システム全体を見た時、あるいは業務的にもしっくりこない感じがするのです。
列の状態が遷移しただけで表を分割するというのは...........
0214デフォルトの名無しさんNGNG
分割じゃないよ。
出荷番号(PK) 製品の連番
------------ ----------

のテーブルをもう一個作るだけ。
元のテーブルにあった製品の連番は、いらない。

こういうこと。
0215デフォルトの名無しさんNGNG
主キーにプライマリキー制約をあえて使わず、
ユニーク制約だけにするというのは、賢い選択だと思うがね。
0216デフォルトの名無しさんNGNG
同意
0217214NGNG
製品の連番じゃない、
まちがえ。

元テーブルにあった出荷番号はいらない

のまちがい。
0218PG一年生NGNG
>>214
ごめんなさい。
よく理解できないです。

Product# Delivery# xxxxxxxx yyyyyy
-------- --------- -------- ------
11111111 Null----- aaaaaaaa 999999
22222222 Null----- bbbbbbbb 999999
33333333 XYZ000001 aaaaaaaa 999999
33333333 XYZ000002 cccccccc 999999
44444444 XYZ000003 aaaaaaaa 999999
44444444 XYZ000004 dddddddd 999999
55555555 Null----- aaaaaaaa 999999
66666666 Null----- aaaaaaaa 999999
77777777 XYZ000005 aaaaaaaa 999999
77777777 XYZ000006 aaaaaaaa 999999
77777777 XYZ000007 aaaaaaaa 999999

↓

Product# xxxxxxxx yyyyyy
-------- -------- ------
11111111 aaaaaaaa 999999
22222222 bbbbbbbb 999999
55555555 aaaaaaaa 999999
66666666 aaaaaaaa 999999

Product# Delivery# xxxxxxxx yyyyyy
-------- --------- -------- ------
33333333 XYZ000001 aaaaaaaa 999999
33333333 XYZ000002 cccccccc 999999
44444444 XYZ000003 aaaaaaaa 999999
44444444 XYZ000004 dddddddd 999999
77777777 XYZ000005 aaaaaaaa 999999
77777777 XYZ000006 aaaaaaaa 999999
77777777 XYZ000007 aaaaaaaa 999999

ということでは ないんですか?
0219デフォルトの名無しさんNGNG
>>215
言っている意味がよくわかりません。
0220214NGNG
Serial(PK) Product# xxxxxxxx yyyyyy
---------- -------- -------- ------
0000000001 11111111 aaaaaaaa 999999
0000000002 22222222 bbbbbbbb 999999
0000000003 33333333 aaaaaaaa 999999
0000000004 33333333 cccccccc 999999
0000000005 44444444 aaaaaaaa 999999
0000000006 44444444 dddddddd 999999
0000000007 55555555 aaaaaaaa 999999
0000000008 66666666 aaaaaaaa 999999
0000000009 77777777 aaaaaaaa 999999
0000000010 77777777 aaaaaaaa 999999
0000000011 77777777 aaaaaaaa 999999

Deliverty#(PK) Serial
-------------- ----------
XYZ000001 0000000003
XYZ000002 0000000004
XYZ000003 0000000005
XYZ000004 0000000006
XYZ000005 0000000009
XYZ000006 0000000010
XYZ000007 0000000011

こういうこと。
検索するとき・表示するときは二つの表を結合してください。
0221デフォルトの名無しさんNGNG
>>219
上の例でいうと、
主キーは、Product# + Delivery# だが、この2項目に
プライマリキー制約(ユニーク制約+ノットナル制約と同等)を設定せず、
ユニーク制約でけにとどめて、NULL値を可能にするということ。
0222デフォルトの名無しさんNGNG
>>221
主キーがあるのがリレーションなのでは?と言って見たり・・・。
勘違いだったらスマソ。
0223デフォルトの名無しさんNGNG
主キーがなくても立派なリレーション(表)です。
0224デフォルトの名無しさんNGNG
>>220
結合は上のテーブルを軸にしたアウタージョインだと思うが、
結果は結局、Deliverty#がNullの列ができる。
0225デフォルトの名無しさんNGNG
全部の製品を見たいときはouter join
出荷した製品を検索するときはinner join

OK?
0226デフォルトの名無しさんNGNG
>>222
勘違い。
ちなみに、第一正規形には主キーは必要ない。
第二正規形で始めて主キーが登場する。
0227182=206=214NGNG
つかもう眠い。
後は勝手に本を読んでくれ。
0228デフォルトの名無しさんNGNG
>>222
「主キーがある」ということと、RDBMSの提供機能である「PRIMARY KEY制約を適用する」
ということは違うと思うぞ。
0229デフォルトの名無しさんNGNG
痛い展開になっている模様。
0230デフォルトの名無しさんNGNG
ようするにまともにRDBわかってなくても仕事でつかちゃってるってことだ。
0231デフォルトの名無しさんNGNG
一応指摘しておくが、>>214は悪い設計の見本。
もうSerial#を入れてしまっていて、変更不可ならしかたないが。
0232デフォルトの名無しさんNGNG
>>230
一番わかっていないのはチミだよ。
0233デフォルトの名無しさんNGNG
>>214じゃなかった。
>>220は悪い設計の見本。
0234PG一年生NGNG
>>231 >>233
よい設計の見本を教えてください。
0235デフォルトの名無しさんNGNG
>>233こそ本物のYahooBB顧客DB設計者
0236デフォルトの名無しさんNGNG
実力と経験とうんちくもあります(藁
0237デフォルトの名無しさんNGNG
>>234
やだ。
なお、なぜ悪いのかの理由は>>198の通り(俺の発言じゃないけど)

正規化をしらなければまずはこれを勉強しろ(第三正規形まで)。
データベースの入門書も読んだことないんだろう?
0238デフォルトの名無しさんNGNG
>>237
ケチはつけるが対案がない。
237は厨房の良い見本。
0239デフォルトの名無しさんNGNG
>>237
>>182の二の舞だぞ。
もうほっとけ
0240デフォルトの名無しさんNGNG
なお、良い設計を示して欲しければ、
Productの定義とDelivery処理の要件を提示しろ。
これがわからずに、あーだこーだ言ってもしかたない。
>>220の設計が悪いというのは言えるけどな。
0241デフォルトの名無しさんNGNG
>>237は最近正規化を学んで、その言葉を使ってみたかっただけです。
0242デフォルトの名無しさんNGNG
>>240はYahooBBの経営者がこのスレを見て怒り狂うのが怖いので
必死に自分の設計を正当化しようともがいているのです。
0243デフォルトの名無しさんNGNG
>>239
そうしとくよ。吉外がいるみたいだからな。

>なお、良い設計を示して欲しければ、
>Productの定義とDelivery処理の要件を提示しろ。

は本気だからな>一年生

俺に限らず、良い設計見本を知りたければ最低限必要だろ。
0244デフォルトの名無しさんNGNG
>>240
厨房丸出し。カコワルイ
0245デフォルトの名無しさんNGNG
厨房の逃げ口上:
○○を勉強しろ
××を読め
0246PG一年生NGNG
>>243
で、結局あなたは良い見本を知らないんでしょ?
0247Error401(243)NGNG
ああ、知らないね。
相手するのやめた。さよなら。
0248PG一年生NGNG
>>247
さよなら。
0249デフォルトの名無しさんNGNG
眠いって場よ。

ところで>>220の意図するところは分かったか?
>>243がいう存在しないはずのデータがあって、
それをキーにしているのは不自然というのはもっともだけど
とりあえず、あれが一番よく使われる設計パターンだ。
0250デフォルトの名無しさんNGNG
あーあ、変な展開になってるな。
もう寝よ。
0251PG一年生NGNG
>>249
>>220は理解しました。
でも、外部結合の結果は結局Nullの列ができるわけだから、
PRIMARY KEY制約を用いず、UNIQUE制約だけにするというのも
捨てがたい気がする。パフォーマンスが劣化するのは理解しているが、
業務的に実用に耐えるレスポンスなら
「Nullを含む主キーがあっても良いのでは?」という疑問は晴れません。
0252デフォルトの名無しさんNGNG
>>174の設計がいいんじゃネーノ?
0253デフォルトの名無しさんNGNG
俺は主キーにNULLがあってもOKに同意。
0254デフォルトの名無しさんNGNG
>>253
俺もそれに同意。厨房ばっかで困るよな、相棒。
0255デフォルトの名無しさんNGNG
まだやってたのか。

>>251
Nullを含まないものを主キーとするというのは定義。
よって、主キーにはNullを含んではいけない。

Q.E.D.
0256PG一年生NGNG
>>255
Nullじゃなくて"*"なんてヘンな記号ならいいの?
Nullなんて実装手段を「定義」だなんていわれても......
0257デフォルトの名無しさんNGNG
>>256
>Nullじゃなくて"*"なんてヘンな記号ならいいの?

良いか悪いかを俺に聞かれてもこまる。
それは要件次第であり、それを知っているのは君だけだ。

>Nullなんて実装手段を「定義」だなんていわれても

nullは「実装手段」などではない。「未定義(不定)状態」という概念。
0258デフォルトの名無しさんNGNG
>>255
256の言うとおり、番号未発番という状態を示すのにNULLを用いているに過ぎない。
表の論理的主キーなんてその値がNULLをとるか否かなど考慮しない。
0259デフォルトの名無しさんNGNG
>>255
それは定義(それもいうなら定理だろ)でもなんでもなく、
RDBMS製品の仕様に過ぎない。
0260デフォルトの名無しさんNGNG
>>258-259
そうではない。
だとすると、なぜRDBMSの論理値が3つの値を取ることを前提に
理論構築されていることを説明できるのだ?
0261PG一年生NGNG
>>260
番号未発番という状態を表すのにNullを用いてはならないと言っているだけですか?
0262デフォルトの名無しさんNGNG
>>261
その通り。

主キーの要件は「タプルを一意に決定できるもの」であり、
nullは「不定」を現す概念だのだから、主キーには使えないとしている。
これは定義なのだから、いくら「nullを主キーに使いたい」と言っても
駄目なのだ。

多くの(全てのかもしれない)RDBMSの実装では、「主キー」を
primary keyというconstraint(制約)で実装しているのだから、
primary keyにnullが使えないのは当然のこと。

Q.E.D.
0263デフォルトの名無しさんNGNG
なお、リレーショナルデータベースのモデルは、数学で厳密に定義
されているそうだが、俺はそれを知らないし、説明できない。

なお、俺が説明したことも誤りがある可能性はあるので、
その辺は承知しておいてくれ。
0264デフォルトの名無しさんNGNG
DB設計の入門書に書いてあることまだやってたのかよ。
ネロ
0265デフォルトの名無しさんNGNG
付け加えると、RDBの枠組みにnullという概念を入れてしまったことを
E.F.Coddも後悔しているというようなことをどこかで読んだ気がする。
(これは非常に曖昧な記憶なので間違っている可能性大)

Googleで検索してみたが、それらしいのがいくつかあったので、
興味があるなら、読んでみると良い。(E.F.Codd + null)
0266デフォルトの名無しさんNGNG
>>264
俺は起きたばかりなんだが(藁
0267デフォルトの名無しさんNGNG
質問者はもう寝たらしいので、勝手に話をすすめる。

未発送状態を"*"として、>>166のテーブルでProduct#+Delivery#を
PKとして良いのか?
あの表が他の表から完全に独立していて、なおかつ、将来拡張が
無く、Delivery#だけで、他と識別する必要がなければそれでよい。
つまり要件次第だな。

しかし、将来必ず更新される項目をPKに入れておくのは一般には
良くない。なぜならば、その項目をFKとして持つ表があった場合
Delivery#を更新する場合に、FKとして持つ表も更新しなければ
ならなくなる。
これは容易にシステム全体のデータの整合性を崩してしまう要因になる。
(ツールによるad hocな更新をしてしまったなど)。

ということで、「後から発送番号が付けられる」場合は、それを
単なる属性値として持っておくのが良い。
代わりに、システムが付番する「発送受付番号」のようなものを
作りPKとしておく。
つまり>>174のようにしておく。
>>202ということなので、今の実装で問題が無かったというオチだな。

なお、>>214は冗長だと思う。
特に「発送番号が付番済のもの」をひとまとまりに管理する必要が
なければ、テーブルを分ける必要がないと思う。

まぁ、データモデリングは人それぞれで、唯一の正解というものは
無いのが普通なので、どれが正解、どれが間違いとは一概には言えないもの。

ただし「無意味なSerial#」や「無意味な非正規化」は
間違いだとはいえると思う。
0268デフォルトの名無しさんNGNG
ん、ちょっと待てよ。
FK constraintを付けた場合、UPDATE出来なくなる実装のRDBMSが
あったような。これはRDBMSの実装依存の部分かもな。

更新されるPKなんてここ最近使ったこと無いので、>>267は微妙に嘘が
混じってる可能性があるので注意。
0269mageNGNG
mage
0270MBNGNG
>>262
>これは定義なのだから、いくら「nullを主キーに使いたい」と言っても駄目なのだ。
なんでその定義に従わなければならないんですか?
実装レベルでは、nullを許した方が性能がよくてもなおその定義に従うメリット
はなんですか?
0271デフォルトの名無しさんNGNG
>>270
というのであれば、主キーにnullを許す処理系を作って使えばいいじゃん。
いつまで、駄々こねてんだ。
0272デフォルトの名無しさんNGNG
>>270
PostgreSQLかMySQLを改造すれば?

俺は今まで主キーにnullを許すRDBMSを見たこと無いが、
それはそれなりの理由があると思う。それが何かは知らないけど。
そういや、主キーは更新不可というRDBもあったな。
0273MBNGNG
>>271
初カキコなんですけど..........
0274デフォルトの名無しさんNGNG
>>270
>実装レベルでは、nullを許した方が性能がよくてもなおその定義に従うメリット
>はなんですか?

メリットなんかないよ。だから、>>271-272の言うように、自分の好きな
使用でRDBを作ってください。
■ このスレッドは過去ログ倉庫に格納されています