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

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

ただいまの
回答率

89.69%

同じフィールドを複数テーブルで持つことは問題か

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 416

annderber

score 93

※ベストアンサー付けてしまいましたがこれは操作ミスで、まだ解決していないです。
お世話になります。

テーブル設計で悩んでいることがあります。
イメージ説明

非常に簡単な例ですが、上図のような商品マスタの設計で、
productテーブルには自社の製品コードと他のテーブル間(例ではproduct_info、deliveryテーブル)で共有するフィールドがいくつか入っています。product_infoはその製品の詳細なスペック表のイメージです。
問題なのはproduct_infoに入っている製品情報は自社だけでなく、他社の製品の情報も入っており、productとは別のコード体系で管理されていて、かならずしもproductテーブルと紐付いている訳ではないところです。

仕様ではproduct_infoテーブルはcsv形式でデータ更新を行う予定で、
product_infoを更新するときにproductテーブルに紐付いているフィールドはproductテーブルも更新します。

このような設計でも運用出来なくは無いですが、今後の運用に不安を感じています。
できれば同一のフィールドを複数テーブルで持ちたくないのですが、何か良い案はないでしょうか。

少し例が分かりづらいかもしれないですが、よろしくお願いいたします。

追記
product_infoテーブルで持っている他社製品情報はこのテーブル以外では参照しません

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

product は自社製品の情報
delivery は他社製品の情報
product_info は製品の詳細情報

という扱いで合っているのでしょうか。
この結果として、product_info のレコードは、product か delivery のどちらかに紐付く、と。

本来なら product_info を product と delivery のそれぞれに対して別々に用意した方がよいような気がします。
ただそれが出来ないなら、product_info には別の ID を振るようにして、そのIDとproduct、delivery のID との間を紐付けるためのテーブルを別に設けてやる感じでしょうか。

あるいは逆に、product と delivery を一つにまとめてしまう(自社でも他社でも「製品」だからエンティティーとしては一つ)か、ですかねえ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/09 17:47

    コメントありがとうございます。

    deliberyは納品先テーブルです。上図ではproductテーブルに紐付いているテーブルが複数あるという例で出しています。他社製品情報はproduct_infoのみで扱っています。

    キャンセル

  • 2018/08/09 18:52

    難しいですね

    キャンセル

+3

製品のコード体系が違うものを管理しようとするなら、製品コードのみだけでは管理できないですから、識別できる情報が必要です。
「会社コード+製品コード」などで一意にするしかありません。
但し、上記はナチュラルキーですので、リレーションに影響を与えないように、サロゲートキーで管理するのが良いかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

不安しか無いですね全部DBでやらなければならないんですか?
csvがプログラムから吐かれているものなら良いんですが、手作業が含まれていると高頻度でミスタイプでロールバックしなければならなくなると思います。
import失敗ならまだ良いですが、桁間違えみたいな正フォーマット誤データですと裏でゴリゴリ破壊が進みますよ。
さらに他社コードが自社コードと衝突したら目も当てられません。

なのでデータ更新プログラムを作るのをおすすめします。
その上で他社データを自社コード体型に吸収しproduct_infoに会社コードカラムと他社コードカラムをつけ自社なら空、他社なら他社(1社ならbool)コードと他社製品コードを入れるという案を考えます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/09 17:46 編集

    コメントありがとうございます。

    csvに関してはプログラムでもやる予定です。
    似たような設計は私も考えたのですが、
    product_infoテーブルに入っている他社製品レコードはproduct_infoテーブルだけで管理しているデータで他のテーブルからは参照されません(本来考えにくいことですが)。なのでそのようなレコードはproduct_infoテーブル内だけでとどめておきたいという気持ちがあります。
    情報の後出しで申し訳ないです

    キャンセル

+2

基底のテーブル(仮にproduct_base)で全ての製品に共通するカラムを定義します。
自社の製品はproduct_baseのプライマリキーに紐づいたテーブル(product)に自社製品だけが持つカラムを定義します。
product_infoもproduct_baseに紐づけます。
他社の製品も同様です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/09 18:34

    product_infoテーブルはproduct_baseを介してproducと紐づきます。
    この場合のproduct_baseは中間テーブルではなく親と思って下さい。

    キャンセル

  • 2018/08/09 18:47 編集

    すいませんちょっとイメージがわきません。自分がproductを一番の親だという考えが強いからかもしれません。
    また別の人をベストアンサーにしてますがこれは操作ミスです。

    キャンセル

  • 2018/08/09 19:01

    よく使われる「クラステーブル継承」パターンです。
    欠点としては自社製品でありかつ他社製品でもある製品が作れてしまう点があげられます。
    しかしこれはカラムが明らかに違うので実運用上問題となることが殆ど無いでしょう。
    詳しくは「クラステーブル継承」でググってください。

    キャンセル

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

  • ただいまの回答率 89.69%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる