■掲示板に戻る■ ■過去ログ倉庫めにゅーに戻る■
なぜRDBはあんなに難しいのか?
1 名前: デフォルトの名無しさん 投稿日: 2001/03/03(土) 11:10
なぜRDBはあんなに難しいのか?

RDBを使ったプログラムを開発してます。
テーブルの設計者がおかしなテーブルを作ってくれたせいで大変です。

たとえば
テーブルAに二つの外部キーがあり
それぞれさしているものはテーブルBの同じレコードです。
本人いわくどちらを使ってもいいようにと気を使ってくれたようです。
だからテーブルAのレコードを更新するときは
二つの外部キーの同期を考えてプログラムを作っています。

ほかにも
テーブルAのレコードを更新したら
テーブルBのレコードも更新しないと整合性が保たれない
というのもあります。

作り直してくれと頼んだのですが
論理的に間違いはないと一点張りです。

かく言うわたしもRDBの分析設計(正規化)は
素人同然です。(がこのテーブル設計者よりはマシです)

こいつに理にかなった説明をして作り直させるため
分析設計正規化について勉強したいのですが
よい参考書としてどのようなものがあるのでしょうか?

当方、 「なぜC++はあんなに難しいのか? 」立てたものです。



2 名前: デフォルトの名無しさん 投稿日: 2001/03/03(土) 11:14
たとえば
テーブルAに二つの外部キーがあり
それぞれさしているものはテーブルBの同じレコードです。
本人いわくどちらを使ってもいいようにと気を使ってくれたようです。
だからテーブルAのレコードを更新するときは
二つの外部キーの同期を考えてプログラムを作っています。

【補足】
テーブルBの主キーは2つあります。



3 名前: バイト 投稿日: 2001/03/03(土) 15:56
RDBは3日でおーけー


4 名前: デフォルトの名無しさん 投稿日: 2001/03/03(土) 19:02
>>1
>当方、 「なぜC++はあんなに難しいのか? 」立てたものです。
君んとこの職場って・・・楽しそうだね。



5 名前: デフォルトの名無しさん 投稿日: 2001/03/03(土) 21:24
>>4

ああ。たのしいよ。
インプットとアウトプットさえ合ってればよしとする体制でとりくんでるよ。
はじめてソフト開発学ぶやつはこれが普通だと思っている。
だから何も考えずに
もっと給料の高い(徹夜必死)のソフト開発会社に転職する。
そこでホントの厳しさをしりこの業界を去っていくのがおおいよ。



6 名前: デフォルトの名無しさん 投稿日: 2001/03/03(土) 23:41
RDB が難しいんじゃなくてそいつがアホなだけでは。
正規化つってもよっぽど複雑じゃなければ
そう直感に反するわけでもなし。

むしろ RDB(の製品) は管理が面倒、複雑だと思うがどうか。



7 名前: デフォルトの名無しさん 投稿日: 2001/03/03(土) 23:43
>テーブルBの主キーは2つあります。

ユニークなインデックスは幾つでも付けれたと思うが、
主キーは1つしか付けれないと思うぞ。
候補キーか?

>論理的に間違いはないと一点張りです。

その論理とやらをきいてみれ。
1対1じゃそれが一人よがりな論理だと認めたがらんだろうから
プロジェクトメンバー全員の前でレビューさせてみれ。

それからそいつは通産省のDBスペ試験でも受験させた方が
いいな。


8 名前: デフォルトの名無しさん 投稿日: 2001/03/04(日) 00:52
私の場合は(運良く?)優れたDB設計者の元で、実際に稼働している
優れた設計のテーブル群を実際に扱いながら勉強したので
どんな本が世の中にあるのか知りません。実際に稼働している
きれいなテーブルを見るのが一番早いのだけど、そんなのには
なかなか出会えないですね。
私も、その後腐ったテーブル設計を山ほど見てきて、一番最初に
出会った設計者がどれだけ優れていたか実感したわけですが。

てなわけで、運の悪い人は自分で勉強するしかないわけだけど
「正規化」とかのキーワードで探せば、山ほど情報はあるはず。
私も、DBスペシャリスト試験はいいと思うよ。


9 名前: デフォルトの名無しさん 投稿日: 2001/03/04(日) 13:15
翔泳社
Oracleシステム 構築・運用ガイド 3200円
がなかなかいい本と思われ。読んでみて。
でも、1のような正規化オンリーを勉強したい場合はちょっと違うかも。

RDB自体は難しくも何とも無いだろ。きちんと設計すれば、あれほど楽な
ものは無いぞ。

