blob: 0c41c14f1fc060c1cc85999d646cbe37d2a3badb [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
= NetBeans Eコマースのチュートリアル-データモデルの設計
:jbake-type: tutorial
:jbake-tags: tutorials
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: NetBeans Eコマースのチュートリアル-データモデルの設計 - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, NetBeans Eコマースのチュートリアル-データモデルの設計
この単元では、データモデリング、またはストレージシステムの概念モデルを作成する手順に焦点を当てています。そして、システムが必要とするエンティティとお互いの関係も識別し定義します。 データモデルには、すべての論理的および物理的な設計パラメータが含まれています。設計パラメータは、データ定義言語(DDL)がデータベースを作成するためのスクリプトを生成するのに必要とされます。^<<footnote1,[1]>>^
この単元では、主に link:http://wb.mysql.com/[+MySQL Workbench+] で仕事をします。ワークベンチは、データモデル、リバースエンジニア SQL スクリプトなどをビジュアルに作成するためのグラフィカルツールです。データモデルをforward-engineer(前方エンジニア)してデータベース構造の中に取り込み、動作中のMySQLデータベースサーバーとモデルとを同期します。
`AffableBean` アプリケーションのデータモデルを表現するためのER図(エンティティ関係図)の作成をはじめましょう。すべてのエンティティとリレーションシップを識別し、それらを結びつける関係の定義を完了している場合は、Workbench forward-engineering 前方エンジニアリングを使用して、DDL スクリプトを実行し、データモデルをデータベース構造に変換します。最後に、NetBeans IDE から新しい構造(スキーマ)に接続します。
このチュートリアルで構築するアプリケーションのライブデモを見ることができます: link:http://services.netbeans.org/AffableBean/[+NetBeansのEコマースのチュートリアルデモアプリケーション+]。
|===
|ソフトウエアまたはリソース |必須バージョン
|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |Java バンドル版, 6.8 または 6.9
|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Java Development Kit (JDK)+] |バージョン 6
|link:http://dev.mysql.com/downloads/mysql/[+MySQL データベースサーバー+] |バージョン 5.1
|link:http://dev.mysql.com/downloads/workbench/[+MySQL Workbench+] |バージョン 5.1 または 5.2
|===
*注:*
* NetBeans IDE を正常に実行するには Java開発キット( JDK )が必要です。上記の他のリソースがない場合は、最初に JDK をダウンロードしインストールする必要があります。
* NetBeans IDE Java バンドル版には、Java Web JAVA EE 技術が入っており、このチュートリアルでアプリケーションを構築するのに必要です。
* あなたは、このチュートリアルで作成したER図からMySQL Workbench が生成した完全な DDL スクリプトを以下からダウンロードすることができます: link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Faffablebean_schema_creation.sql[+affablebean_schema_creation.sql+]。
[[idEntities]]
== データモデルのエンティティを識別する
現実の世界でアプリケーションのデータモデルが貧弱な場合があります。たとえば、既存のデータベースの上にアプリケーションを開発するタスクがあったとします。アプリケーションの元となるデータモデルがないと仮定すると、開発に着手する前に最初から設計ステップを一つ一つしなければなりません。データモデルを作成するには、オブジェクトを識別するか、またはシステムが必要とする_entities エンティティ_を識別し、それらの間の関係を定義する必要があります。
我々は、データモデルに必要なエンティティを識別することから始めます。link:design.html#mockups[+アプリケーションの設計+]に示されたユースケースを再度調べる必要があります。よく出てくる名詞を調べます。たとえば:
=== ユースケース
*Customer顧客* はウェルカムページを訪問し製品*category カテゴリ*を選択する。 *Customer*は選択した製品カテゴリのページをブラウズし、彼または彼女のショッピングカートへ *products製品*を追加します。 *Customer* は、ショッピングを続け、別の *category*を選択します。 *Customer*はこのカテゴリーからいくつかの*products*を*shopping cartショッピングカート*へ追加します。*Customer*は、「カートを見る」オプションへ進み、「カート」のページでカートの*products*の数量を修正します。*Customer*はショッピングカートの内容を確認し、チェックアウトに進みます。チェックアウトのページで、*Customer*は*order注文*金額と他の情報を見ます。個人データを記入し、彼または彼女の詳細を送信します。 *order*は処理され、 *customer*は確認ページへ行きます。確認ページは顧客を追跡するための一意の参照番号を持っています。*order*の要約も同様です。
上記の*強調表示*されたテキストは、データモデルとして捉えることができる候補を示しています。より詳細に調べると、あなたがショッピングカートをデータモデルに含む必要がないと推測できるかもしれません。それゆえ、提供されるデータ(すなわち、製品とその数量)は、処理されるときには、顧客の注文と同じになります。実際に、第8単元、link:manage-sessions.html[+セッション管理+]でデモします。ショッピングカートは、単に一時的にユーザのセッションを保持するメカニズムとして機能します(顧客がオンラインでショッピングをしている間)。その結果、我々は次のリストを決めることができます。
* *customer 顧客*
* *category カテゴリ*
* *product 製品 *
* *order 注文*
これら4つのエンティティから、エンティティ関係図(ER図、以下 ERD)の構築を始められます。
*注:* このチュートリアルでは、ERD からデータベーススキーマを作成します。そして、IDE EclipseLink サポートを使い既存のデータベースから JPA エンティティクラスを生成します( EclipseLinkJava Persistence API(JPA)は、第7章でlink:entity-session.html[+エンティティクラスとセッションBeanを追加する+])で説明します)。この手法を_ボトムアップ_開発といいます。同様にこれと反対の実行可能な手法は_トップダウン_開発です。
訳者注。スキーマ(schema)とは、データベースの構造であり、データベース管理システム (DBMS) でサポートされている形式言語で記述される。関係データベースでは、スキーマは関係 (表) と関係内の属性 (フィールド) 、属性や関係の関連の定義である。
スキーマは一般にデータ辞書に格納される。スキーマはテキストによるデータベース言語のデータ定義言語 (DDL) で定義されるが、グラフィカルにデータベース構造を表したものをスキーマと呼ぶことも多い[ウィキペディア]
* *トップダウン:* _トップダウン_で開発する場合は、既存のドメインモデルの Java 実装から始めます。ドメインモデルではデータベーススキーマ設計を全く考慮する必要はありません。あなたはマッピングメタデータ(すなわち、JPA エンティティクラスで使われるアノテーション)を作成する必要があります。そして任意で、永続化ツールを使いスキーマを自動生成することもできます。
* *ボトムアップ: *_ボトムアップ_開発は既存のデータベーススキーマから始めます。ボトムアップを最も簡単に行う方法は、forward-engineering ツールを使って、スキーマからメタデータを抽出し、アノテートした Java のソースコード( JPA エンティティクラス)を生成します。
訳者注。フォワードエンジニアリング(forward engineering)とは,リバースエンジニアリングによって既存のシステムから解析された仕様をもとに,新規のシステムを開発すること。つまり、モデルからソースに変換する手法。
トップダウンとボトムアップ設計戦略の詳細については以下を参照してください。link:http://en.wikipedia.org/wiki/Data_modeling#Modeling_methodologies[+データモデリング:モデリング方法論+] [ウィキペディア]。
[[createERDiagram]]
== エンティティ関係図(ER図、ERD)の作成
MySQL Workbench(ワークベンチ)を実行してはじめます。この演習ではワークベンチを使い、`AffableBean` アプリケーションの ER 図を設計します。
*注: *以下の手順は MySQL Workbench バージョン_5.1 5.2_ で作業します。このチュートリアルの画面はバージョン5.2 のものです。 バージョン間でグラフィカルなインターフェイスにわずかな違いがあります。しかし、機能は一貫性を保っています。バージョン5.2 にはクエリエディタが組み込まれているため(以前のMySQL Query Browser)、同様にサーバー管理インターフェイス(以前の MySQL Administrator)も組み込まれているため、workbench を開くとホーム画面が表示されます(下図参照)。
[.feature]
--
image::images/workbench-home.png[role="left", link="images/workbench-home.png"]
--
Workbench 5.2で作業する場合、 ホーム画面のデータモデリング見出しの下にある「*Create New EER Model* (EERモデル新規作成)」をクリック。
* <<createSchema,`affablebean` スキーマの作成>>
* <<createEntities,エンティティの作成>>
* <<addProperties,エンティティのプロパティを追加する>>
* <<identifyRelationships,関係を識別する>>
[[createSchema]]
=== `affablebean` スキーマの作成
1. デフォルトのインターフェイスで、 AffableBean アプリケーションで使われる新しいスキーマの作成を始めます。見出しの *Physical Schemata* 見出しの右側にあるプラスアイコン( image::images/plus-icon.png[])をクリック。
新しいパネルが画面の底部に開き、新しいスキーマの設定を指示できます。
[.feature]
--
image::images/workbench.png[role="left", link="images/workbench.png"]
--
[start=2]
. 新しいスキーマ用に次の設定を入力します:
* *scheme: * `affablebean`
* *Default Collation:* `utf8 - utf8_unicode_ci`
* *Comments:* `Schema used with the AffableBean application`
image::images/affablebean-schema.png[title="Enter settings for 'affablebean' schema"]
新しいスキーマが作成され、ワークベンチ画面の右側のCatalogタブの下に一覧表示されます。
文字セットと照合順序についての説明は、MySQLサーバマニュアルを参照してください: link:http://dev.mysql.com/doc/refman/5.1/en/charset-general.html[+9.1.1. 一般的なキャラクタセットおよび照合順序+]。
[[createEntities]]
=== エンティティの作成
MySQL Workbench で新しいエンティティ関係図の作成を始めます。キャンバス上で、エンティティテーブルをドラッグアンドドロップすることができます。
1. Workbench EER 図見出しの下で、「 Add Diagram (図を追加)」(image::images/add-diagram-btn.png[])アイコンをダブルクリックします。新しい EER 図が空のキャンバスに表示されます。
[tips]#' EER ' Enhanced Entity-Relationship(拡張されたER(実体関連))の略語です)。
#
[.feature]
--
image::images/workbench-empty-canvas.png[role="left", link="images/workbench-empty-canvas.png"]
--
[start=2]
. 左余白にある New Table(新しいテーブル)(image::images/wb-new-table-icon.png[] )アイコンをクリック。キャンバス上にマウスを移動し再度クリックします。キャンバス上に新しいテーブルが表示されます。
image::images/wb-new-entity-table.png[title="Click the New Table icon to drag empty tables (entities) onto the canvas"]
[start=3]
. テーブルをダブルクリック。テーブルエディタが画面の下の方に開き、テーブルの設定を作成することができます。
*注:*「テーブル」と「エンティティ」という用語は、この単元ではほぼ同義語です。データベーススキーマの観点からすると、「テーブルを作成している」となります。データモデリングの観点からすると、「エンティティを作成している」ということなります。同様に、後の節で、エンティティ_プロパティ_に相当する各テーブルを作成します。
[start=4]
. テーブルエディタで、テーブルをユースケースから識別した一つ一つの名詞にリネームします。必要に応じてテーブルの目的をコメントに記載します。例:
* *Name:* `customer`
* *Engine:* `InnoDB`
* *Comments:* `maintains customer details(顧客の詳細を保持する)`
[.feature]
--
image::images/wb-customer-table.png[role="left", link="images/wb-customer-table.png"]
--
link:http://www.innodb.com/[+InnoDB+] エンジンは、このチュートリアルで利用する外部キーをサポートしています。後の節で、<<forwardEngineer,データベースのフォワードエンジニアリング>>を使うので、デフォルトのストレージエンジンをInnoDBに設定します(Workbenchを使って)。
[start=5]
. ワークベンチの左側にある*Catalog* タブの下(バージョン5.1の場合は右側)で、`affablebean` > `Tables` と展開します。*customer* テーブルが現れます。
image::images/wb-catalog-tab.png[title="Catalog tab automatically refreshes to display any changes to the schema"]
さらに重要なことに注意して下さい。新しい `customer` テーブルには、今、 `affablebean` スキーマが含まれています。新しく EER 図を作成した時に `affablebean` スキーマを選択したので、EER 図を変更したときはいつでも自動的にスキーマがバインドされます。
[start=6]
. <<nounList,上記のユースケースで識別した名詞>>の残り毎に、手順2から4を繰り返しキャンバスにテーブルを追加してください。しかしながら、テーブルに名前を付ける前に、考慮すべき重要な事があります。特定のキーワードは、MySQL サーバで使われる SQL 方言にとって特別な意味を持つことがあります。残念ながら、「`order`」はそのうちの1つです。 (「`order`」は、MySQL で「 `ORDER BY` 」ステートメントで使用されます)。したがって、「 `order` 」の代わりに「`customer_order`」という名前を付けます。この段階では、キャンバス上へのテーブル配置の順番はありません。
MySQLサーバーで使用される予約語のリストについては、公式マニュアルを参照してください: link:http://dev.mysql.com/doc/mysqld-version-reference/en/mysqld-version-reference-reservedwords-5-1.html[+2.2. MySQL 5.1 での予約語+]
image::images/wb-entity-tables.png[title="Create all tables for affablebean schema"]
[[addProperties]]
=== エンティティのプロパティを追加する
これでキャンバスにエンティティを追加しました、次にそのプロパティを指定する必要があります。エンティティのプロパティは、データベーステーブルの列の定義に相当します。たとえば、 `customer` エンティティを検討します。 `AffableBean` アプリケーションに関していえば、「顧客の側面の何をデータベースに永続化するのか?」。 link:design.html#checkout[+チェックアウトページ+]の顧客の詳細フォームに集まった情報のすべてがそれなのか、同様に処理済みの注文に関していくつかのものがあるのではないか。などを検討する必要があります。
プロパティを追加するときは、各プロパティに最も適切なデータ型を決定する必要があります。MySQL はいくつかのカテゴリのデータ型をいくつかサポートしています:数値型、日付と時刻型、および文字列は(文字)型。各カテゴリ別のデータ型の概要は公式マニュアルを参照してください。: link:http://dev.mysql.com/doc/refman/5.1/en/data-type-overview.html[+10.1.データ型の概要+]。 このチュートリアルでは、データ型はすでに決まっています。適切なデータ型を選択することは、データベースサーバーのストレージ最適化に重要な役割を果たしています。詳細については次を参照してください:
* link:http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html[+10.5. データ型とストレージ要件 10.5. Data Type Storage Requirements+]
* link:http://dev.mysql.com/doc/refman/5.1/en/choosing-types.html[+10.6 。列のために正しい型を選択する 10.6. Choosing the Right Type for a Column+]
ERD に存在するエンティティへプロパティを追加するためのMySQL Workbenchの使い方、を以下の手順に説明します。初期設計段階のほとんどは、エンティティのプロパティを決定することに費やされます。決定するには、解決する必要があるビジネス上の問題を慎重に検討する必要がありますし、解析にも時間を必要としますし、同様にクライアントとの数多くの協議を必要とするでしょう。
1. `customer` テーブル見出しをダブルクリックします。Workbench のテーブルエディターが立ち上がります。
[start=2]
. テーブルエディタで、Columnsタブをクリックします。表示されたテーブル内をクリックして、最初の列を編集します。以下を入力してください:
|===
|Column |Datatype |PK (Primary Key) |NN (Not Null) |UN (Unsigned) |AI (Autoincrement)
|`id` |`INT` |✓ |✓ |✓ |✓
|===
image::images/customer-id-column.png[title="Click to edit table columns in the Table editor"]
[start=3]
. 引き続き、`customer` テーブルで作業し、以下の `VARCHAR` 列を追加します。これらの列は見ればすぐわかるようにしておくべきです。 Affable Bean ビジネスが顧客の注文を処理し、お客様のアドレスに食料品の出荷を送信するためにキャプチャされる必要があるデータを表しています。
|===
|Column |Datatype |NN (Not Null)
|`name` |`VARCHAR(45)` |✓
|`email` |`VARCHAR(45)` |✓
|`phone` |`VARCHAR(45)` |✓
|`address` |`VARCHAR(45)` |✓
|`city_region` |`VARCHAR(2)` |✓
|`cc_number` |`VARCHAR(19)` |✓
|===
[tips]#`VARCHAR` データ型の説明については、MySQL リファレンスマニュアルを参照してください: link:http://dev.mysql.com/doc/refman/5.1/en/char.html[+10.4.1. CHARとVARCHAR型+]。 #
image::images/customer-varchar-columns.png[title="Edit inline to add columns to customer table"]
[start=4]
. キャンバス上で選択した `customer` テーブルで、「Arrange」>「Reset Object Size」を選び、テーブルのサイズを変更します。そうすれば、キャンバス上ですべての列が見えるようなります。インデックス行をクリックして、任意のテーブルのインデックスも表示されるようにします。(これには主キーと外部キーも含まれます。テーブル間のリレーションシップの作成をする場合に便利です。後の方で演習します)。
終了時に、`customer` エンティティ(実態)は次のように見えます。
image::images/customer-table.png[title="'customer' table on EER canvas displays columns"]
[start=5]
. 上記の手順に従って、残りのテーブル列を作成します。
==== categoryカテゴリ
|===
|Column |Datatype |PK |NN |UN |AI
|`id` |`TINYINT` |✓ |✓ |✓ |✓
|`name` |`VARCHAR(45)` |✓
|===
==== customer_order
|===
|Column |Datatype |PK |NN |UN |AI |Default
|`id` |`INT` |✓ |✓ |✓ |✓
|`amount` |`DECIMAL(6,2)` |✓
|`date_created` |`TIMESTAMP` |✓ |`CURRENT_TIMESTAMP`
|`confirmation_number` |`INT` |✓ |✓ |` `
|===
==== product製品
|===
|Column |Datatype |PK |NN |UN |AI |Default
|`id` |`INT` |✓ |✓ |✓ |✓
|`name` |`VARCHAR(45)` |✓
|`price` |`DECIMAL(5,2)` |✓
|`description` |`TINYTEXT`
|`last_update` |`TIMESTAMP` |✓ |`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`
|===
`TIMESTAMP` データ型の詳細については、MySQL リファレンスマニュアルを参照してください: link:http://dev.mysql.com/doc/refman/5.1/en/timestamp.html[+10.3.1.1. TIMESTAMP型のプロパティ+]
完了したら、キャンバスは次のようになります。
image::images/affablebean-tables.png[title="Use the Table editor to add columns to all tables on canvas"]
[[identifyRelationships]]
=== 関係の識別
ここまでで、エンティティ関係図にはいくつかのエンティティがありますが、それらの間の関係が欠けています。我々が作成しているデータモデルでは、オブジェクトが他のオブジェクトを認識(すなわち他への参照)しているかどうかを示す必要があります。1つのオブジェクトが別のオブジェクトを参照している場合は、_unidirectional 一方向_の関係として知られています 。同様に、両方のオブジェクトがお互いを参照する場合は、_bidirectional双方向_ な関係と呼ばれています。
データベーススキーマでは外部キーに関連づけて参照します。テーブルをお互いにリンクさせることを始めるときには、テーブルがリンクされていることを示すために、外部キーが新しい列として追加されることに注意しましょう。
一般に、ERDは情報の2つの他の要素を中継します: _cardinality 濃度_(つまり、multiplicity多重度)と_ordinality_ (つまり、optionality 随意選択性)。 このことについてはあとで、キャンバス上でエンティティ間の関係の追加を始めるときに説明します。ERDを完了するためには、基本的に2つ関係を作成する必要があります。一つは、_one-to-many 一対多_ の関係、もう一つは _many-to-many 多対多_の関係を作成します。詳細は以下を参照してください。
* <<oneToMany,1対多の関係を作成する>>
* <<manyToMany,多対多の関係を作成する>>
[[oneToMany]]
==== 1対多の関係を作成する
ビジネス上の問題を考慮しながら、キャンバス上の4つのオブジェクトを調べます。次の2つの _one-to-many 1対多_ の関係があることに気づきます:
* カテゴリには1つまたは複数の製品を含める必要がある
* 顧客が1つ以上の注文をすることがある
これら2つの関係をER図で組み込みます。以下のステップで必要となる4つのエンティティが入っている MySQL Workbench プロジェクトのコピーをダウンロードすることができます: link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252Faffablebean.mwb[+affablebean.mwb+]。
1. 左余白で、「1:n Non-Identifying Relationship1n 非依存関係)」( image::images/one-many-btn.png[] )ボタンをクリックします。これにより、 _one-to-many 1対多_の関係を作成することができます。
[start=2]
. `product` テーブルをクリックし、`category` テーブルをクリックします。最初にクリックしたテーブルに2番目のテーブルを参照するための外部キーが入ります。ここでは、categoryを参照することができる(`category` への参照が入った)`product` テーブルが欲しいのです。下の画像を参照してください。新しい列 `category_id` `product` テーブルに追加されています。外部キーのインデックスつまり `fk_product_category` がテーブルのインデックスに追加されています。
image::images/product-category-relationship.png[title="A one-to-many relationship is defined between the category and product objects"]
外部キーは、外部キーが参照する列と同じデータ型がである必要があります。 注。`category` テーブルの主キーと合わせるので、 `category_id` `TINYINT` 型となります。
[tips]#このチュートリアルのエンティティ関係図では、link:http://en.wikipedia.org/wiki/Entity-relationship_model#Crow.27s_Foot_Notation[+Crow's Foot クローの足+] 表記を使用しています。Workbenchで、「モデル」>「関係表記」を選択すれば表記法を変更することができます。 #
[start=3]
. relationship 関係をダブルクリック(すなわち、2つのエンティティ間の破線クリックします)。 Relationship editor関係エディタが、画面の下部領域に表示されます。
[start=4]
. 既定の見出しを`belongs to`に変更します 。言い換えれば、 「製品xは、カテゴリーyに属している」ということです。 注意してください。これは_unidirectional_ 一方向関係です。: `product` 製品オブジェクトは自分が属するカテゴリへの参照を持っているが、関連づけられた`category` カテゴリーオブジェクトは自分のカテゴリに入っている製品への参照を全く持っていないのです。
[start=5]
. リレーションシップエディタで外部キータブをクリックします。次の表示を見てください。
image::images/foreign-key-tab.png[title="Use the Foreign Key tab to modify a relationship's ordinality and cardinality"]
Foreign key(外部キー)タブで、関係を変更できます:
* *cardinality カーディナリティ: *2つのオブジェクト間の関係は _one-to-one 11_ _one-to-many 一対多_
訳者注:cardinality:カーディナリティとは値に対する種類の数のことです。濃度などと訳されます。例えば人の性別のカーディナリティは男女の2種類です。データベースの世界でのディナリティとは、エンティティ間の対応関係(「11」、「1対多」、「多対多」)のことを言います。
* *ordinality(序数): *エンティティ間の参照があろうとなかろうと、モデルの整合性を維持するために必ず ordinarity が必要となります。(「Toggle the Mandatoryトグル必須」チェックボックスでいずれかの側にします)。
* *タイプ: *(つまり、_identifying特定_) _non-identifying(非特定)_)。このような非特定関係は、以下の事実からきています。子オブジェクト(`product`製品)は、親(`category`カテゴリ) から個々に特定することができるという事実です。関係を特定するということは、子供が親なしでは一意に特定できないということを意味します。この例は後で、あなたが `product` `order` テーブルの間に多対多の関係を作成するときにデモします。
訳者注。1:n Identifying Relationship(特定関係) とは、1つのビルと複数の部屋の関係。部屋はビルの中にあるので、ビルなしには部屋は成り立たない。依存しているといってもいいかも。
1:n Non-Identifying Relationship(非特定関係) とは、1つのレンタルDVDと複数のレンタルユーザーの関係。ユーザーは別にDVDに依存しているわけではないが、1:nの関係は成り立つ。
[start=6]
. 1:n Non-Identifying Relationship1n の非識別関係) ( image::images/one-many-btn.png[] )ボタンをクリックします。次の手順で、 `customer` `customer_order` オブジェクトの間に_one-to-many_ 1対多 の関係を作成します。
[start=7]
. 最初に `order` テーブル(このテーブルには外部キーが入っています)をクリックします。次に `customer` テーブルをクリックします。これで、この2つの間に関係が作られます。
[start=8]
. 2つのテーブル間のリンクをクリックすると、関係エディタで表示されるが、既定のキャプションを「`is placed by`配置される」に変更する 。関係は、今、「顧客注文×は 顧客yに配置される」と読めます。
image::images/order-customer-relationship.png[title="A one-to-many relationship is defined between the customer and order objects"]
キャンバス上にテーブルをドラッグアンドドロップして、モデルのための最も理にかなっ所に置くことができます。上の画像では、 `order` テーブルを `customer` の左に移動しています。
[[manyToMany]]
==== 多対多の関係を作成する
_Many-to-many_多対多 の関係は、関係する双方が、関連するオブジェクトに対して多くの参照を持つことができます。たとえば、Affable Bean(愛想のいいビーン)事業は、桜のアイスクリーム、ソーセージロール、またはアボカドスフレなど、複数のカテゴリの中に表示される可能性がある製品を提供している場合を想像してください。`product` 製品 `category` カテゴリ間の _many-to-many_ 多対多の 関係を含めて、データモデルを説明する必要があります。また、カテゴリは複数の製品を含んでおり、製品は複数のカテゴリに属することができます。
データベース内で _many-to-many_多対多 の関係を実装するためには、その関係を2つの関係を _one-to-many_ 一対多 の関係にブレークダウンする必要があります 。そうするには、2つの元のテーブルの主キーが入った3番目のテーブルを作成します。先に述べた `product` - `category` の関係は以下のデータモデルのように見えるかもしれません。
image::images/many-to-many.png[title="A many-to-many relationship is depicted as two one-to-many relationships"]
今、どのようにアプリケーションが顧客の注文を保持するかを検討します。 `customer_order` エンティティはすでに必要なプロパティが含まれています。プロパティには、作成された日付、確認番号、金額、注文を発行した顧客への参照があります。 しかし、現在の所、注文にある製品の指示またその数量が全くありません。`customer_order` `product` の間に 多対多 の関係を作成することによってこの問題を解決することができます。この方法では、どの製品が与えられた注文にあるのかを決めるために、アプリケーションのビジネスロジックは、_many-to-many_ 多対多の関係から生じる新しいテーブルに問い合わせることができますし、 `order_id` に一致するすべてのレコードを検索することができます。顧客はショッピングカートに製品の数量を指定できるので、我々は`quantity` 数量の列をテーブルに追加することもできます
1. 左余白で、[n:m Identifying Relationship nm 関係の特定)](image::images/many-many-btn.png[] )ボタンを押します。これにより、あなたは _many-to-many_ 多対多 の関係を作成することができます
[start=2]
. `customer_order` テーブルをクリックし、 `product` テーブルをクリック。新しいテーブルが現れるので、`customer_order_has_product` と名前をつけます。
_identifying relationship_(関係を特定する) 」を思い出して下さい、つまり、子供は親なしに一意に識別することはできないということです。特定関係の場合は、Workbench キャンバス上の2つのテーブル間のリンクが実線で表示されます。ここでは、 `customer_order_has_product` テーブルは、2つの親テーブル(`customer_order` `product`)と特定の関係を作ります。`customer_order_has_product` テーブルに含まれているレコードは 、それが存在するために、両方のテーブルからの参照を必要とします。
[start=3]
. 下図にしたがってテーブルをアレンジします。 _many-to-many_ 多対多 の関係は以下で強調表示されています。
image::images/many-to-many-order-product.png[title="The 'customer_order_has_product' table contains two foreign keys to the order and product tables"]
新しい `customer_order_has_product` テーブルには、2つの外部キーが含まれています。 `fk_customer_order_has_product_customer_order` `fk_customer_order_has_product_product` です。それぞれ `customer_order` `product` テーブルの主キーを参照しています。これら2つの外部キーは、`customer_order_has_product` テーブルの複合主キーを形成します。
[start=4]
. 新しい `customer_order_has_product` テーブルの名前を、'`ordered_product`' に変更します。`customer_order_has_product` テーブルをダブルクリックし、テーブルエディタを開きます。[名前]フィールドに `ordered_product` と入力してください。
[start=5]
. 外部キーのインデックスを新しいテーブル名に対応した名前に変更します。「 `ordered_product`」テーブルエディターで、「Foreign Keys 外部キー」タブをクリックします。次に、両方の外部キーのエントリをクリックして、「`customer_order_has_product`」を「`ordered_product`」に変更します。完了したとき、2つのエントリを読んでください:
* `fk_*ordered_product*_customer_order`
* `fk_*ordered_product*_product`
image::images/ordered-product-foreign-key.png[title="Rename the foreign key indexes under the Foreign Keys tab in the Table editor"]
[start=6]
. 2つのオブジェクトの関の行をダブルクリックします。Relationship editor(関係エディタ)で既定のcaptions(見出し)を削除します。
[start=7]
. `ordered_product` テーブルに、`quantity` 列を作成します。これを行うには、「`ordered_product` テーブルエディタの [Columns] タブをクリックし、以下の情報を入力します。
|===
|Column |Datatype |NN (Not Null) |UN (Unsigned) |Default
|`quantity` |`SMALLINT` |✓ |✓ |`1`
|===
image::images/quantity-column.png[title="Add a 'quantity' column to the 'order_has_product' table"]
現在、 ERD(エンティティ関係図)を完了したところです。この図は `AffableBean` アプリケーションのデータモデルを表しています。後で説明しますが、あなたが作成した JPA エンティティクラスは、データモデルにあるエンティティから派生されたものです。
image::images/affablebean-erd.png[title="ERD for the AffableBean application"]
View > Toggle Grid を選び、キャンバスのグリッドを無効にします。また、左の余白にあるNew Text Object(新しいテキストオブジェクト)ボタン(image::images/text-object-btn.png[] )を使用して、図の注釈も作成することができます。
[[forwardEngineer]]
== データベースのフォワードエンジニアリング(Forward-Engineering)
MySQLデータベースにあなたが作成したデータモデルを組み込むには、Workbench で図を forward-engineering して、SQL スクリプト(より正確にいえば、DDL スクリプト)に落とし込んでスキーマを生成することができます。あなたが使用しているウィザードから、すぐにデータベースサーバー上でスクリプト(定型手続)を実行することができます。
*重要: *MySQL データベースサーバが動作していることを確認してください。データベースのセットアップおよび実行手順はここにあります。link:setup-dev-environ.html#communicate[+開発環境の設定:データベースサーバーとの接続+]。
1. Workbench で使うデフォルトのストレージエンジンにはInnoDBを設定します。 Tools > Options Mac 上で、MySQLWorkbench > Preferences )で Workbench の環境設定ウィンドウを開きます。MySQL タブをクリックし、デフォルトのストレージエンジンとして InnoDB を選択します。
image::images/inno-db.png[title="Set the default storage engine to InnoDB"]
link:http://www.innodb.com/[+InnoDB+] エンジンは、このチュートリアルで利用されている foreign key (外部キー) をサポートしています。
[start=2]
. OK」をクリックしてPreferences (設定)ウィンドウを終了します。
[start=3]
. メインメニューから、Database > Forward Engineer を選択します。
[start=4]
. [Forward Engineer to Database」ウィザードの最初のパネルで、「`DROP Objects Before Each CREATE Object`」と「 `Generate DROP SCHEMA` 」を選択します。
image::images/forward-engineer-wzd.png[title="Enable DROP options to be generated in the SQL script"]
これらの `DROP` オプションは、プロトタイプには便利なものです。もしあなたが、スキーマまたはスキーマテーブルを変更したい場合には、スクリプトは、それらを再作成する前に、最初にこれらの item を削除します(つまり、_drop_)。 (もし、既にMySQLサーバーにある item を作成しようとすると、サーバーはエラーフラグを立てます。
[start=5]
. Continue 次へ」をクリックします。Forward Engineer パネルの「 Select Objects」で「Export MySQL Table Objects」オプションがデフォルトで設定されていることに注意します。「 Show Filter 」ボタンをクリックします。 `affablebean`スキーマの中に5つのテーブル全てが含まれていることに注意してください。
[start=6]
. Continue 次へ」 をクリックします。「 Review SQL Script 」パネルで、データモデルに基づいて生成された SQL スクリプトを調べることができます。必要に応じて、「 Save to File 」をクリックして、コンピュータにスクリプトを保存します。
*注:* スクリプトを調べるには、ファイルの先頭に次の変数を設定する必要があります:
[source,java]
----
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
----
「これらの変数は何?」そして「スクリプトの中での目的は何か?」の説明については、公式の Workbench マニュアルを参照してください: link:http://dev.mysql.com/doc/workbench/en/workbench-faq.html[+第11章。 MySQL Workbench FAQ+]。
[start=7]
. Continue 」をクリックします。「 Connection Options 」パネルで、実行中のMySQLサーバに接続するためのパラメータを設定します。
* *Hostname:* `127.0.0.1` (_or `localhost`_)
* *Port:* `3306`
* *Username:* `root`
* *Password:* `nbuser`
(これから設定するパラメータは、以下の形式に対応しています。 link:setup-dev-environ.html#communicate[+開発環境の設定:データベースサーバーとの接続+])。
[start=8]
. Execute 」をクリック。ウィザードの最後のパネルで、「the wizard was able to connect to and execute the script successfully ウィザードは正常にスクリプトを実行し、接続することができた。」という確認を受けとります。
[start=9]
. Close 閉じる」をクリックして、ウィザードを終了します。
今、`affablebean` スキーマが作成され、スキーマはMySQLサーバ上にあります。次のステップでは、 IDEから、スキーマに接続、または_ データベース_へ接続します。この段階で、「スキーマとデータベースの違いは何?」と疑問を抱くかもしれません。実際に、 MySQLコマンド「 `CREATE SCHEMA` 」と「`CREATE DATABASE`」は同義語です。(link:http://dev.mysql.com/doc/refman/5.1/en/create-database.html[+12.1.10. CREATE DATABASE 構文+]を参照してください )。
スキーマをデータベースの内容を定義する設計図だと考えてください。データベースの内容には、テーブル、リレーションシップ、ビューなどがあります。データベースはスキーマ構造に合わせた方法でデータを格納します。これは、Javaクラスやオブジェクトのオブジェクト指向の世界に似ています。クラスはオブジェクトを定義します。しかしプログラムが走るとオブジェクト(つまり、クラスのインスタンス)が作成され、管理され、最後には、プログラムが破棄を実行してオブジェクトは破棄されます。
[[connectDB]]
== IDE からデータベースへの接続
今、`affablebean` スキーマが MySQL サーバ にあります。IDE の「 ServicesServices 」ウィンドウから ERD で作成したテーブルが表示できることを確認します。
*重要: * link:setup-dev-environ.html#communicate[+開発環境:データベースサーバーとの通信設定+]、に概説されている手順を理解しておいてください。ここの見出しには、MySQL データベースサーバの実行方法、IDE への登録方法、データベースインスタンスの作成方法が説明してあります。そして、 IDE からインスタンスへの接続を作成する方法が説明してあります。
1. IDE で、「 Services サービス」ウィンドウを開き( Ctrl-5 。⌘-5 Macの場合)、データベース接続ノード(image::images/db-connection-node.png[] )へマウスを置きます。link:setup-dev-environ.html#communicate[+前の単元+]で作成した `affablebean` データベースインスタンスの場所です。
[start=2]
. `affablebean` データベースへの接続をリフレッシュします。そのために、接続ノードを右クリックし Refresh リフレッシュを選択します。
[start=3]
. 任意のテーブルノードを展開します。現在、スキーマで定義済みの5つのテーブルを見ることができます。
[start=4]
. 任意のテーブルノードを展開します。各テーブルには MySQL ワークベンチの作業で作成した列とインデックスがそこに含まれています。
image::images/services-window-schema.png[title="Update the database connection to view schema tables"]
IDE は今 `AffableBean` アプリケーション用に作成したスキーマを使用して、データベースに接続されています。 IDE から、今あなたがデータベースに作成したテーブルのデータをどれでも見ることができます。同様に、直接、データの変更、追加、削除ができます。データベースにサンプルデータを追加した後で、 link:connect-db.html[+アプリケーションをデータベースに接続する+]の中でこれらのオプションのいくつかを探索します。
link:/about/contact_form.html?to=3&subject=Feedback: NetBeans E-commerce Tutorial - Designing the Data Model[+ご意見をお寄せ下さい+]
[[seeAlso]]
== 参照
=== NetBeans リソース
* link:../../../articles/mysql.html[+MySQL NetBeans IDE+]
* link:../../ide/mysql_ja.html[+MySQL データベースへの接続 +]
* link:../../web/mysql-webapp_ja.html[+MySQL データベースを使用した単純な Web アプリケーションの作成+]
* link:../../ide/database-improvements-screencast.html[+スクリーンキャスト:NetBeans 6.5 でのデータベースサポートの改善+]
=== MySQL とデータモデリング リソース
* link:http://wb.mysql.com/[+MySQL Workbench ブログ+]
* link:http://forums.mysql.com/index.php?151[+MySQL Workbench フォーラム+]
* link:http://dev.mysql.com/librarian/[+MySQL コミュニティ ライブラリー+]
* link:http://dev.mysql.com/doc/workbench/en/index.html[+MySQL Workbench リファレンスマニュアル+]
* link:http://dev.mysql.com/doc/refman/5.1/en/[+MySQL 5.1 リファレンスマニュアル+]
* link:http://en.wikipedia.org/wiki/Innodb[+InnoDB+] [Wikipedia]
* link:http://en.wikipedia.org/wiki/Database_model[+データベースモデル+] [Wikipedia]
* link:http://en.wikipedia.org/wiki/Data_modeling[+データモデリング+] [Wikipedia]
== 引用文献
1. <<1,^>> データ定義言語(DDL)は、SQL 言語のサブセットであり、 `CREATE TABLE` `DROP`、および `ALTER` のようなステートメントを含んでいます。その他のサブセットには、データ操作言語(DML 、およびデータ制御言語(DCL)も含まれています。詳細については、以下を参照してください。link:http://en.wikipedia.org/wiki/Data_Definition_Language[+Data Definition Language データ定義言語+] [Wikipedia]。