- PR -

マスターテーブルの設計と入力画面について

1
投稿者投稿内容
ふみお
会議室デビュー日: 2007/11/07
投稿数: 5
投稿日時: 2007-11-07 20:14
お世話になります。

【1】昨今、下記のようなID等の代理キーを主キーとして設計するというようなガイドラインをよく見ますが、
  このような設計の場合、これらのマスターを利用するテーブル側ではコードではなく、IDが記録されます。
  しかしそうした場合、紐付けられるのはIDなので、マスターメンテナンス画面でレコードを物理削除した後、
  同じコードのレコードの再作成というオペレーションが行われた場合、紐付けはされません。
  そこでマスターメンテナンス画面および利用するテーブル側の画面ではどのようなUIにされていますでしょうか?

  1.マスターメンテナンス画面では商品IDを入力させ、利用するテーブル側の画面ではコードではなく、
  商品IDを選択させる。
  2.マスターメンテナンス画面では商品IDを入力させないが、利用するテーブル側の画面では自動生成された
  商品IDを選択させる。
  3.マスターメンテナンス画面でも商品IDを入力させず、、利用するテーブル側ではIDではなく、コ−ドで選択
  させるので、失われた紐付けはそのまま。(運用で修正と削除を区別してやってもらう等)
  4.マスターメンテナンス画面では削除機能を付けない。(使用しないデータはそのまま)
  5.その他

商品マスタ
--------------------------
商品ID |商品コード|商品名|
--------------------------


【2】【1】の質問のようにテーブル設計で代理キーを付けた場合、時系列に管理できるマスターテーブルも作成
  できますが、IDを記録された利用するテーブル側では、いつも登録時点のマスターテーブルを参照することに
  なります。これは予め、登録時点のマスターテーブルを参照したい場合と最新のマスターテーブルのデータを
  参照したい場合とできちんと判別できていることが前提でしょうか?
  例えば独自な業務等で時系列に持つデータなのか、最新のデータでよいものかどうか設計の段階では判断が
  付かない場合はどのようにされていますでしょうか?


以上、うまく説明できない文章ですがよろしくお願いします。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-07 22:05
【1】
当然4にしないと過去のデータと整合性が保てないので、さらに削除フラグのようなものを追加して論理削除するようなメカニズムにするのが一般的かと思います。
もしくは削除機能は追加するものの、そのIDが利用されてしまっている場合は削除をデータチェックなどでさせないようにするという対応にするかです。
それでもそうしたデータを削除する場合は運用でカバーです。

【2】
そもそも利用用途は要件を分析しデータベース設計の段階で区別をつけるべきです。
それでもなお汎用的に作成したいのであれば、とりあえず、利用開始、利用終了年月日のカラムだけとりあえず追加しておいて、アプリケーションの画面設計で現在年月日などを利用してマスタ値を登録できたり、できなかったりする仕組みにするべきでしょう。
ふみお
会議室デビュー日: 2007/11/07
投稿数: 5
投稿日時: 2007-11-08 10:55
Anthyhimeさんありがとうございます。

【1】についてですが、論理削除を行うと紐付けされたIDは残るので、参照整合性は確保されますが、新しいIDとの紐付けに関しては
やはりされないままという問題が残りますので、物理・論理とも削除を禁止してコード入力値を間違えたというような場合は値を修正
してもらうようにした方がいいのでしょうかね・・・
既に使用チェックにつきましては、テーブル数が多いのでコスト的に難しいかも知れません。


【2】につきましては、おっしゃる通り事前分析すべきですが、汎用的にしたいという訳ではなく、例えば、公共機関で法改正等で新しい
業務が発生するのは分かっているが詳細な情報が小出しにしか出てこない、あるいは遅くにしかわからない、といった場合です。
(システム開発期間を十分に見込んで情報を出してくれればありがたいんですが)
とりあえず最新のマスターデータを採用しておくというのが一般的でしょうか。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-11-08 11:32
引用:

ふみおさんの書き込み (2007-11-07 20:14) より:
商品マスタ
--------------------------
商品ID |商品コード|商品名|
--------------------------


拝見して良く分からなかったのですが、「商品ID」と「商品コード」の両方を持つからには、「商品ID」がDB上の主キーであって多くの場合はシーケンシャルなどを使いユーザーの目には見せず、「商品コード」はユニーク制約を付けるだけでこれはユーザーの目に見せるような感じでしょうか。

あとの紐付けや時系列の肝心の部分が良く分からなかったのですが、「商品ID」と「商品コード」の両方を持つことに直接関連する話なのでしょうか?(片方だけ持つ場合は生じない問題なのでしょうか?)

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
ふみお
会議室デビュー日: 2007/11/07
投稿数: 5
投稿日時: 2007-11-08 14:08
引用:

unibonさんの書き込み (2007-11-08 11:32) より:
「商品ID」と「商品コード」の両方を持つからには、「商品ID」がDB上の主キーであって多くの場合はシーケンシャルなどを使いユーザーの目には見せず、「商品コード」はユニーク制約を付けるだけでこれはユーザーの目に見せるような感じでしょうか。


unibonさんありがとうございます。

その通りです。ただ、ユーザーがコードベースで紐付けている感覚なのに対してDB上ではIDベースでの
紐付けになるということになります。
なのでIDが見えない(ユーザーが存在を知らない)ということは、画面からある商品コードの属性を変更
する場合、該当箇所だけを修正するパターンと、一度レコードを削除して再作成するパターンの2つの
オペレーションが考えられると思いました。
再作成されてしまうと、普通はIDの再利用は行いませんので新しくシーケンシャルなIDが振られます。
そこで削除されたIDを参照していた既存のテーブル群に不整合が発生するのではないか、というのが【1】
の疑問になります。
そこで選択肢のような対応を考えてみました。

引用:

unibonさんの書き込み (2007-11-08 11:32) より:
あとの紐付けや時系列の肝心の部分が良く分からなかったのですが、「商品ID」と「商品コード」の両方を持つことに直接関連する話なのでしょうか?(片方だけ持つ場合は生じない問題なのでしょうか?)



マスターテーブルの設計に関しては同じ質問なのですが、異なる内容だったので番号を振ったのですが、
別に投稿した方がよければ編集します。始めての投稿だったもので勝手がわからず申し訳ありません。
確かに【2】の時系列の問題は例えば自然キーである商品コードと履歴番号などを複合キーとする設計
でも発生します。(記録時点のマスターしか参照できない)
ただ、IDという自然キー以外の人工的なキーを設ける時点で、間接参照と時系列という概念が現れ、
一緒に話題にされることが多いので、二つに切り離して質問しました。
【1】が間接参照による疑問、【2】が時系列に関する疑問のつもりです。

おっしゃっている「片方だけ持つ場合」というのは自然キーである商品コードを主キーとする設計のことだと
思いますが、この場合はレコードを再作成しても同じ商品コードである限り、紐付けは維持されますので【1】
の疑問は発生しないと考えています。