でも設計者がバカだとプログラマが泣くんだよな。
あとシステムのパフォーマンスを決めるのは、最終的にはテーブル設計。
SQLでどんなすさまじいコードを書こうが、テーブルがタコだとダメですな。
数万件くらいだと、ハードでごまかせるけどね。


10 名前: 1です 投稿日: 2001/03/04(日) 13:50
ご意見どうもです。

参考文献の紹介もありがとう。

学生の時に少々ソフトウェア工学全般を学んだときに
本質的なところ捕らえているなと興味をもっていました。
でも現実はかなりいいかげんなものだということをしりました。

いい設計者に出会いたいな。
そしてそこから学べるものを学びたいな。



11 名前: 1です 投稿日: 2001/03/04(日) 14:09
余談です。

RDBとは関係ないがCでプログラムを組んでいたとき
変な決まりがあった。その一部を紹介。

・else if はマシンに負荷がかかり他人の迷惑になるので使用禁止。
・再帰処理は使用禁止。
 ソースを見せたときこんな書き方はない。と一喝されて以来。

いまは2社目なんですが友人もへんなコードを
書かされているという話しかきかないような。



12 名前: デフォルトの名無しさん 投稿日: 2001/03/04(日) 14:13
挿入しかされなくて、全く更新されないテーブルが40個ほどあって、
第三正規化が全てに掛かってる&挿入の関係でインデックスは全く
使用しない、という仕様なんだが、参照の速度が足りないって
困ってたな…

アホばっかしだ、みかかの連中。


13 名前: デフォルトの名無しさん 投稿日: 2001/03/04(日) 15:25
>>12
みかかにもエースはいるようですよ。
一部に集められて、通常運用業務にはかすばっかりらしいですが


14 名前: デフォルトの名無しさん 投稿日: 2001/03/05(月) 17:45
「外部キー」という概念はおわかりですか?

> テーブルAに二つの外部キーがあり
> それぞれさしているものはテーブルBの同じレコードです。

「親表/子表」という表現を使うとすれば、
A: 子表
B: 親表
です。よって、

> ほかにも
> テーブルAのレコードを更新したら
> テーブルBのレコードも更新しないと整合性が保たれない
> というのもあります。

というのは、概念上正しくありません。


15 名前: デフォルトの名無しさん 投稿日: 2001/03/06(火) 09:32
そもそも、「外部キー」は、参照整合性制約のためにあるのであって、

> 本人いわくどちらを使ってもいいようにと気を使ってくれたようです。

というようなものではありません。「使う」って何のことでしょうか?

> だからテーブルAのレコードを更新するときは
> 二つの外部キーの同期を考えてプログラムを作っています。

外部キーはその性質上、親キーとの整合性があっていれば良いわけで、
いくつあろうが、外部キー同士の同期などというものは、考慮する必要は
ないはずです。

> 論理的に間違いはないと一点張りです。

まぁ、なんというか、お互いわかっていないような気がします。



16 名前: デフォルトの名無しさん 投稿日: 2001/03/06(火) 09:35
あなたが、「論理的に誤った設計になっている」と思っているテーブルの
DDLを、問題が無いように一般的な項目名に変更し、関係無いカラムの
定義を殺ぎ落としたものを、ここに書いてくれれば、それが論理的には
どうなのか、という議論になるかもしれません。



17 名前: 名無し 投稿日: 2001/03/06(火) 13:22
設計者のスキルは、正規化ができるかではなくて、
どこで正規化を止めるか、どう非正規化できるかです。
正規化は機械的に誰でもできます。



18 名前: デフォルトの名無しさん 投稿日: 2001/03/06(火) 16:50
>>17
正規化よりも、エンティティと属性の抽出の方が大事。
特に、目に見えないもののエンティティの抽出。
これが、言うは簡単、行うは難しなんだよね。知識と
経験がものを言うね。
OOのクラス設計と通じるものがあるね。


19 名前: デフォルトの名無しさん 投稿日: 2001/03/06(火) 21:24
なんつーか
オブジェクト指向言語のクラスとRDBの表という概念に
親和性が低すぎる気がしません?
たまに頭の中が混乱することがある。

OODB使えば解決するんだろうけど。





20 名前: デフォルトの名無しさん 投稿日: 2001/03/06(火) 23:10
>>19
インピーダンスミスマッチと呼ばれる、昔からある
開発者の悩みの種。
でも、いますでに出来上がってるベンダ製RDBMS並の
スケーラビリティだのを持っている他のデータ永続化
手段がないから、いわばみんな仕方なく使ってるのよん。

