データモデル大全 論理フィールド について

12 views
Skip to first unread message

村井智哉

unread,
Dec 14, 2025, 6:26:57 AM12/14/25
to benky...@googlegroups.com
賛助会員の村井です。お世話になっております。
渡辺さんの著書にある論理フィールドを実現する方法について自分なりに考えてみました。
お気づきの点がありましたらコメントをいただけるとありがたく存じます。
よろしくお願いいたします。

・検討対象: 「データモデル大全」 p.56 「図3-7 論理フィールド(品種区分)を参照キーに含める」
・記述方法: 検討資料では上図を以下のように簡易的な表現とする。
 (Table)商品 => (Table)A (項目){商品ID} => {a} (項目)品種区別 => b
 (Table)受注 => (Table)C (項目){受注No} => {c} (項目)得意先ID => d (項目)商品ID => a 
     (項目)(品種区分) => (b)
 (Table)得意先別値引率 => (Table)D (項目){得意先ID, 品種区分} => {d, b} (項目)値引率 => e
・検討資料 "2025-12-14 SQL データモデル大全 論理フィールド.pdf"
・検討結果: カッコつき数字は上記検討資料内の番号を示す。
 (2) (Table)C に行を追加する場合
   {d, b} の組み合わせが (Table)D に存在する場合
     Trigger は (Table)A の b を (Table)C の (b) に copy する。
   {d, b} の組み合わせが (Table)D に存在しない場合
     Relationship 不成立のため (Table)C に行を追加できない。
 (3) (Table)C の行の d, a の値を変更する場合
   {d, b} の組み合わせが (Table)D に存在する場合
     Trigger は (Table)A の b を (Table)C の (b) に copy する。
   {d, b} の組み合わせが (Table)D に存在しない場合
     Relashionship 不成立のため (Table)C の値を変更できない。
 (6) (Table)A の行の b の値を変更する場合
   {d, b} の組み合わせが (Table)D に存在する場合
     Trigger は (Table)A の b を (Table)C の (b) に copy する。
   {d, b} の組み合わせが (Table)D に存在しない場合
     Trigger は A を変更させない。(いったん変更したものを戻す?)
 (7) (Table)A の行を削除する場合
   (Table)A の a が (Table)C の a に使われている場合
     Relationship により (Table)A の行を削除できない。
   (Table)A の a が (Table)C の a に使われていない場合
     (Table)A の行を削除する。(Trigger 不要)
 (10) (Table)D の行を削除する場合
   (Table)A の d, b が (Table)C の d, (b) に使われている場合
     Relationship により (Table)A の行を削除できない。
   (Table)D の d, b が (Table)C の d, (b) に使われていない場合
     (Table)A の行を削除する。(Trigger 不要)
・背景
 私はプラント電気設備の設計支援システムの仕様作成と試験を行っています。
 DBMS としては MS Access で開発し、DB 部分を SQL Server に置き換えています。
 今後、論理フィールドを使う場合に備えて、実現方法を検討しています。
・所感
 上記の処理は複雑なので Trigger など1か所にまとめてなければ
 処理を忘れることがありうると思いました。
2025-12-14 SQL データモデル大全 論理フィールド.pdf

Akipii Oga

unread,
Dec 14, 2025, 8:45:13 AM12/14/25
to sohai...@gmail.com, benky...@googlegroups.com
村井さん

はじめまして。あきぴーと申します。
他の皆様にもご無沙汰しております。

拝見したデータモデルを見たところ、
テーブルCに属性bを追加できるならば、
テーブルCの(d,a,b)にunique制約を追加することで
より簡単に実装できると思いますが、いかがでしょうか、

動的参照関係なので、属性bが暗黙的に追加されて、そこに関数従属性が生じる
暗黙的リレーションシップになりますが、あえてテーブルに属性追加した方が
モデル上も理解しやすく、実装上も簡単になるかなと思いました。

意図が違っていましたらご容赦ください。
以上、よろしくお願いいたします。

/****************************
Akihiko Ogawa (aki...@gmail.com)
/****************************/

2025年12月14日(日) 20:26 村井智哉 <sohai...@gmail.com>:
> --
> このメールは Google グループのグループ「IT勉強宴会」に登録しているユーザーに送られています。
> このグループから退会し、グループからのメールの配信を停止するには benkyoenkai...@googlegroups.com にメールを送信してください。
> このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAHq7Liqd4Yii9Km3j-3N76Cwo7n8MRJ3S%2BuiW9b2XD1hMBCf1g%40mail.gmail.com にアクセスしてください。

qyf0...@nifty.com

unread,
Dec 14, 2025, 6:14:45 PM12/14/25
to benky...@googlegroups.com
村井さん

導出項目や動的参照関係の実装方針についての話題ですね。まとめられた資料に問題はないと思います。ただしトリガーを使うと、移行時にRDBMS毎の方言に悩まされる可能性があります。私としては、RDBMSから独立したトリガー機能を搭載しているドメイン特化基盤(いわゆるローコード基盤)をお勧めしたいところです。トリガーの設定とアプリの設定とテーブル定義の設定を基盤内から切り替え無しにやれるという意味でも都合がいい。ただし、基盤の開発者毎にここらへんのスタンスは違っていて、Talonを作った古関さんは、RDBMSのトリガーを勧める立場だったりしますね。

あきぴーさん

cの値が異なるCのレコード間で重複し得るために、{d,a,b}のユニーク制約は役に立たないような気がします。どうなんでしょう。

渡辺幸三
このメールは Google グループのグループ「IT勉強宴会」の登録者に送られています。
このグループから退会し、グループからのメールの配信を停止するには benkyoenkai...@googlegroups.com にメールを送信してください。
このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAGobN%3Di9hD5GpE_uSuxFHMVai9%2B8aLcGeVytsZy5fbyvB-jGHw%40mail.gmail.com にアクセスしてください。

佐野初夫

unread,
Dec 14, 2025, 9:27:33 PM12/14/25
to sohai...@gmail.com, benky...@googlegroups.com
村井さん

 佐野です。問合せありがとうございます。

 動的参照関係をそのまま実装されるなら、添付に書かれた通りの実装で問題ないと思います。
私はSalesforceの技術者ですが、Salesforceの参照関係の機能でも動的参照関係を実装しようと
するとそこで書かれたようなトリガー処理が必要になります。

 とはいえこれを毎回実装するのは面倒です。少し視点を変えて楽することが多いです。

 データモデル大全の通り、テーブル名を<商品><受注><得意先別値引率>とします。
このポイントは、<得意先別値引率>の主キーが、次の複合主キーとなっていることです
 1. <受注>にある「得意先ID」
 2. <受注>にある「商品ID」から検索した<商品>にある「品種区分」
2の品種区分は、導出項目ですので、導出元である<商品>の「品種区分」が更新されると
参照する<得意先別値引率>のレコードが変わります。そのためトリガーが必要になります。

 こういう構造を設計するとき私は2つの事を気にかけてヒヤリングします。
 1. 動的といっても、変更される可能性はどの程度あるのか?
 2. 動的に変更しなければならない時間的余裕はどの程度か?リアルタイム?日次?

 ほんとに動的に変更すべきものもありますが、基幹システムであればほとんどありません。
この例でいうと<商品>の品種区分が変わるなんて何年かに1度でしょう。もし変わったとしても
その日のうちにバッチで更新すれば問題にならないでしょう。

 こういう条件ならもっと簡単な実装テクニックが2つあります。
◆実装案1
 導出される<商品>の「品種区分」の変更を禁止します。実装可能なら、<商品>の「品種区分」を
変更するときに、<受注>の中に変更しようとする「商品ID」があるかを検索し、あるとき変更不可にします。
(業務的には売上済みの受注は対象外にして検索するべきかも)
 変更したい時は、<受注>の値引率も再参照するバッチ処理を行います。