[ メッセージ編集済み 編集者: ふみお 編集日時 2007-11-08 15:22 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-11-09 01:02
引用:

ふみおさんの書き込み (2007-11-08 14:08) より:
その通りです。ただ、ユーザーがコードベースで紐付けている感覚なのに対してDB上ではIDベースでの
紐付けになるということになります。
なのでIDが見えない(ユーザーが存在を知らない)ということは、画面からある商品コードの属性を変更
する場合、該当箇所だけを修正するパターンと、一度レコードを削除して再作成するパターンの2つの
オペレーションが考えられると思いました。
再作成されてしまうと、普通はIDの再利用は行いませんので新しくシーケンシャルなIDが振られます。


「商品ID」と「商品コード」の2つが登場していますが、ここでの「商品コード」はどっちかというと「商品名」に近い性質のものかな、と思います。「商品名」は極端かもしれませんが、「型番」ぐらい?

一方、「商品ID」は、(C言語などでいう)ポインターに近いものだと思いますので、参照されている側(マスターテーブルの側)を、勝手に消すわけにはいかないと思います。DB上では非マスターのテーブルからマスターを外部参照しているのに、勝手に参照先のマスターのレコードを削除できるのはキレイな設計ではありません。

でも、マスターからレコードを削除したい、ということはたしかにあります。典型的なケースとしては、商品の売り上げがあったので、売り上げテーブルには存在するが、その後その商品が製造中止になった場合などは、商品マスターからレコードを削除したいわけですよね。結局は、時系列の問題なのだと思います。時間が関わってくると、物事はとにかく複雑になります。

つぶしがきき、誰にでも分かるような素朴な設計としては、やはり、「削除フラグ」方式でしょう。そして、選択肢は「4.マスターメンテナンス画面では削除機能を付けない。(使用しないデータはそのまま)」になるのではないでしょうか。これはAnthyhimeさんがおっしゃることとほぼ同じですけど。

引用:

ふみおさんの書き込み (2007-11-08 10:55) より:
【1】についてですが、論理削除を行うと紐付けされたIDは残るので、参照整合性は確保されますが、新しいIDとの紐付けに関しては
やはりされないままという問題が残りますので、物理・論理とも削除を禁止してコード入力値を間違えたというような場合は値を修正
してもらうようにした方がいいのでしょうかね・・・
既に使用チェックにつきましては、テーブル数が多いのでコスト的に難しいかも知れません。


これは、旧商品を新商品に差し替えた場合、売り上げテーブル中の旧商品のファクトデーターまでも新商品に差し替えてしまうのでしょうか?売り上げたのは、旧商品ですから、その事実を後日に新商品に差し替えてしまうのは、過去を変えてしまうことになり、話がややこしくなりませんか?売り上げはあくまでも旧商品であり、それを残した上で、新商品とのマッピングの仕組み別途組み込むようにするほうが話は簡単になると思います。旧商品と新商品を同じグループに入れて管理すれば良いと思いますが、そうするとそのグループ用にテーブルを新たに作る必要があり、テーブルが増えてしまって誰でも分かるという設計でなくなってしまう恐れがあります。

まず、商品マスターテーブルはなにを管理するテーブルなのかという定義をはっきりさせるほうが良いでしょう。現行商品だけを管理するテーブルなのか、売り上げテーブルが持っている過去の商品も含めて管理するテーブルなのか、です。これがあいまいだと、ずっとあいまいなままでしょう。「削除フラグ」を付けるということは、現行商品か否かを判断するフラグになるわけです。
さらに【2】のような要求仕様だと、「削除フラグ」のような1ビットの情報ではなく、商品の生存期間のような日付情報が必要になるのでしょうけど、管理がさらに複雑になります。

エンドユーザーがDBを直接いじることがあるのかも重要なファクターでしょう。システムの設計がどうとかDBの設計がどうとかよりも、これがもっとも重要なことだと思います。エンドユーザーが「削除フラグ」はまだしも、「生存期間」などを正しく管理できる可能性は低いと見たほうが良いです。

以上、さほど、ブレークダウンしていない回答ですが、とりあえず書きました。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
ふみお
会議室デビュー日: 2007/11/07
投稿数: 5
投稿日時: 2007-11-09 14:05
引用:

unibonさんの書き込み (2007-11-09 01:02) より:
以上、さほど、ブレークダウンしていない回答ですが、とりあえず書きました。



いえ、大変参考になります。自分的には気軽な事でも色々書いて頂けた方がありがたいです。
それこそ表題の会議室みたいに。


引用:

unibonさんの書き込み (2007-11-09 01:02) より:
「商品ID」と「商品コード」の2つが登場していますが、ここでの「商品コード」はどっちかというと「商品名」に近い性質のものかな、と思います。
「商品名」は極端かもしれませんが、「型番」ぐらい?
一方、「商品ID」は、(C言語などでいう)ポインターに近いものだと思いますので、参照されている側(マスターテーブルの側)を、勝手に消すわけにはいかないと思います。
DB上では非マスターのテーブルからマスターを外部参照しているのに、勝手に参照先のマスターのレコードを削除できるのはキレイな設計ではありません。
でも、マスターからレコードを削除したい、ということはたしかにあります。
典型的なケースとしては、商品の売り上げがあったので、売り上げテーブルには存在するが、その後その商品が製造中止になった場合などは、商品マスターからレコードを削除したいわけですよね。
結局は、時系列の問題なのだと思います。時間が関わってくると、物事はとにかく複雑になります。



そうですね。、商品名と同じと言ってもよいかと思います。変更可能な一属性的な位置付けです。
おっしゃる通りご指摘の売り上げテーブルの例では、IDを付けた事によって生じた時系列概念の典型的な例だと思います。
ただ、私が【1】の疑問であげたのは、業務要件的なことではなく、例で言えば、売り上げテーブルに記録した後に単純に商品名を間違えていたことに気づいて修正しようとして削除→作成の手順で行ってしまった、というケースです。
もちろん商品名だけを修正すればよいのですが、削除ボタンがあればそういう操作も可能です。
やはり削除ボタンは付けない方向がよいみたいですね。不要なデータが存在するという件については表示フラグみたいなもので対応?でしょうかね。

引用:

unibonさんの書き込み (2007-11-09 01:02) より:
これは、旧商品を新商品に差し替えた場合、売り上げテーブル中の旧商品のファクトデーターまでも新商品に差し替えてしまうのでしょうか?
売り上げたのは、旧商品ですから、その事実を後日に新商品に差し替えてしまうのは、過去を変えてしまうことになり、話がややこしくなりませんか?



過去を変えるというよりも、先ほどの例のように過去の事実の記録が間違っていた、というケースになるかと思います。
旧商品、新商品につきましては事実(登録)に間違いがなければそれぞれマスターに別IDで保持することになるかと思います。
商品コードが主キーな設計だと利用されてしまった後でコードを変更するのは大変ですが、IDを付けるとこういう場合も対応できる、ということなのでしょうね。でもIDを付けると・・・というわけで質問を投稿した次第です。

引用:

unibonさんの書き込み (2007-11-09 01:02) より:
まず、商品マスターテーブルはなにを管理するテーブルなのかという定義をはっきりさせるほうが良いでしょう。
現行商品だけを管理するテーブルなのか、売り上げテーブルが持っている過去の商品も含めて管理するテーブルなのか、です。
これがあいまいだと、ずっとあいまいなままでしょう。



やはり【2】の疑問はこれにつきますかね。できる限り定義をはっきりできるよう努力したいと思います。
1

スキルアップ/キャリアアップ(JOB@IT)