OracleDBを一から作るには数百億ドル掛かるとか
どこかに書いてあったが、ほんと?

誰か作ってくれんか?ちゃんと動くOODBMS。

Javaなら比較的簡単じゃないか?他言語と共用
するつもりがなければ、Serializableだけで逝く
事にできるし。


21 名前: 那菜紙餐 投稿日: 2001/03/07(水) 23:11

> 設計者のスキルは、正規化ができるかではなくて、
> どこで正規化を止めるか、どう非正規化できるかです。
> 正規化は機械的に誰でもできます。

正論かもしれませんけれど、それすらまともに出来ない人がいるから
問題になるんじゃないかと思いますけど。





22 名前: 1です 投稿日: 2001/03/09(金) 20:45
1です。

とりあえずこんなテーブルでプログラム組まされています。

■ GROUP_TABLE
GID GID2 GNAME PARENT_GID
---------------------------------
G94001 01 A NULL
G95088 0101 A/A G94001
G98001 0102 A/B G94001
G98004 010201 A/B/A G98001
G99022 010202 A/B/B G98001
G94011 0103 A/C G94001
G00023 02 B NULL
G00007 0201 B/A G00023

■ USER_TABLE
UID UNAME GID GID2
------------------------------
U93121 SUZUKI G98001 0102
U97101 SATOU G99022 010202

階層構造になっている GROUP_TABLE と
それに関連する USER_TABLE があります。
キーは GID と GID2 どちらでもアクセスできるように2つ。

GID はユニークに振り分けたコードです。
GID2 は階層的なをコードです。

もし PARENT_ID を更新したとき、GID2 を更新する。
下位の階層のレコードがあればそれも更新する。
関連する USER_TABLE のレコードも更新する。

このテーブル設計っていかがなものでしょうか?
またこういう階層構造をテーブル化するにはどのようにしたらよいか?

このテーブル設計者は絶対の自信を持っています。
でもインデックスとは何かを知りません。
なので NULL チェックや ユニークチェックなどの定義はしてくれません。
テーブル名とカラム名前と長さ(すべて固定長文字列256バイト)を
定義したにすぎません。
キーと言っているのはそいつがキーだと言っているだけです。



23 名前: 1です 投稿日: 2001/03/09(金) 21:02
1です。

22の補足
ディレクトリの移動という感じです。
親ディレクトリを変更したら階層的につけられている GID2 を
再設定する仕様です。

テーブル設計者いわく
GID2 の存在理由はそのレコード階層が一目で分かるからだそうです。



24 名前: デフォルトの名無しさん 投稿日: 2001/03/09(金) 21:09
まずキーが二つあるって認識が変です。キーそのものはGIDだけで
十分ですね。で、親が変わった時にすべての子孫レコードを更新
しなければいけない設計は絶対におかしいです。GID2がなんのために
使うフィールドか不明ですが、階層関係をあらわすためだけなら不要
でしょう。親子関係は別テーブルにするという手もあります。



25 名前: 24 投稿日: 2001/03/09(金) 21:12
>GID2 の存在理由はそのレコード階層が一目で分かるからだそうです。

名前のデータにそんなもん保存してもしょうがないですよね...
この調子だとあちこちに冗長なフィールドをつくってそうですね。


26 名前: 24 投稿日: 2001/03/09(金) 21:31
名前じゃなくて、生です。


27 名前: 1です 投稿日: 2001/03/09(金) 21:32
1です。

テーブル設計者のプライドがめちゃくちゃ高いので
直してくれそうにありません。
プログラマはみんな泣いています。

GID2 は親レコードから子レコードへの
関係ともおっしゃっておられます。

PARENT_GID は子レコードから親レコードへの
関係ともおっしゃっておられます。

いま挙げた例はごく一部です。
実際のテーブルはもっと関係が絡み合ってて劣悪です。
マスタテーブルと更新テーブルを2つ作るべきなところも
1つのテーブルでやりくりしています。
これはマスタレコードだよ。とか。これは更新レコードだよ。とかの
カラムをもうけたり。
レコードに日付カラムをつけてレコードを挿入したけれど
処理日付に達するまで予約レコードとして扱うので処理対象外とかね。



28 名前: デフォルトの名無しさん 投稿日: 2001/03/09(金) 22:02
■ PARENT_TABLE
PARENT_GID ---PK,REF
GID2

■ GROUP_TABLE
GID ---PK,REF
GNAME
PARENT_GID ---FOR