◆実装案2
 動的参照として<得意先別値引率>が必要なのは、「値引率」を参照するためなので、<受注>を登録
 するときにスナップショットとして<受注>に「値引率」を登録してしまいます。
 この実装例の「値引率」について10年前の受注が変わることが必要とも思えませんのでこの実装方法が
 お奨めです。「受注時点での値引率」という業務上の制約をつける事も合理的です。

ーーーーー蛇足
 案2の実装の話は以前谷島さんにインタビュー記事にしてもらいましたので参考にしてください。

 ここで偉そうに語っていることは、椿正明氏のデータモデリングの教科書で勉強したものです。
商品Mにある単価を、参照属性で持つか、断面属性(スナップショット)として持つか。
断面で持つ場合でも上書き不可とするかしないか、更新波及を許すか許さないか表記法がありました。

 椿さんのデータモデリング手法は、THモデリングと呼ばれていまでも(株)データ総研で教えてるはず。
マスタ(リソース)をオカレンスとタイプに分類する手法も椿さんに教わりました。これはついつい忘れがち
ですが意識すると業務分析が楽になります。タイプリソースの代表は商品マスタ、オカレンスリソースの
代表は社員マスタです。性質や更新タイミングが大きく変わります。

よろしくお願いします

2025年12月14日(日) 20:26 村井智哉 <sohai...@gmail.com>:
賛助会員の村井です。お世話になっております。

--
このメールは Google グループのグループ「IT勉強宴会」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには benkyoenkai...@googlegroups.com にメールを送信してください。
このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAHq7Liqd4Yii9Km3j-3N76Cwo7n8MRJ3S%2BuiW9b2XD1hMBCf1g%40mail.gmail.com にアクセスしてください。


--
--------------
佐野 初夫
http://www.benkyoenkai.org/
※毎月勉強会開催中。詳しくは上記webサイトまで

Akipii Oga

unread,
Dec 14, 2025, 10:33:39 PM12/14/25
to hats...@gmail.com, sohai...@gmail.com, benky...@googlegroups.com
村井さん、渡辺さん、佐野さん

お世話になります。あきぴーです。
村井さん、観点違いのメールで大変失礼しました。
皆様のコメントを再読してみます。
よろしくお願いします。


/****************************
Akihiko Ogawa  (aki...@gmail.com)
/****************************/ 


2025年12月15日(月) 11:27 佐野初夫 <hats...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAEKEWdJEqMhxUUsaGQyrLKZm-GmJvaCXuBm%2BpbYUiUKwafZeog%40mail.gmail.com にアクセスしてください。

佐野初夫

unread,
Dec 15, 2025, 12:24:11 AM12/15/25
to Akipii Oga, sohai...@gmail.com, benky...@googlegroups.com
小川さん

 佐野です。気にせず正しいと思うことは発言してください。間違っているかもしれない
ときは誰かがきっと上書きしてくれます。私はそういう感覚で発言しています。

>村井さん

 私はSalesforceを基盤として使いますので渡辺さんのデータモデルをそのままは実装
出来ないことが多いです。会社のブログにも書いたことがあります。

 例えばTMでモデリングした時そのまま実装するとエンティティが増えすぎて大変なことに
なりますので、サブタイプはまとめて実装される方が多いです。THモデルには「実装独立」
という便利な言葉があります。椿さんと飲んで議論した時「実装は興味ないから」と言われた
ことが数限りなくあります。それが逃げではないことはすぐわかりました。

 そういう理論と実践との違いに関しては本にも書かれていませんので実践されている技術者
さんに尋ねるのが時間短縮になります。いくらでも質問してください。

よろしくお願いします


2025年12月15日(月) 12:33 Akipii Oga <aki...@gmail.com>:

一倉徹

unread,
Dec 15, 2025, 12:55:06 AM12/15/25
to hats...@gmail.com, Akipii Oga, sohai...@gmail.com, benky...@googlegroups.com
小川さん

一倉です。

私も実装であれば、佐野さんが書かれている方法のうち、実装案2を採用する場合が多いと思います。
ただし、値引率としてです。

というのは、値引率は、マスタに登録した値を初期値として、上書きする場合も想定しているため。
(上書きを勝手にやられるとまずいので、このチェックも必要となってしまいますが)

また、値引きはルールも変わりやすいので、データモデルのみで表現するのが難しい場合もあります。
私が遭遇した実例だと得意先別、得意先のランク別、季節変動、重点商品の特別値引き、ボリュームディスカウトなどあり、なかなか一筋縄ではかないです。

論理でスーパー・サブがある場合、実装では、マスタはスーパー寄せ、トランは場合によってですが、サブ寄せにすることが多いですね。
マスターをサブ寄せにする場合は、トランにサブタイプ識別の属性を持たせないとマスタを特定できなくなるため、それを避けるというのもあります。



2025年12月15日(月) 14:24 佐野初夫 <hats...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAEKEWdKwZ7S9OFALd5uROte517eLgKvUN4uXD-bj47jx-SbePw%40mail.gmail.com にアクセスしてください。


--

村井智哉

unread,
Dec 15, 2025, 7:40:41 AM12/15/25
to benky...@googlegroups.com
あきぴーさん、渡辺さん、佐野さん、一倉さん。
村井です、コメントをいただき、ありがとうございます。
会社から帰宅後、図を見ながら考えてみました。(頭の中だけでは考えられないため)

・(Table)C に (d,a,b)にunique制約を追加した場合 ... 添付資料の(2)参照
(Table)C に d = d1, b = b1 で a = {a2, a3, a4} という (Table)A とは相いれない
タプルを登録することができてしまうことがわかりました。

・(Table)A の b を変更 ... 添付資料の(6)参照
(Table)A にタプルを登録する前に (Table)D に存在するか否かを判断する必要がある
と改めて気が付きました。

・「動的といっても、変更される可能性はどの程度あるか」 「時間的余裕はどの程度か」
この切り口は新鮮でした。今回の例は 「品種区分」、「値引き率」でしたが、各項目の
具体的な使い方をよく考える必要があることを理解しました。

・導出項目や動的参照関係の実装方法ついて
考え方が合っていることを確認できてほっとしています。
データベースを使い始めて4年目です。まだ Trigger を自分で作ったことはないため、
これを機会に作ってみて実際の動きを試してみたいと考えています。
ありがとうございました。
2025-12-15 SQL データモデル大全 論理フィールド 追加検討.pdf

qyf0...@nifty.com

unread,
Dec 15, 2025, 7:43:22 PM12/15/25
to benky...@googlegroups.com

村井さん、佐野さん

 

> こういう構造を設計するとき私は2つの事を気にかけてヒヤリングします。

> 1. 動的といっても、変更される可能性はどの程度あるのか?

> 2. 動的に変更しなければならない時間的余裕はどの程度か?リアルタイム?日次?

 

細かい指摘ですが、私の言う「動的参照関係」は「動的なプロセスを経て参照先レコードにアクセスするタイプの参照関係」という意味です。具体例に沿って言えば、受注レコードを起点として、「品目の品種区分を検索する」という動的プロセスを実行してから{得意先C+品種区分}で得意先別値引率レコードにアクセスするという形式の参照関係です。「関連するデータ項目の値が変化するゆえに動的」と呼んでいるわけではないんですよね。ゆえに、このコメントは次のように表現されるのが適切と考えます。

 

1. その動的参照関係に関与するデータ項目値が変更される頻度はどの程度あるのか?

2. その動的参照関係に関与するデータ項目間の値整合性が回復するまでの時間的余裕はどの程度か?リアルタイム?日次?

 

1について考慮すれば、たとえば品目マスターの品種区分を変更禁止にするといった措置が考えられます。品目の品種区分が変化するとしたら品目の同一性が変化しているとみなせるケースが多そうなので、無理なやり方ではありません。旧品目を削除して、それに代わる新品目を追加すればいい。また、受注上の品目を変更禁止にすることも無茶な感じはありません。変更したければその受注を削除してから新規追加してもらえばいいからです。

