- 締切済み
Accessリレーションシップについて
お世話になります。 Access2010 普段はクエリにて、いくつかのテーブルやクエリを紐づけているのですが リレーションシップの設定は今までやったことがありません。 ネットで調べて、 ・「参照整合性」にチェックを入れることにより、1対多の多側で1側に存在 しないIDで登録しようとするとエラーになる。 →間違ったデータが入力されるのを防ぐ。 ・多側でリレーションシップが設定されているフィールドに値を入力しない ことは可能。但し、当該フィールドの「値要求」プロパティを"はい"に した場合は、入力しないとエラーになる。 ・「フィールドの連鎖更新」にチェックを入れると、1側で変更したものが 多側でも自動的に変更される。 ・「レコードの連鎖削除」にチェックを入れると、1側で削除した場合、 多側で該当するデータをもつレコードが自動的に削除される。 上記については実際に試してみて動きを確認しました。 ※上記の認識違いや、もっと大事なことがあればご指摘、ご教示頂けると 幸いです。 今までは、こっちのテーブルで削除したらこっちのテーブルでも削除 みたいなことをやってたので、便利だとは思うのですが。。 以下のテーブルでリレーションシップの設定を行ったとします。 売上テーブル ID 商品 担当者コード 1 AAAAA 3 2 BBBBB 1 3 AAAAA 1 4 CCCCC 2 5 CCCCC 3 担当者テーブル 担当者コード 担当者名 1 担当者A 2 担当者B 3 担当者C 売上テーブルの担当者コードと、担当者テーブルの 担当者コードでリレーションの設定を行い、「参照整合性」及び 「レコードの連鎖削除」にチェックを入れたとします。 例えばフォーム上にリストボックスを設置し ID 商品 担当者名 を表示し、リストボックス上で選択されたレコードを、削除ボタンを 押したら、そのレコードが削除されるプログラムを作成します。 ※選択されたレコードのIDを取得し削除クエリで削除。 リストボックスでID:5のレコードを選択し、削除ボタンを押した場合 売上テーブルのID:5のレコードを削除しても、担当者テーブルから 担当者コード:3のレコードは削除されない・・という認識でよろしい でしょうか。 ※要するに、1対多の多側で削除されても1側には影響無し。 同様にリストボックスでID:5のレコードを選択し、削除ボタンを押したときに 担当者コード:3を取得し、まずは担当者テーブルで担当者コード:3の レコードを削除すると、併せて売上テーブルのID:1及びID:5が削除 される。 要するに、上記のケースで「レコードの連鎖削除」の設定を行うと 本来削除すべきID:5以外のレコード(ID:1)まで削除されてしまう ことになる?? ※そもそも例がちょっと悪かったかもしれません。。 何が言いたいかというと、「フィールドの連鎖更新」「レコードの 連鎖削除」は、よーく考えて設定しないと意図しないところまで 更新されたり削除されてしまうのかなと。。なので、設定することに よって、プログラムの作りも変わってきてしまうことになるので しょうか。 理解不足で質問自体もモヤモヤしたものになってしまいましたが、 ご教示のほど、宜しくお願い致します。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- chayamati
- ベストアンサー率41% (260/624)
- panacon
- ベストアンサー率31% (214/679)
naoto0216 さんへ 担当者の入れ替わりの件ですが、退職者の営業コードを新しい担当者に充てることはあまりしないと思います。若し、これを行うようであれば、担当者の営業コードに2つの日付を持って、いつからいつまでをAの担当者、次の期間をBの担当者にして、商品を動かした日付で紐づけていくようになると思います。これは、営業コードよりも、顧客コードを中心にして、いつどの商品を誰の担当で処理したというデータ構造にした方が良いと思います。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
【補足】リレーションシップの種類とオプション。 先の回答は、具体例のみで抽象的で概念的なそれではありませんでした。そこで、その意味するところを補足しておきます。 ≪リレーションシップにも種類(タイプ)がある≫ 1、発生時点での参照先を明らかにするためのもの。 2、発生時点及び変更時点での参照先を明らかにするためのもの。 3、参照ではなく主表、従表関係を明らかにするためのもの。 ≪リレーションシップにも種類とオプションは関係がある≫ 1では、連鎖参照と連鎖削除の設定は共にあり得ません。 2では、連鎖参照はあっても連鎖削除の設定はあり得ません。 3では、連鎖参照と連鎖削除の設定が必要・必須です。 例示の[売上履歴]と[担当者」は1に相当します。[商品台帳]と[商品枝番リスト]の関係は3です。ですから、「一体、このリレーションシップのタイプはどれなのか?」ということを検討したら設定すべきオプションも浮上してくると思いますよ。
- 山田 太郎(@f_a_007)
- ベストアンサー率20% (955/4574)
Q、Accessリレーションシップのオプション。 A、全てはケースバイケース。 例えば、質問のケースですと≪フィールドの連鎖更新≫と≪レコードの連鎖削除≫を設定することは不適当であってすべきではありません。 ・なぜ、[売上履歴].[担当者_ID]---->[担当者].[ID]なのか? 理由:テーブル[担当者]に不具合が発生しても[売上履歴」は表示される。 ・なぜ、[担当者].[担当者コード]でリレーションしないのか? 理由:[担当者コード]と[名前]とが修正・変更しても過去の履歴の書き換えを防げる。 1,無効,101,鈴木 2,有効,101,佐藤 このように複数の[担当者コード]と[名前]とを登録可能な設計をするのが一般的です。 ≪列[担当者コード]ではリレーションすべきではない≫ 上記のような考えに立てば、[担当者コード]はリレーション列には相応しくないということになります。また、何らかの事情で[担当者_ID]=1が参照不能になった場合に、テーブル[担当者]を速やかに復旧するためには[担当者_ID]ではオートナンバー型を利用すべきではないことも自明のことです。 【レコードの連鎖削除を設定すべきケース】 ≪レコードの連鎖削除≫を設定すべきケースってのも当然に存在します。例えば、[商品台帳]と[商品枝番リスト]の場合などです。 [商品台帳] ID__________1,2・・・・N 連鎖削除____Yes/No 商品コード__AAAA,BBBB [商品枝番リスト] ID__________1,2・・・・N 商品台帳_ID_1,2・・・・N 枝番名______S,M,L 在庫数______10 例えば、過去5年間の使用履歴がなくて、かつ、在庫数=0 の場合には[連鎖削除]=Yesだとします。この場合には、当然に、[商品台帳]を削除したら関連する[商品枝番リスト]は連鎖削除されてしかるべきです。ですから、当然に、レコードの連鎖削除を設定すべきケースだと言えます。 このように、Accessリレーションシップのオプションのどのように設定すべきかはケースバイケースではないでしょうか? と、私は思います。
- panacon
- ベストアンサー率31% (214/679)
naoto0216 さんへ 私は、連鎖削除は使用しないで、連鎖更新のみ使っています。 ご理解の通り、1対多の連携で、1を削除したときにそれに関連した多が削除されます。多の中の1行を削除しても1のほうは削除されません。参照整合性を組んだときには、多のレコードを全部消さないと1のレコードは削除できないようになっています。 サブフォームを使ったデータ入力で参照整合性は便利と思います。連鎖更新は多のレコードを増やすときに自動で1のKeyが代入されますので良いですが、データを蓄積する目的の中で、担当者のデータをすべて捨てる行為は無いと思います。若し、担当者がいなくなってバックグラウンドでデータを移行したいという事になったときは、多のデータを先に移行してから、1のデータを移行するようになると思います。ここは、連鎖削除に任せない方が良いと思います。
お礼
例では「売上テーブル」だから更新されない方がよいかもしれ ませんが、例えば、「顧客テーブル」で、 ID 顧客名 担当者コード 1 AAAAA 3 2 BBBBB 4 3 AAAAA 4 4 CCCCC 2 5 CCCCC 3 のような場合は、「担当者Aから担当者Xに引き継がれた」 ということで一括更新されてもよい(された方がよい) ケースなんですかね。
補足
panaconさま ご回答ありがとうございます。 >データを蓄積する目的の中で、担当者のデータをすべて捨てる >行為は無いと思います。 についてですが、質問に書いているテーブルを例にすると 担当者Aが退職し、担当者Xに代わった場合、担当者テーブルで 担当者コード 担当者名 4 担当者X 2 担当者B 3 担当者C のように更新したら、 売上テーブル ID 商品 担当者コード 1 AAAAA 3 2 BBBBB 4 3 AAAAA 4 4 CCCCC 2 5 CCCCC 3 となってしまい、ID2、3は、あたかも担当者Xが売り上げたように 変更されてしまう・・よって、こういうケースは「連鎖更新させない」 方がよいってことでしょうか。 ※実際には新規にID4でレコードを追加するかとは思いますが。 仰る通り、あくまでも整合性をとるだけにしておいて、更新/削除 については使用する場所をよくよく考えてからでないと(今の私の 知識では)危険ですね。 ありがとうございました。
補足
f_a_007さま ご回答ありがとうございます。 仰る通り、質問に書いた例が悪かったです。 ケースバイケースであること承知しました。 とりあえず、整合性はとれるように「参照整合性」の チェックは入れておいて、連鎖更新、連鎖削除については ちゃんと理解した上で設定すべきところで設定したいと 思います。 ありがとうございました。