If you see this, you must use any unsupported web browser. Or constructing the page.
この表示が見えている場合、描画処理中です。しばらくお待ちください。 長時間見えている場合は、非対応ブラウザで参照しています。

INTER-Mediator Lab. - Room 1

8. 関連レコードの展開

1対多の展開とリレーションシップ

前のページの例では、2つのテーブルを利用しましたが、2つ目のconnectionテーブルは、あるフィールドに入力する値を記録するものであり、その中の1つが選択されれるという関係でしたが、さらに複雑な関係がある場合について説明をします。

まず、住所録のaddressテーブルとして以下のようなものがあったとします。ここでの例は、con_idは利用しません。

idpnametelcon_id
1山田一郎0123-456-98761
2風下寒子0123-456-98763
3屋根裏夫0123-456-98761

addressテーブルが顧客を記録していて、営業部員が顧客に対するコンタクト内容を以下のようなcontactテーブルで記録していたとします。idフィールドが主キーになりますが、address_idには該当する顧客に関して、addressテーブルのその顧客のレコードのidフィールド値を記録します。たとえば、以下のid=2のテーブルは、address_idの値が「3」なので、「屋根裏夫」さんに関して、9月14日にメールで展示会の案内をしたということを記録していることになります。

idaddress_iddtmemo
122013-9-12 10:00電話したが不在
232013-9-14 14:00メールで展示会の案内をした
322013-9-15 17:00電話で展示会の案内をした
412013-9-16 13:00訪問して商品説明した

この2つのテーブルで、顧客ごとに、コンタクト情報を一覧するようなページを作るとします。定義ファイルは以下のような記述となります。ここで新たにrelationというキーワードが登場します。

name: address
key: id
-
name: contact
key: id
relation: [foreign-key: address_id, join-field: id, operator: =]

このrelationキーの値は、複数の項目からなっており、[ ] でその1つの項目を記述することにします。

ここで、 addressという名前のコンテキストがページファイル内で利用されるようなターゲット指定があるとします。このとき、addressテーブルからデータを取り出すのですが、階層関係にある上位のリピータに関して、join-fieldで指定したidフィールドの値を取り出し、addressテーブルでforeign-keyに指定したaddress_idの値とイコールなレコードだけに絞り込みます。この動作は実際のデータを考えた方が分かりやすいので、この後で動作を見ながらが説明します。

ページファイルについては、次のようなものを作成したとします。前のページの例との違いは、外側のテーブルの3列目に、さらにテーブルがあって、そこにcontactテーブルの内容が展開されるという点です。

<table>
    <thead>
        <tr><th>名前</th><th>電話番号</th><th>分類</th></tr>
    </thead>
    <tbody>
        <tr>
            <td class="IM[address@pname]"></td>
            <td class="IM[address@tel]"></td>
            <td>
                <table>
                    <thead>
                        <tr><th>日時</th><th>連絡内容</th></tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td class="IM[contact@dt]"></td>
                            <td class="IM[contact@memo]"></td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
</table>

上記のページを実際に作ったサンプルは、「実験環境(別ウインドウに表示)」に用意してあります。実験環境のページのsample8.html/phpをご覧ください。