2については、リアルタイムを基本としたいところです。夜間バッチで整合性が回復するとしたら、昼間に眺める取引データに対して疑心暗鬼を持たざるを得なくなるからです。夜間バッチで整合性を回復させることが許容されるのは、統計・集計系のような特殊なデータに限られると思いますね。

 

渡辺幸三

--

このメールは Google グループのグループ「IT勉強宴会」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには benkyoenkai...@googlegroups.com にメールを送信してください。

このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAHq7Lio%2BPZd4QDtTgwZGt2YegkasEErxNnU43KTB1p3kdHgYaQ%40mail.gmail.com にアクセスしてください。

松下知博

unread,
Dec 15, 2025, 9:40:58 PM12/15/25
to qyf0...@nifty.com, benky...@googlegroups.com
渡辺さん、みなさま

実用面を考慮した検討も加わってきたように感じたため、
【品種区分を受注および後続データに追加する方法】もデータモデルにご検討の余地があるかと思い、割り込みさせていただきました。
冗長性とデータモデル制御に課題が発生します。アプリケーション側の制御も必要になりそうです。
業務上の例外をマニュアル処理し、部署間で連携できる、データ処理の例外をシンプルにできるメリットがあります。

受注の品種区分を加え、品目マスターの品種区分を初期値とする。
必要な場合、受注の品種区分を受注処理の制御に使用する。
例外がある場合、通常、受注登録時に、受注の品種区分を変更する。
受注の後続データ(出荷指示など)など業務上の要件がある場合、受注の品種区分を変更不可とし、変更履歴を保持する。

品目マスターの品種区分に基づき、棚卸資産(在庫金額)とする場合、
在庫がゼロの場合に品目マスターの品種区分を変更可とする。

受注および後続データに品種区分を追加する場合、
後続データは直前のデータを初期値とする。
重要度に応じて、品種区分を総勘定元帳明細にも追加する。

実用面を考慮する場合、細かい配慮・設計が必要と考えます。

不備・不明な点等お気づきの際にはお声がけいただければ幸いです。

松下

2025年12月16日(火) 9:43 <qyf0...@nifty.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/002e01dc6e24%24f7b84940%24e728dbc0%24%40nifty.com にアクセスしてください。

村井智哉

unread,
Dec 20, 2025, 10:07:48 PM12/20/25
to benky...@googlegroups.com
賛助会員の村井です。お世話になっております。
論理フィールドについて無料版である SQL Server Express で動作する Trigger を Copilot に相談したところ、以下を行うスクリプトを得ることができました。Text file [CREATE AND TEST.txt] として共有します。興味がある方が見えましたらご覧ください。参考まで。

(1) Database [Test05] を作成する。
(2) Table [TA], [TD], [TC] を作成する。
(3) Trigger [TR_TC_ValidateAll], [TR_TA_ValidateUpdate] を作成する。
(4) 自動的に動作試験を行い、結果を表示する。

Copilot との会話における重要な箇所を以下に示します。

(1) SQL Server には BEFORE INSERT トリガーが存在しないため、 AFTER INSERT トリガーで条件をチェックし、条件を満たさない行をロールバックする実装になる。

(2) [TD] - [TC] に FK を設定せず、Trigger で対応する。
  [TD] - [TC] に FK を設定すると、[TC].[A] を変更した際に [TD].[D] = [TC].[D] and [TD].[B] = [TC].[B] が成立しないタイミング ([TA].[B] を [TC].[B] に Copy する前) が発生するため、FK の Error が発生する。SQL Server には FK の遅延チェック (DEFERRABLE) をサポートしていないため、FK を設定せず Trigger で対応する。
 
(3) 動作試験の内容を以下に示す。
 (a) [TC] 正常 INSERT => 成功
 (b) [TC] 異常 INSERT => ロールバック
 (c) [TC] 正常 UPDATE => 成功
 (d) [TC] 異常 UPDATE => ロールバック
 (e) [TA].[B] 正常 UPDATE => 成功 + [TC].[B] 自動更新
 (f) [TA].[B] 異常 UPDATE => ロールバック
 (g) [TC] DELETE

