• ベストアンサー

データベース設計、同一マスターへの外部キーについて

例えば社員マスターテーブルがあり、稟議書のテーブルがあったとします。 稟議書のレコードには、作成者、指示者、承認者など、 社員を入れるべき項目がいくつもあり、 データ上はIDとしたいですが、表示は氏名を利用したいと思っています。 こういった場合はどうテーブル設計したらいいでしょうか、 または皆様はどういうテーブル設計にしているでしょうか。 私は以下の2案しか思いつきませんでしたが、 もっとスマートな方法、または実際にどうしている、 どうすべきなどありましたら、ご教授、ご意見ください。 よろしくお願いいたします。 案a.稟議書テーブルに各項目の社員IDフィールドを作り、 表示時は、必要数分の社員マスターテーブルを別名で結合する →リレーションとしてあまり正しくない? 処理が重くなる? 案b.稟議書テーブルに各項目分の社員IDフィールドと 社員氏名フィールドも作る →冗長である? 整合性が問題?

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

案a.で良いのではないかと思います。 >→リレーションとしてあまり正しくない? 処理が重くなる? 別に普通です。フィールドが幾つあるか知りませんが、100や200で 重くなるようなDBシステムでは使い物にならないでしょう。 案b.は稟議時のデータの正確性を異常に気にする場合には必要です。 例えば、稟議作成者が、結婚などで姓名が変更されたとします。 稟議データ自体は変更しないのに、社員マスタ更新前後で出力内容が 変化しますね。こういうのを許すか許さないかで、氏名フィールドの 要否が決まります。

coffret
質問者

お礼

なるべく複雑な結合をしないように シンプルなテーブル設計にした方がよいと言われていたこともあり、 また書籍やサイトなどで調べようとしても、 似たような事例やその設計に対する解説が見つけられず、 実際にはどう設計すべきなんだろうと悩んでおりました。 そういった意味で、普通と言っていただけ安心いたしました。 また、氏名フィールドの要否についても参考になりました。 ご回答ありがとうございました。

その他の回答 (1)

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

検索効率を重視したとしても、案bはさすがによろしくないと思います。フローが固まっているならば案aの方式ですかね。 他の方法としては別テーブルを作って、承認履歴を縦持ちさせる方法があります。 承認履歴テーブル(稟議書番号、ワークフロー番号、社員ID、日時、承認者コメント) で、稟議書番号、ワークフロー番号、社員IDに外部制約を掛けます。 一覧表のビューを作成する上では1の方式と比べてパフォーマンスがいいということはありませんが、 稟議書システムは性質的に後で承認フローが伸びることもあるので、しっかり要件が固められない場合や汎用的に作りたい場合は、 データ件数やDBMSの仕様(ビューにインデックスが張れるかなど)を検討した上で、この方式でやるかもしれません。

coffret
質問者

お礼

bの方がイレギュラーで、基本的にはaが正しいのですね。 他の方法についても、どう設計すべきかの判断材料や参考として、 大変有益な情報でした。 今回は項目(フロー)がほぼ固まっていることと、 おっしゃるとおりビュー作成でa案と変わらない処理であろうことから、 とりあえずa案でいこうかと思います。 ご回答ありがとうございました。

関連するQ&A

  • データベースのマスタ設計についての質問

    現在データベースの設計を勉強しています。 マスタの設計について疑問があって質問しました。 【1】すべてのマスタデータを統合したテーブルを作成 カラム1:カテゴリID(PK) カラム2:カテゴリCD(PK) カラム3:値 【2】それぞれのカテゴリに応じたテーブルを作成 カラム1:カテゴリCD(PK) カラム2:値 ※私はパターン1の方が、カテゴリの追加等柔軟かなと考えています。 それぞれのパターンの長所・短所を教えてください。

  • FileMakerProでリレーションについて

    FileMakerについて教えてください。 以下のようなテーブルがあるとします。 テーブル1:個人マスタ フィールド:氏名 テーブル2:測定値 フィールド:氏名 フィールド:測定日 フィールド:身長 フィールド:結果 以下のような一覧を作成したいと考えております。 氏名、測定日、身長、結果 身長の平均、最小値、最大値 結果には個人マスタには存在するが、測定値がない場合”無” という値を入れたいと考えております。 テーブル1とテーブル2をテーブル1を元に氏名で リレーションすると個人マスタの数しか一覧に表示されません。 テーブル2の測定値を元にリレーションすると個人マスタに 登録されているが、測定値がない人が表示されないのですが どう処理したらいいのか教えていただけないでしょうか。 よろしくお願いします。

  • データベースの設計について教えてください。

    データベースの設計について教えてください。 基本的な質問ですみません。宜しくお願いいたします。 単純なテーブルで表現しますが、 パターンA、Bのどちらのテーブルで設計するのが良いのでしょうか。 DBはmysqlで5000万件のデータで検索のみのデータベースです。 【前提】 ユーザは複数のメールアドレスを持ちます。 画面から、このユーザのもつメールアドレスを表示させる仕様だとします。 【userマスタ】 (PK)ユーザID   ユーザ名   会社名 <パターンA> 【mailテーブル】 (PK)ユーザID (PK)ユーザメールアドレス   モバイル用アドレス <パターンB>  【mailテーブル】 (PK)ユーザメールアドレス   モバイル用アドレス   ユーザID ←インデックスをはります。

    • ベストアンサー
    • MySQL
  • 社員マスタの氏名について

    Access2000で社員マスタを作成しているのですが、氏名を「氏」と「名」に 分けて作ったほうがいいのか「氏名」を1つのフィールドにしようか悩んでいます。データベース設計経験のある方、この場合どうすればいいのか是非教えてください。

  • 2パターンのデータベース設計で最適なほうはどちら?

    こんにちは。 データベース設計をするにあたり、迷っています。 言語はRuby on rails、DBはMysqlです。 たとえば日記サイトを作るとして (1)テーブル : users , diariesがあって、それぞれのidはuser_diaries というリレーション用のテーブルを作って持たせる (2)テーブル : users , diariesがあって、diaries にuser_id というカラムを持たせる というような作り方ができると思うのですが、どちらが優れていると言えるでしょうか? 決めの問題でしょうか? 将来的に大きなサイトになっても大丈夫なようにしておきたいです

  • リレーション?参照整合性の謎?

    Ac2000です。 「T_メンバー一覧」(テーブル) ・ID ・名前 ・所属 「T_マスタ」(テーブル) ・ID ・名前 ・所属 ・備考 とします。 それぞれからフォームを作成し、「F_マスタ」のフォーム上で IDはコンボボックスとし、ここでIDを指定すれば 名前と所属が入るようになっています。 「T_メンバー一覧」に変更があった場合(所属が変わるなど)に、 「T_マスタ」も自動で変更されるようにしたいのです。 T_マスタにデータが入っている場合です。(1件のみ) リレーションをはり、ID同士で設定しました。 「参照整合性」にチェックをし作成しようとすると、 「T_マスタ」テーブルのデータが参照整合性の規則に違反しています。 たとえば、ある社員に関連するレコードがリレーションテーブルにあるときに、 この社員に関連するレコードが主テーブルにありません。 ・・・・ となってしまうのです。 T_マスタにデータが入っておらず、上のリレーションが成功したあとに、 入力をしようと、F_マスタを開き、IDを選択して、 フォームを閉じようとすると、 「テーブル 'T_メンバー一覧'にリレーションシップが設定されたレコードが必要なので、 レコードの追加や変更は行うことはできません。 となります。 この2点を解決する回避策を教えてください。

  • データベースの設計について

    朝からデータベースの設計について悩んでいます。 テーブルにしたいデータがあるのですが、 それぞれカテゴリーが違うデータがあります。 構造的には少ししか違わないのですが、 これらのデータを1つのテーブルとしてまとめるか、 それとも、それぞれ1つずつのテーブルにするか迷っています。 迷っている理由として: ・同時にアクセスがあった場合、全て一つのテーブルにまとめていると、障害がないか? ・全てを1つのテーブルにすると、多少は構造が違うので、必要のないフィールドが出てしまう。 それぞれを1つのテーブルで分割するということも考えたのですが、 例えば、全てのデータからある特定のデータの検索をかける場合に 不都合なのではないか?と考えてしまいます。 こういう場合には: select * from table_A where field="検索したいデータ"; select * from table_B where field="検索したいデータ"; select * from table_C where field="検索したいデータ"; とテーブルの分だけSQLを実行するしかないのでしょうか? どちらを選択しても、それぞれ一長一短のようで、混乱しています。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • データーベース設計段階での質問です。

    データーベース設計段階での質問です。 管理しなければならないフラグ項目が100近くあり、そのフラグがよく検索対象になります。ただし、1レコードにつけられるフラグは10個までと決まっています。現在使用中のデータベースでは10個のカラムをつくっていて、そこに対象フラグのIDを列挙しています。 例えば A項目に対して1,20,34,56,78 B項目に対して3,6,11,15,42,78,89 のフラグがたっている場合、 name f0  f1  f2  f3  f4  f5  f6  f7  f8  f9 ------------------------------------------------------ A   1   20  34  56  78  null null null null null B   3   6   11  15  42  78  89  null null null となっています。他に日付などのカラムが5項目ほどあります。 このままだと検索等でややこしいことになるため テーブルを整理したいと思っています。 1.100個のboolean型のカラムを作る 2.ビットフラグ(ビットフィールド)のカラムを4つほど作って、検索時ビット演算する 3.項目名(ID)とフラグNo、だけの2カラムで構成した別テーブルを作ってjoinする 4.文字列としてIDを格納し、フルテキストインデックスをはる などがあると思うのですが、効率のいい設計がいまいちよくわかっていません。 上記の方法以外にも何かいい方法があると思います。 このような場合の、テーブル設計の方法を教えて下さい。

  • 出勤管理のデータベース設計

    ↑をアクセスで作成しています。今のところ、社員テーブル、作業場テーブル、部門テーブルなどを作ってあるのですが、肝心の出勤データはどう設計すればよいのかぜんぜんわかりません。月ごとに申告するものですが、年、月、日、さらに一日分の出社時刻、退社時刻、場所、その他いくつかの項目があり、複雑すぎてどうやればわかりません。もちろん社員分のデータ管理なので、一人分ではありません。かなりぱにくってます。どうぞおしえてください。

  • 外部キーを切り替えられますか?

    データベースの概念として間違ってるかもしれませんので、そのへんも指摘していただければ幸いです。 以下このような感じです。 正社員 --------- ID,Name,役職, 1,田中,社長 2,山田,部長 3,井上,課長 パート社員 ----------- ID,Name 1,佐藤 2,山口 という2つのテーブルがあったときに、 通勤手段 ---------- ID,手段,(外部キー:正社員、あるいはパート社員のID) 1,車,正社員の1 2,電車,正社員の2 3,バイク,正社員の3 4,車,パート社員の1 5,電車,パート社員の2 というように、外部キーを切り替える感じで テーブルを作ることはできますか? 正社員の通勤方法テーブルとパート社員の通勤方法テーブルを分けて作って、検索時にUNIONするのが正攻法ですか? (項目名、テーブル名は例です。)