■ USER_TABLE
UID ---PK
UNAME
GID ---FOR

PK:主キー
REF:親キー
FOR:外部キー

ちょっと考えてみましたがこういうことですか?



29 名前: 1です 投稿日: 2001/03/09(金) 22:16
1です。

>>28

そうなんですが、、、
GROUP_TABLE のレコードは階層的で深さは可変です。
再帰的に?なっています。



30 名前: デフォルトの名無しさん 投稿日: 2001/03/09(金) 22:23
>GROUP_TABLE のレコードは階層的で深さは可変です。
再帰的に?なっています。

すみません。意味がよくわからないんですけど、もう少し説明下さい。
(物分り悪くてゴメンナサイ(藁)


31 名前: 30 投稿日: 2001/03/09(金) 22:36
>GID2 は階層的なをコードです。
すみません。この部分ですか?

よく見るとデータが
PARENT_GID:GID2=1:1
ではないんですね(汗

でも、そーするとこのGID2って...?



32 名前: デフォルトの名無しさん 投稿日: 2001/03/09(金) 22:53
GID2ってのは要するにただのコメントなんでしょ?
プログラマはGIDこそキーだと思ってクエリー書いて一週間に一回GID2を
更新するバッチ書くってのはどう?


33 名前: 30 投稿日: 2001/03/09(金) 23:21
うーーん...(藁


34 名前: 1です 投稿日: 2001/03/09(金) 23:28
1です。

GID をキーとするアプリと
GID2 をキーとするアプリがあります。
これから開発するアプリは GID2 をキーにすることを推奨しています。
GID は既存のアプリで使われているので残してあります。

GID2 は そのフィールド値だけで自分のレコードの階層位置がわかる
絶対パスみたいなものです。
テーブル設計者この仕組みを考え出したことに誇りを感じているので
ねじ伏せるのは用意ではありません。



35 名前: 1です 投稿日: 2001/03/09(金) 23:32
1です。

>これから開発するアプリは GID2 をキーにすることを推奨しています。
推奨というか GID2 をキーにしろといわれています。
GID2 は値が変動するキーです。この考え自体がへん。

ソースコードはエライ複雑になってます。
わかりにくい。



36 名前: デフォルトの名無しさん 投稿日: 2001/03/10(土) 00:08
確かに一目で階層がわかるのはすばらしいアイデアです。
早速すべてのアプリをGID2をキーにして作り始めましょう。

ただGID2は値が変わることがあるので、その場合には既存のすべての
テーブルやBCPファイルででGID2を参照してるものを調べて更新する必要
があります。欠点と言えばそれくらいでしょうか。



37 名前: 30 投稿日: 2001/03/10(土) 01:12
>>28を訂正

■ GROUP_TABLE
GID ---PK,REF
GID2
GNAME
PARENT_GID

■ USER_TABLE
UID ---PK
UNAME
GID ---FOR

GROUP_TABLE.GID2を変更してもUSER_TABLEに影響がないように。
USER_TABLE.GID2を参照してるPGMは修正が必要ですけど。



38 名前: デフォルトの名無しさん 投稿日: 2001/03/10(土) 01:14
全部大文字なのがいやだ


39 名前: 名無しさんi486 投稿日: 2001/03/10(土) 01:59
>>1 やっぱりおかしいと思ったら全員で説得すべき。
説得できないのであれば、自分も賛同したということ。PGならPGなりに
プライドを持ってがんばれ。設計した奴がえらいとは限らん。


40 名前: デフォルトの名無しさん 投稿日: 2001/03/10(土) 11:57
つーか、将来のことも考えて辞めちまえ


41 名前: 1です 投稿日: 2001/03/10(土) 16:23
>>40

1です。

転職2回目です。
前の会社も今の会社も結構外面はよく
確かな技術力と信頼性で評価されてきた会社です。
名前もみんなが知っています。
でも実際の仕事を見ているとどちらも丁寧ではありませんでした。
店頭なんかで見るソフトなども携わったが設計はひどかった。
簡単にシステムを停止できるようなものまでいろいろと。



42 名前: くどいが 投稿日: 2001/03/10(土) 19:00
全部大文字なのがいやだ


43 名前: 名無しさんi486 投稿日: 2001/03/11(日) 01:43
>>42 なぜ? Cじゃないんだからさ。まぁ使い分けた方が見やすいが。


44 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 13:16
言葉を正しく使わないと議論が混乱するいい例。
FKがある(設定する)のはテーブルBですね。参照される側の
テーブルAの方にFKがあるとは言いません。

>二つの外部キーの同期を考えてプログラムを作っています。
同期させるのは、あるFK(外部キー)とあるFKの間ではないですね。

*

テーブル設計としては、USER_TABLEにGID2があるのが冗長という
点を除けば、全くおかしくありません。(計算値であるGID2を
GROUP_TABLEに入れるべきではない、という視点もありますが)

再帰構造の実現は、GROUP_TABLEのようなやり方が普通です。

GID2をUSER_TABLEに入れたのは、アプリケーションのアクセス
状況や、レコード数などを見なければなんとも言えませんね。
ただ、Join無しにGID2を条件として、USER_TABLEを検索できるよう
設計しているのだ、と言えば、誰もそれが誤りであるとは言えないでしょう。

*

では、USER_TABLE.GID2をどうやってGROUP_TABLE.GID2と同期
させればいいのか。
トリガーがあるRDBMSであれば、GROUP_TABLEのトリガーとして、
USER_TABLEを更新するようにします。
# これ試してないので、何かの制限にひっかかるかも

あるいは、USER_TABLEに対するアクセスをストアードプロシージャ
化します(add_user_table()とか)。

どのようなクライアントアプリケーションからのデータ変更に対しても、
データベース全体の整合性が自動的に保たれ状態に出来るという
意味では、トリガーで実装するのが一番キレイだと思います。


45 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 13:32
なお、データベース理論的に正しいテーブルは、30さんのフォーマット
を借りれば、以下のようになります(外部キーはFKとしてあります)。

■ GROUP_TABLE
GID ---PK,REF
GNAME
PARENT_GID

■ USER_TABLE
UID ---PK
UNAME
GID ---FK

計算値(導出項目)であるGID2がGROUP_TABLEにあってはなりません。
ただし、データベースへのアクセスを容易にするために、計算値を
テーブルの項目にキャッシュしておくのは非正規化同様良くやる
手法です。


46 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 14:58
うん、別に悪くないテーブルじゃない?

GID2の整合性ととるのもトリガ用意するかストアド経由で
更新するようにすれば手間じゃない気が。


47 名前: 46 投稿日: 2001/03/12(月) 14:59
うへぇ、外出だ


48 名前: いつでもどこでも名無しさん 投稿日: 2001/03/12(月) 15:26
あの直接RDBとは関係無いのですが
テーブルやフィールドに名前を付けるのを
英語で記述して行こうと思っているのですが
辞書等で調べてもなかなかマッチしません
何か良い書籍やサイトが有れば教えていただけませんか?


49 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 15:57
excite翻訳


50 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 15:59
付けた英単語を見て、万人がその内容を想像出来るかどうか、
という問題はおいときます。

私が良くやる方法は、まず対象カテゴリで頻出の英単語(その
カテゴリ名ズバリが分かればそのほうがなお良い)で、英語圏
のサイトをいくつか検索します。
で、そのカテゴリや概念の説明ページを探し、そのカテゴリに
対する正しい英単語を調べます。

ただし、最初に言ったように、正しい英単語を使ったからと言って、
それを見る人が理解できなければなにもなりません。

カッコ悪いですが、基本英単語であればそれを使い、その他の
難しい英単語や専門分野の単語は、ローマ字で命名するのが
良いと思います。

# ただこの場合も、'si'や'shi'、'cha'や'cya'など人によって違いがある
# ので、「ヘボン式で命名する」などの規約を作っておくのが吉。


51 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 16:05
>>49
goo( http://www.goo.ne.jp/ )のEXCEEDもある。

でも、個人的には、yield_to_maturityなんてのよりも、manki_rimawari
のほうが好き。


52 名前: 24 投稿日: 2001/03/12(月) 16:21
>うん、別に悪くないテーブルじゃない?

本気でそう思うんですか? Aを親とするレコードBが、Cを親にするように変更
されたら、Bの子孫レコードすべてとそのレコードのGID2を参照するすべての
レコードが更新されるんですよ。もし階層構造の変更が頻繁に行われるので
あれば、デッドロックの嵐でしょうね。

個人的にはGID2とやらは、何の役にも立たないだろう、と思います。


53 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 16:26
>>50 うちも簡単な英単語と、ローマ字の組み合わせでやっていますね。
プロジェクトでルールを決めてやっています。(当り前だと思うけど)


54 名前: 46 投稿日: 2001/03/12(月) 16:31
>もし階層構造の変更が頻繁に行われるので
>あれば、デッドロックの嵐でしょうね。

本当か?

>個人的にはGID2とやらは、何の役にも立たないだろう、と思います。

使わなければ役に立たない。
使おうと思えば使える。
再帰的に探すよりは多分早い。


55 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 16:41
>>52
>本気でそう思うんですか? Aを親とするレコードBが、Cを親にするように変更
>されたら、Bの子孫レコードすべてとそのレコードのGID2を参照するすべての
>レコードが更新されるんですよ。もし階層構造の変更が頻繁に行われるので

だから、それはアプリケーションからのアクセス要件によりますって。
頻繁に、「select * from group table wher gid2 like '01%'」みたいな
検索を必要とするなら、レコードに変更があった時に、gid2を再構築
するのはそれほど悪い戦略では無いと思いますよ。
逆にそのような検索がめったに無いのであれば、get_gid2()みたいな
ストアードファンクション(プロシージャ)を用意しておけば良いだけの
話でしょ?

第三正規系として正しいかどうか、というのであれば、件のテーブル
設計は正しくないけれども、だからといって、アプリケーションからの
アクセス要件無しに、その設計が間違っているかどうかは判断出来ない
のでは?

> あれば、デッドロックの嵐でしょうね。

デッドロックにはなりませんよ。

> 個人的にはGID2とやらは、何の役にも立たないだろう、と思います。

GID2無しに( >>22 参照)、「G95088以下に属するUSERの中から
○○という条件に合致するものを検索する」みたいな検索は簡単
には出来ませんよね?

GID2があれば、
select * from user_table where gid2 like '0101%' and more_cond
って書けるでしょ?


56 名前: 55 投稿日: 2001/03/12(月) 16:43
あ、外出だった(ワラ


57 名前: 55 投稿日: 2001/03/12(月) 17:00
それに、GID2の再構築はそれほど大変じゃ無いよ。

■ GROUP_TABLE
GID    GID2   GNAME PARENT_GID
---------------------------------
G94001 01     A     NULL
G95088 0101   A/A   G94001
G98001 0102   A/B   G94001
G98004 010201 A/B/A G98001
G99022 010202 A/B/B G98001
G94011 0103   A/C   G94001
G00023 02     B     NULL
G00007 0201   B/A   G00023

例えばG98001をG94001(GID2=01)の下からG00023(GID2=02)の下に移動する場合、
GID    GID2   GNAME PARENT_GID
---------------------------------
G98001 0102   A/B   G94001
G98004 010201 A/B/A G98001
G99022 010202 A/B/B G98001

のGID2の先頭2文字を'02'に変更できればOK。GNAMEはこの際置いとく。
一度のUpdate文で出来るかどうかはわかりませんが。



58 名前: 24 投稿日: 2001/03/12(月) 17:05
うーむ、確かに再帰的な検索があるときには便利ですね。
それは認めます。

>デッドロックにはなりませんよ。

そうですか? 階層構造の変更が行われるときには当然1トランザク
ション内で更新される必要があるから、関連レコードすべてがロック
されますよね? で、その中の複数レコードを更新する別トランザク
ションがあったらデッドロックになりませんか?

よく考えてみると、GROUPテーブルのつくりはそのまま(もしくは
親子関係を表現するテーブルを別に作る)で、GROUPを参照する
テーブルのほうがGIDのみでアクセスすればすむんじゃないですか?


59 名前: 46 投稿日: 2001/03/12(月) 17:11
>>58それはデッドロックとは言わないと思う。

>よく考えてみると、GROUPテーブルのつくりはそのまま(もしくは
>親子関係を表現するテーブルを別に作る)で、GROUPを参照する
>テーブルのほうがGIDのみでアクセスすればすむんじゃないですか?

作った人じゃないから知らんけど、joinするよりしない方が速いから
そうしたんじゃないの?


60 名前: 55 投稿日: 2001/03/12(月) 17:25
>>58
> 階層構造の変更が行われるときには当然1トランザク
>ション内で更新される必要があるから、関連レコードすべてがロック
>されますよね?
それはそのとおり。

> で、その中の複数レコードを更新する別トランザク
>ションがあったらデッドロックになりませんか?
それは、更新の待ち行列に入るだけで、デッドロックとは言いません。

>よく考えてみると、GROUPテーブルのつくりはそのまま(もしくは
>親子関係を表現するテーブルを別に作る)で、

今回の例の場合は、GROUP_TABLE内においては、親が1レコード
しかないので(親:子=1:n)、複数テーブルに分ける必要は無いと思います。

>GROUPを参照する
>テーブルのほうがGIDのみでアクセスすればすむんじゃないですか?

だーかーらー、パフォーマンスの関係で、ジョイン無しに
USER_TABLEだけからツリーを引っ張り出すことをしたいし、
そのようなことが良くある、みたいな状況だと、
USER_TABLEにGID2を入れる戦略もアリだって。

そーゆーこと無しに、その設計が正しいのかどうかなんて議論は
出来ませんって。
そーゆーこと無しに判断するなら、今回のテーブル設計は、それ
ほど間違いは無い、ってことしか言えないんじゃない?


61 名前: 55 投稿日: 2001/03/12(月) 17:29
なお、私個人としては、今回のGID2のような
「再帰構造を線形構造にする」みたいな考え方は、
RDBにはなじまない、と思っています。

でも、これが無いと、エラク検索が大変になりそう。


62 名前: 24 投稿日: 2001/03/12(月) 17:50
>それは、更新の待ち行列に入るだけで、デッドロックとは言いません。

だから「複数レコードを更新する別トランザクション」って書いて
いるでしょう。もちろん必ずおきるわけではありませんが、1回の
トランザクションでロックするレコードの数が増えれば当然デッド
ロックの危険性は高くなりますよね?

>回の例の場合は、GROUP_TABLE内においては、親が1レコード
>かないので(親:子=1:n)、複数テーブルに分ける必要は無いと思います。

まあ確かにそれほど必要ではないですね。ただGROUPテーブルの大きさ
や更新の頻度によっては、更新時のページ分割やレコード転送などが
無視できないかな、と思ったので。

>だーかーらー、パフォーマンスの関係で、ジョイン無しに
>USER_TABLEだけからツリーを引っ張り出すことをしたいし、
>そのようなことが良くある、みたいな状況だと、
>USER_TABLEにGID2を入れる戦略もアリだって。

うーん、まあそれはそのとおりですね。よっぽどその検索のレスポンス
が要求される場合でない限り、そういう設計はしたくないですが(~~;)


63 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 20:36
>>62
> トランザクションでロックするレコードの数が増えれば当然デッド
> ロックの危険性は高くなりますよね?

あ、更新の順序が決まっていなくて、しかも、逐次行ロック(とかいう
言葉は多分無いけど、雰囲気分かりますよね)していく場合ですね。

それは、確かにおっしゃるとおりです。
あまり、そのようなことしないので、気づきませんでした。

# ところで、1さんのRDBMSは何を使ってるんでしょうね?


64 名前: デフォルトの名無しさん 投稿日: 2001/03/12(月) 20:42
>>62
>うーん、まあそれはそのとおりですね。よっぽどその検索のレスポンス
>が要求される場合でない限り、そういう設計はしたくないですが(~~;)

私もあまりしたくありませんが、例えばディレクトリやファイルのモデル
をデータベース化しようとしたときに、「フルパス」という属性は入れる
と思います。get_fullpath()ってありがちでしょ?
これを、ルートディレクトリまで再帰的にたどっていかなきゃ分からない
としたら、それはそれでツライかも。



65 名前: 63 投稿日: 2001/03/12(月) 20:49
やっぱり、前言撤回。
fullpathという属性は入れません。
get_fullpath()というストアードファンクションで実装かな・・・


66 名前: 48 投稿日: 2001/03/14(水) 11:32


>50
>付けた英単語を見て、万人がその内容を想像出来るかどうか、
>という問題はおいときます。

>私が良くやる方法は、まず対象カテゴリで頻出の英単語(その
>カテゴリ名ズバリが分かればそのほうがなお良い)で、英語圏
>のサイトをいくつか検索します。
>で、そのカテゴリや概念の説明ページを探し、そのカテゴリに
>対する正しい英単語を調べます。

なるほど確かにプロジェクト全体が把握できるのが最優先ですね

この方法でしたら多少込み入った用語でも
英単語化できそうですね
どちらにしろ英語はできないと厳しそうですが(^^;

>49,51
まとめて
gooとexciteはしってたのですが
やはり込み入った単語が出てこなかったので
そのときほかの人はどうしてるか気になったもので
他にもこの様なサイトが有ります

http://www.alc.co.jp/



67 名前: デフォルトの名無しさん 投稿日: 2001/03/14(水) 16:33
>>55
GID2があったって良いけど、それを外部に対するキーにするなという主張だと思うぞ。
GID2の変更をそれを参照している全てのテーブルに反映させるのはなんというか…
つーかGIDとGID2だけを持ったテーブル作れば良いじゃん。


68 名前: 55 投稿日: 2001/03/14(水) 17:46
>GID2があったって良いけど、それを外部に対するキーにするなという主張だと思うぞ。
>GID2の変更をそれを参照している全てのテーブルに反映させるのはなんというか…

まぁ、確かにうざいんだけど、非正規化したことが設計ミスかどうかは、
何をトレードオフにしたかによるので、一概にどうこう言えないと思いますよ。
トリガーが使えれば、同期させるのは自動にできるわけだし。


69 名前: 24 投稿日: 2001/03/14(水) 18:57
>まぁ、確かにうざいんだけど、非正規化したことが設計ミスかどうかは、
>何をトレードオフにしたかによるので、一概にどうこう言えないと思いますよ。

まあ、GID2が夜間バッチで変更されるようなものならそれほど影響は
ないでしょうね。

その辺は1を書いた人に出てきてもらわないとわからんことですが...

>トリガーが使えれば、同期させるのは自動にできるわけだし。

どっちかっていうと更新処理の「手間」よりも、同時に更新される
レコード数が爆発的に多くなる可能性があることが問題なので、これ
はあまり説得力がないと思います。


70 名前: デフォルトの名無しさん 投稿日: 2001/03/14(水) 19:39
おーい、1さんよぉ〜
出てきとくれ


71 名前: デフォルトの名無しさん 投稿日: 2001/03/14(水) 21:15
正規化の意味が分かってるのか?
GID2を主キーに使うというのは非正規化じゃないぞ。変更されるものが
なんで主キーなんだ?
#まあ言葉の定義なんぞ人によって違うからそれを非正規化といっても良いけど

この場合の非正規化とはGID2を別テーブルにせず、GIDとGID2が2つとも
(只の)キーとして1つのテーブルに存在することであって、主キーとしてGID2を
選択するのはただの間違い。



72 名前: デフォルトの名無しさん 投稿日: 2001/03/15(木) 02:36
っていうかさ、こういうテクニックは効果的だけど
使用ルールを徹底してほしいよ。




73 名前: 55 投稿日: 2001/03/15(木) 12:16
>>71
>GID2を主キーに使うというのは非正規化じゃないぞ。
ではなくて、GID2をGROUP_TABLEに持つことを非正規化と言っています。
多分、第2正規形に違反(というのか?)していると思います。
また、そのコピーをUSER_TABLEに持つのも、非正規化です。

「主キー」というのは、1さんが主キーというものの意味を誤解している
ために出てきた言葉だと思いますよ。
おそらく、実際のテーブルは、>>37のような構成になっていると思います。
constraint primary key pk_group_table (gid, gid2)
だったら、痛すぎですけど。


74 名前: デフォルトの名無しさん 投稿日: 2001/03/15(木) 13:42
>>71
>#まあ言葉の定義なんぞ人によって違うからそれを非正規化といっても良いけど

正規化したものを崩すことが「非正規化」と言うのでは?
正規化する前のものを「非正規化」とは言わない。
それは、「正規化していない」と言うのが正しい。
・・・と私は思う。


75 名前: >65 投稿日: 2001/03/21(水) 13:25
蒸し返すようだけど・・・
>get_fullpath()というストアードファンクションで実装かな・・・

DBMSによるけど、複数レコードが返ってくる事を考えるとめんどくさくない?


76 名前: 75 投稿日: 2001/03/21(水) 13:47
スマn、言葉足らず

多分

select gid1 from group_table where get_fullpath(gid1) like '%01%'

とか使うつもりでget_fullpath(gid1)って使うんだろうけど、
複数レコードが欲しいときが多ければ

get_fullpath('%01%')

みたいな使い方の方が便利そうだけど・・なぁ・・・
って意見


77 名前: デフォルトの名無しさん 投稿日: 2001/03/29(木) 21:58
      ,一-、
     / ̄ l |   / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
    ■■-っ < んなーこたーない
    ´∀`/    \__________
   __/|Y/\.
 Ё|__ | /  |
     | У..  |




78 名前: デフォルトの名無しさん 投稿日: 2001/03/29(木) 23:53
ある程度のシステムなら正規化原理主義でいくべきかもしれない。
最近思うな。


79 名前: デフォルトの名無しさん 投稿日: 2001/03/30(金) 02:08
その、ある程度ってのがむずかしくない?

最大1万件って話だったのに、運用してみたら10万件になったり
とか


80 名前: デフォルトの名無しさん 投稿日: 2001/03/30(金) 23:09
数十万件くらいなら、どうでもいいでしょ。
数百万件くらいから、真剣にテーブルを考えましょう。


81 名前: 投稿日: