質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

3回答

2858閲覧

データベースの正規化について

退会済みユーザー

退会済みユーザー

総合スコア0

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

1クリップ

投稿2016/10/09 10:34

データベースの正規化について質問です。
「達人に学ぶDB設計徹底指南書」という本で勉強しています。
その本の演習問題についての質問です。
以下転載します。
「次のような「支社支店商品」テーブルについて考えます。主キーは「支社コード、支店コード、商品コード」です。このテーブルを可能な限り、高次に正規化してください。

支社支店商品
![イメージ説明]

答えはこちらになります。以下に示します5つのテーブルになります。(見にくくて申し訳ないです。)
イメージ説明
イメージ説明

そこで質問なのですが、商品テーブルについて考えた時に、これは第3正規化がなされているのでしょうか?
第3正規化がなされたテーブルというのは推移的関数従属をテーブル中に持たないはずですが、このテーブルは
{商品コード} -> {商品名} -> {商品分類コード}
となっているように思えるのです。
すなわち、このテーブルはまだ分割の必要があるのではないでしょうか?

もう一点あります。
最後の支店商品テーブルについてなのですが、主キーだけで構成されている、いわゆる関連エンティティに対応するテーブルになると思います。
第4正規化を考えると、これもさらなる分割の必要があるように思えるのですが、どうなのでしょうか?
以上、2点回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

例題

結果となるテーブル

支社CD支社NM支店CD支店NM商品CD商品NM

細分化

支社CD★支社NM
支社CD★支店CD★支店NM
商品CD★商品NM

関連付けテーブル

支社CD★支店CD★商品CD★

支店支社の組み合わせに対する商品ですので限界ですね。※ 支店コードの重複をみてなかった・・・

投稿2016/10/09 13:10

編集2016/10/09 13:13
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

第3正規化がなされたテーブルというのは推移的関数従属をテーブル中に持たないはずですが、このテーブルは

{商品コード} -> {商品名} -> {商品分類コード}
となっているように思えるのです。

商品コードはプライマリキーですので、商品コードからタプルが一意に特定できると考えれば、最初の矢印は特に不思議では無いと思います。
また、同様の商品名で異なる分類コードを持つ商品が存在することも考えられますので、一般に商品名のみで商品分類コードを特定することはできません。
したがって、これは関数従属ではありません。(この表に存在するデータのみを考えた場合は関数従属のように見えますが…)

最後の支店商品テーブルについてなのですが、主キーだけで構成されている、いわゆる関連エンティティに対応するテーブルになると思います。

第4正規化を考えると、これもさらなる分割の必要があるように思えるのですが、どうなのでしょうか?

「連関」エンティティですね。
これらの外部キーは各々他の表のプライマリキーですので、これ以上の情報無損失分解はできないと思います。(支社コードと支店コードを別の表にすると支店名が特定できなくなります)

投稿2016/10/09 13:09

carimatics

総合スコア740

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/10/09 14:43

>同様の商品名で異なる分類コードを持つ商品が存在することも考えられますので なるほど、このように考えれば確かに問題はなさそうですね。 >支社コードと支店コードを別の表にすると支店名が特定できなくなります それは支店テーブルの話ではないのですか? 関連エンティティでは分割しても問題ないように思えるのですが、どうでしょうか?
carimatics

2016/10/09 15:34 編集

手元に本がないので要件がはっきり分からないのですが、「支店ごとに商品を扱っている」という要件なのかと推測しました。 表名も「支店商品」になってますよね。 つまり「支社コードごとに商品との連関を持たせる」ことに意味はないのです。 また、支店コードは支社ごとに持たせるので、「支店コードと商品に連関を持たせる」ことにも特に意味はないと思われます。 実際に上記の連関を確認すると、同じ東京支社であっても、渋谷では石鹸を扱っていますが、八重洲では扱っていません。 さらに、同じ支店コード(01)であっても、渋谷ではハブラシを扱っていますが、境では扱っていません。 以上を踏まえると、連関エンティティはこれ以上の情報無損失分解はできません。 しようとすれば分解したエンティティ同士に連関を持たせるために余計な属性を付与しなければなりません。
退会済みユーザー

退会済みユーザー

2016/10/10 08:15

なるほど、回答ありがとうございました。
guest

0

ベストアンサー

{商品コード} -> {商品名} -> {商品分類コード}

となっているように思えるのです。
すなわち、このテーブルはまだ分割の必要があるのではないでしょうか?

{商品名} -> {商品分類コード} というテーブルが必要という意見でしょうか?
と書けばおわかりでしょう。もちろんそれも成り立ちますが、{商品コード} -> {商品分類コード} という従属関係が成り立っているので分割の必要がありません。

最後の支店商品テーブルについてなのですが、主キーだけで構成されている、いわゆる関連エンティティに対応するテーブルになると思います。

第4正規化を考えると、これもさらなる分割の必要があるように思えるのですが、どうなのでしょうか?

私は{支社コード、支店コード} ー> {商品コード}の従属関係と捉えています。もちろん支社毎に取扱商品の契約をしなければならない事情がある場合は第四正規化の必要も考えられますが、考え過ぎに思えます。