実際にテーブルが作られる様子を、手順を追って説明します。ページ上に存在するテーブル部分を示します。

  1. BODY要素から探索されて、外側のTBODYとTRが、addressコンテキストを使用するエンクロージャー/リピーターとして識別されます。
    名前電話番号連絡内容
      
    日時連絡内容
       
  2. エンクロージャーからリピーターを取り除き、外側のテーブルのボディ部分がない状態になります。
    名前電話番号連絡内容
  3. addressテーブルにアクセスして、データを取り出します。
  4. 最初のid=1のレコードがあるので、リピーターを複製し、エンクロージャーの子要素に追加します。
    名前電話番号連絡内容
      
    日時連絡内容
       
  5. レコードの中にあるデータが、フィールドに応じてリピーター内部のaddressコンテキストのターゲット指定のある要素内に合成されます。つまり、最初のtdに「山田一郎」、次のtdに「0123-456-9876」という文字列データが埋め込まれます。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
       
  6. リピータ内部を探索すると、新たに3列目にさらにエンクロージャー/リピーターとなるTBODY/TRタグ要素が見つかります。ここでもリピーターを一度削除してエンクロージャの中身を空にします。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
  7. 現在作業中のリピーターはcontactコンテキストを使用する事が中身を解析する事で判別できます。
  8. contactコンテキストの定義に従ってcontactテーブルにアクセスします。このとき、relationキーの指定があるので、まず、その中のjoin-fieldを参照し「id」というフィールド名となっています。そこで、上位のリピーターについて、手順5で得ているようにidの値は「1」です。この値をforeign-keyに指定したaddress_idに持つレコードだけを取り出します。operatorは=なので、つまりは、contactテーブルを取り出すときに、address_id=1のレコードだけを取り出します。
  9. contactテーブルから、id=4の1つのレコードだけが取り出されました。
  10. 手順5で切り出したリピーターを複製し、contactテーブルから得られたデータを合成します。ここではテーブルのTBODYに1行分のTRタグ要素が追加され、1列目には「2013-9-16 13:00」、2列目には「訪問して商品説明した」という文字が追加されます。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
    2013-9-16 13:00 訪問して商品説明した
  11. 内側のコンテキストによる展開はこれでいったん終了します。また、外側のリピーターに関してはエンクロージャー/リピータのセットは1つだけですので、これで最初のレコードに関する合成が終わります。
  12. 外側のコンテキストは、2つ目のレコード、つまりid=2のレコードの展開を行います。
  13. 外側のリピーターの複製を作り、エンクロージャーの子要素に追加します。そして、id=2のレコードのフィールドをリンクノードに合成します。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
    2013-9-16 13:00 訪問して商品説明した
    風下寒子0123-456-9876
    日時連絡内容
       
  14. 内部を探索すると手順6と同様に、エンクロージャーとリピーターのセットが存在します。リピーターを取り除きます。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
    2013-9-16 13:00 訪問して商品説明した
    風下寒子0123-456-9876
    日時連絡内容
  15. 手順8と同様に、ここではid=2のaddressテーブルのレコードが上位のリピーター内に展開されているので、contactテーブルに対してaddress_id=2となるレコードに絞り込んでレコードを取り出します。
  16. id=1とid=3の2つのレコードが取り出されました。
  17. contactテーブルのid=1のレコードについて、手順14で取り出したリピーターを複製してレコード内のデータを合成して、エンクロージャーに追加します。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
    2013-9-16 13:00 訪問して商品説明した
    風下寒子0123-456-9876
    日時連絡内容
    2013-9-12 10:00 電話したが不在
  18. contactテーブルのid=3のレコードについて、手順14で取り出したリピーターを複製してレコード内のデータを合成して、エンクロージャーに追加します。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
    2013-9-16 13:00 訪問して商品説明した
    風下寒子0123-456-9876
    日時連絡内容
    2013-9-12 10:00 電話したが不在
    2013-9-15 17:00 電話で展示会の案内をした
  19. 内側のコンテキストの展開はこれで終了し、addressテーブルのid=2に対する展開は終了しました。
  20. addressテーブルのid=3に対する展開も同様に行います。
    名前電話番号連絡内容
    山田一郎0123-456-9876
    日時連絡内容
    2013-9-16 13:00 訪問して商品説明した
    風下寒子0123-456-9876
    日時連絡内容
    2013-9-12 10:00 電話したが不在
    2013-9-15 17:00 電話で展示会の案内をした
    屋根裏夫0123-456-9876
    日時連絡内容
    2013-9-14 14:00 メールで展示会の案内をした

学習時間調査

ログインユーザ:|

読み終わったとき、以下のラジオボタンのいずれかを選択して、「読み終わった」ボタンをクリックしてください。

開いてから今まで、このページを、

ほとんどの時間は読む事に使わなかった
あまり時間をかけて読んではいなかった
他のことと半々くらいの時間をかけて読んだ
多くの時間をかけて読んだ
ほとんどの時間を読む事に使った

このページの内容について、自分が感じる理解度は、

ほとんど分からなかった
少しは分かったが半分以下しか分からなかった
半々くらい
すべては理解できないが半分以上は理解した
ほとんど理解できた

←クリックすると、次のページに移動します。

実験のトップページ(Room 1)へ