CREATE AND TEST.txt

qyf0...@nifty.com

unread,
Dec 21, 2025, 12:49:23 AM12/21/25
to benky...@googlegroups.com

村井さん

 

無料版ではBefore Insertが使えないとは。ゆえに、Commit/Rollbackで対応する羽目になるんですね。なんとも強引なやり方です(^^;

 

渡辺

 

 

From: benky...@googlegroups.com <benky...@googlegroups.com> On Behalf Of 村井智哉

--

このメールは Google グループのグループ「IT勉強宴会」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには benkyoenkai...@googlegroups.com にメールを送信してください。

このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAHq7LiqPW-%3DGdw%2Be6LPNsRN5B%3DQd1dnpAVMDQ15oc82gyv3Fyg%40mail.gmail.com にアクセスしてください。

村井智哉

unread,
Dec 21, 2025, 4:39:33 AM12/21/25
to benky...@googlegroups.com
賛助会員の村井です。
今回、初めて Trigger を作成した (正確には Copilot に作ってもらった) ので BEFORE INSERT が使えないという Copilot の説明を鵜呑みにしています。

Copilot が示した Microsoft Learn [トリガー作成] (下記 URL 参照) を見る限りでは、Trigger の選択肢は AFTER と INSTED OF の 2種類で、 BEFORE が見当たりません。この説明は無料版限定ではないので、有料版も同様と考えます。

なお、BEFORE INSERT を使えないことについて、疑問を持っています。(ホントかな?)
どなたか、お気づきの点がありましたらコメントをいただけるとありがたく思います。
よろしくお願いいたします。

佐野初夫

unread,
Dec 21, 2025, 9:09:58 PM12/21/25
to benky...@googlegroups.com
村井さん その通りですね。

 SQL Serverには有償版でもBefore Trigger がありません

 他の主要なDBMSには全部にあります。
 Salesforceでもあります。Beforeの方が速いので良く使います。

 BeforeトリガーすらなくてDBMSと言って良いのかな・・・

佐野

2025年12月21日(日) 18:39 村井智哉 <sohai...@gmail.com>:
--
このメールは Google グループのグループ「IT勉強宴会」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには benkyoenkai...@googlegroups.com にメールを送信してください。
このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAHq7LirRPFeZcUiCqy6yLtqy_bwFZt97dMiA5FWbQEX8WyADyg%40mail.gmail.com にアクセスしてください。

村井智哉

unread,
Dec 23, 2025, 6:48:22 AM12/23/25
to benky...@googlegroups.com
一倉さん、佐野さん。村井です。
やはり SQL Server には BEFORE TRIGGER がないのですね。情報をありがとうございます。
「データモデル大全」のなかで自分にとって謎であった 論理フィールドの実現方法 を知ることができて今年の収穫となりました。

ところで、メーリングリストの操作を間違えたようで、リストが切れてしまいました。すみません。

明後日 (25日) は Zoom から参加します。引き続きよろしくお願いいたします。


2025年12月22日(月) 21:58 村井智哉 <sohai...@gmail.com>:
一倉さん、佐野さん。村井です。
やはり SQL Server には BEFORE TRIGGER がないのですね。情報をありがとうございます。
「データモデル大全」のなかで自分にとって謎であった 論理フィールドの実現方法 を知ることができて今年の収穫となりました。

ところで、メーリングリストの操作を間違えたようで、リストが切れてしまいました。すみません。

明後日 (25日) は Zoom から参加します。引き続きよろしくお願いいたします。

2025年12月22日(月) 11:09 佐野初夫 <hats...@gmail.com>:
このディスカッションを表示するには、https://groups.google.com/d/msgid/benkyoenkai/CAEKEWdK%2Bt%3DA3VzEh%3D%2BGJ_4fww8dcj1aj%3DLBez27kF%3DZRzWDdWA%40mail.gmail.com にアクセスしてください。
Reply all
Reply to author
Forward
0 new messages