投稿2016/10/09 12:58

iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/10/09 14:37

回答ありがとうございます。 >もちろんそれも成り立ちますが、{商品コード} -> {商品分類コード} という従属関係が成り立っているので分割の必要がありません。 それはすなわち第3正規化がなされていないということを意味するのではないでしょうか? {商品コード} -> {商品名} -> {商品分類コード} が成り立つというということは推移的関数従属が存在するということを意味して、これをなくすことが第3正規化の定義なのですよね? >私は{支社コード、支店コード} ー> {商品コード}の従属関係と捉えています。 そもそも関連エンティティとしてお考えではないという意味でしょうか?
iwamoto_takaaki

2016/10/09 15:01

> それはすなわち第3正規化がなされていないということを意味するのではないでしょうか? {商品コード} -> {商品名} -> {商品分類コード} が成り立つというということは推移的関数従属が存在するということを意味して、これをなくすことが第3正規化の定義なのですよね? まず何のために正規化するかという点があると思います。{商品コード} -> {商品分類コード}の関係が無いなら推移的従属関係を解消する意味がありますが、候補キー(主キー)に従属的で無いものを除くのが第三正規化だと思っています。(https://ja.wikipedia.org/wiki/%E9%96%A2%E4%BF%82%E3%81%AE%E6%AD%A3%E8%A6%8F%E5%8C%96#.E7.AC.AC3.E6.AD.A3.E8.A6.8F.E5.BD.A2) > そもそも関連エンティティとしてお考えではないという意味でしょうか? 関連エンティティの定義については失念しました。しかし、第四正規化は多値従属性の解消に使われると認識しています。(https://ja.wikipedia.org/wiki/%E5%A4%9A%E5%80%A4%E5%BE%93%E5%B1%9E%E6%80%A7) どのような、分割が可能でどのような問題を解消出来ると考えていますか?
退会済みユーザー

退会済みユーザー

2016/10/10 08:12

お返事ありがとうございます。 >{商品コード} -> {商品分類コード}の関係が無いなら推移的従属関係を解消する意味がありますが、候補キー(主キー)に従属的で無いものを除くのが第三正規化だと思っています。 iwamoto_takaakiさんの第三正規化の定義は 「推移的関数従属をなくすこと(ただし、全ての非キー要素が主キーに関数従属していれば、これ以上第三正規化をする必要はない)」 つまり、 {A,B,C} のテーブルに関して、Aが主キー、B,Cが非キーとすると、 A -> B and A -> C という関係が成り立てば、 A -> B -> C という推移的関数従属が見られても良いということでしょうか? http://ext-web.edu.sgu.ac.jp/HIKO/Prog03/SenpaiKyozai/shiohara/formalize.html こちらのサイトによると、全ての非キーが主キーに完全従属していても、推移的関数従属が見られれば、正規化する、といったようなことが書かれていますが、どうなのでしょうか? >第四正規化は多値従属性の解消に使われると認識しています。 私も全く同じの認識です。 この場合、(別の回答者の方からのご指摘で気づいたのですが)この関連エンティティを表しているテーブルはカラムは3つになっていますが、実質的には支店と商店のリレーションを表しているので、これ以上分割の余地はなさそうです。 今ではこのように思うのですが、これを教えていただく前は単純に3つの要素があって、多値従属性が見られるので、第四正規化の必要があるのではないか、と考えていました。
iwamoto_takaaki

2016/10/10 11:48

> A -> B and A -> C という関係が成り立てば、 A -> B -> C という推移的関数従属が見られても良いということでしょうか? はいそうです。特にデータが冗長になるわけでは無いと思います。 > http://ext-web.edu.sgu.ac.jp/HIKO/Prog03/SenpaiKyozai/shiohara/formalize.html こちらのサイトによると、全ての非キーが主キーに完全従属していても、推移的関数従属が見られれば、正規化する、といったようなことが書かれていますが、どうなのでしょうか? そのような記述があったように見ませんでした。こういった場合は引用をお願いします。 よくあるのが人物を表すのに[ID, 氏名, 住所, 性別, 電話番号]などの項目がある場合、IDがキーです。{ID}->{氏名, 住所} であると同時に{氏名, 住所}->{ID}でもあります。更に、{氏名, 電話番号}->{住所}、{ID}だったりもします。更に{ID}, {氏名, 住所}, {氏名, 電話番号}->{性別}という関係があります。 しかし、いずれの項目も{ID}に直接従属しているので、分解する必要はありません。この点は直感的に違和感がないと思いますがその点で納得出来ませんか。 > 実質的には支店と商店のリレーションを表しているので、これ以上分割の余地はなさそうです。 支店と商品のリレーションの誤りでしょうか?
iwamoto_takaaki

2016/10/10 13:10

> http://ext-web.edu.sgu.ac.jp/HIKO/Prog03/SenpaiKyozai/shiohara/formalize.html こちらのサイトによると、全ての非キーが主キーに完全従属していても、推移的関数従属が見られれば、正規化する、といったようなことが書かれていますが、どうなのでしょうか? > 上のテーブルでは主キー以外の属性は、主キーに完全従属しています。しかし(Genre_name)を見てみると(Genre_code)に従属しています。この関係を推移従属関係といいます。 この点を指しているのですね。確かにこの場合正規化の必要がありますね。{cinema_id}->{genre_name}が成り立ちます。この場合、cinemaテーブル内で、genre_idとgenre_nameの組み合わせが冗長で不整合を起こす可能性があります。 確かに私の主張に誤りがあったようです。 しかし、[商品名, 商品分類コード]というテーブル定義には断固として違和感を感じます。多分、個の組み合わせに関して不整合をおこしても問題ないと感じるからです。 商品コードが違えば商品名が同じであっても商品分類コードが違っても良いと思うのですがそれについての良い説明が思い浮かびません。
退会済みユーザー

退会済みユーザー

2016/10/11 02:48

お返事ありがとうございます。 だいたいおっしゃりたいことは理解できたように思えます。 [ID, 氏名, 住所, 性別, 電話番号]などの項目があった場合、IDが主キーである場合、主キーであるIDからの関数従属だけでなく、 {氏名、住所} -> {電話番号} の関係もありそうです。 その意味では推移的関数従属は残っているわけですが、直感的に見て、分割の必要はないから上のようなテーブルでも問題はない、ということでしょうか? >[商品名, 商品分類コード]というテーブル定義には断固として違和感を感じます。多分、個の組み合わせに関して不整合をおこしても問題ないと感じるからです。 >商品コードが違えば商品名が同じであっても商品分類コードが違っても良いと思うのですがそれについての良い説明が思い浮かびません。 これらの文章の意味についてお伺いします。 「この組み合わせに関して不整合を起こしても問題ない」というのは、私もいい例が思いつかないですが、 [商品ID, 商品, 商品分類コード] の組み合わせにおいて、 [009, 商品X, C1] かつ [010, 商品X, C2] を満たすような商品Xが存在しても良い、というのと同義でしょうか?
KaedeKazane

2016/10/11 03:03

>商品コードが違えば商品名が同じであっても商品分類コードが違っても良いと思うのですがそれについての良い説明が思い浮かびません。 こちらの例として1つ思いついたので失礼します。 ※[商品ID,商品名,商品分類名]の形式で表記します。 [001,ブラシ,掃除器具] [002,ブラシ,美容器具] あるいは、 [003,ブラシ,書籍] なんていう本もあるかもしれません。 恐らくこういったものの可能性を考慮しているのではないでしょうか。
iwamoto_takaaki

2016/10/11 04:07

KaedeKazaneさん、ありがとうございます。まさに、それです。 そもそも、idを使うのは長い名称を略すのもあるとおもいますが、名称変更や表記の揺れに影響されないため(アイデンティファイ)が一番の目的だとおもいます。
iwamoto_takaaki

2016/10/11 07:54

> その意味では推移的関数従属は残っているわけですが、直感的に見て、分割の必要はないから上のようなテーブルでも問題はない、ということでしょうか? はい。しかし、直観だけでなく論理的に考える必要もあります。 正規化を杓子定規に当てはめていくとどこまでも細かく作りこむことができます。論理的には{電話番後}→{住所}で正規化すべきという議論もできます。 しかし、文脈がレンタルビデオ店の登録会員であったら、会員の連絡先を登録するのに、それをしても意味がないこと明白です。こういった点は論理的にはやりずらい部分です。 商品名が一意になるかというのも(スマホなど)業種によって常識だったりします。 このあたりは実際の設計するにあたっての面白い部分だと思います。
Panzer_vor

2016/10/11 12:01

横やり失礼いたします。 > 正規化を杓子定規に当てはめていくとどこまでも細かく作りこむことができます。 論理的には{電話番後}→{住所}で正規化すべきという議論もできます。 データ整合性を担保するという目的に絞った正規化であれば、 第3正規形まででほぼほぼ保証できるので、 一般的な業務システムでは、 基本的には第3正規形までで十分なんですよね。 割りすぎると今度は結合コストが発生しますしね。 結局はバランスが大事ってことなんでしょうが。 後、商品コード、商品名、商品分類コードのお話は、 商品コードと商品名で相互に従属性があるのか、 数Aから引っ張ると「必要十分条件」を満たすか否かが鍵ですね。 必要十分条件であるならば多値従属性があると見なせなくもないですが、 そうでないならそもそも多値従属性があると見なせませんからね。 業務によっては商品名が決定しても、商品コードが一意に定まらないというのは稀によくある話なので。 そもそも第4正規形と、 第5正規形は関連を整理するための正規化であって、 第1正規形〜第3正規形までの実体を整理する正規化と異なることを念頭に置くと良いかもしれませんね。 商品コードと商品名を別テーブルに分割してしまうと、 1つの実体を分割することになるので、今ケースでは不適当かなと思うのです。
退会済みユーザー

退会済みユーザー

2016/10/13 13:10

みなさま、回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問