5
CREATE TABLE Phone
(
phoneID - PK
.
.
.
);

CREATE TABLE PhoneDetail
(
phoneDetailID - PK
phoneID - FK points to Phone
phoneTypeID ...
phoneNumber ...
.
.
.
);

CREATE TABLE Customer
(
customerID - PK
firstName
phoneID - Unique FK points to Phone
.
.
.
);

顧客は、Cell、Workなどの複数の電話番号を持つことができます。CustomerテーブルのphoneIDは一意であり、PhoneテーブルのPhoneIDを指します。顧客レコードが削除された場合は、電話テーブルのphoneIDも削除する必要があります。

私のデザインについて何か心配はありますか?これは適切に設計されていますか?私の問題は、CustomerテーブルのphoneIDが子であり、子レコードが削除された場合、親(Phone)レコードを自動的に削除できないことです。

4

2 に答える 2

12

あなたはそれを過剰に設計したと思います。別のPhone+PhoneDetailテーブルは使用できません。通常、2つの実用的なアプローチがあります。

1)シンプルさ-すべての電話を顧客レコード自体に入れます。はい、それは正規化ルールに違反しますが、実際には非常に単純であり、通常、提供する限り(職場、自宅、モバイル、ファックス、緊急)機能します。利点は、コードが単に書くことであり、実装までの時間が短くなることです。顧客レコードを持つすべての電話を取得するのは簡単で、特定のタイプの電話(Customer.Fax)を使用しています。

欠点:後で電話の種類を追加するのは少し面倒で、電話番号の検索は厄介です。SQLのように書く必要があります"select * from customer where cell = ? or home = ? or work = ? or emergency = ?"。事前に設計を評価します。これらの問題のいずれかが懸念事項である場合、またはそれが懸念事項であるかどうかわからない場合は、正規化されたアプローチを使用してください。

2)拡張性-あなたが行くルートに行きます。電話タイプは後で追加できます。DDLは変更されません。顧客->顧客電話

Customer (
   customerId
)

CustomerPhone (
   customerId references Customer(customerId)
   phoneType references PhoneTypes(phoneTypeId)
   phoneNumber
)

PhoneTypes (
   phoneTypeId   (H, W, M, F, etc.)
   phoneTypeDescription
)
于 2010-04-08T01:47:48.143 に答える
1

mrjoltcolaはすでに正規化に取り組んでいるので、電話に記録があり、電話の詳細に記録がないという問題に取り組みます。

それがあなたの唯一の問題である場合、3つのアプローチがあります:

1)詳細テーブルからではなく、CASCADE DELETEを使用して電話から削除します-単一のSQLステートメントを使用して2つのテーブルから削除し、データの一貫性を維持します

2)親の最後のレコードが子から削除されたときに親を自動的に削除するトリガーを詳細テーブルに設定します(これはうまく機能せず、テーブルのすべての削除が遅くなります。それでも醜いです。それでも可能です。それをするために)

3)アプリケーションのビジネスロジックレイヤーで実行します-このレイヤーが適切に分離されていて、ユーザー(アプリケーション)がこのレイヤーを介してのみデータを変更する場合は、必要なレベルの整合性保証に到達する可能性があります

于 2010-04-08T10:26:58.853 に答える