21

すべてCustomerに物理アドレスとオプションの郵送先住所があります。これをモデル化するためのあなたの好ましい方法は何ですか?

オプション1.Customerへの外部キーがありますAddress

   顧客(id、phys_address_id、mail_address_id)
   住所(ID、通り、都市など)

オプション2Customerは、と1対多の関係にAddressあり、アドレスタイプを説明するフィールドが含まれています

   顧客ID)
   住所(id、customer_id、address_type、street、cityなど)

オプション3。アドレス情報は非正規化され、に保存されます。Customer

   顧客(id、phys_street、phys_cityなど。mail_street、mail_cityなど)

私の最優先の目標の1つは、オブジェクトリレーショナルマッピングを単純化することなので、最初のアプローチに傾倒しています。あなたの考えは何ですか?

4

12 に答える 12

11

私は、正規化のすべての通常の理由から、最初のアプローチを好む傾向があります。また、このアプローチにより、メールの詳細に対するデータ クレンジングの実行が容易になります。

複数のアドレス (メール、自宅など) を許可する可能性がある場合、または発効日を使用できるようにする場合は、このアプローチを検討してください。

   顧客 (id、phys_address_id)
   Cust_address_type (cust_id、mail_address_id、address_type、start_date、end_date)
   住所 (ID、番地、都市など)
于 2009-03-15T20:28:26.570 に答える
7

(問題のドメインに応じて) 考慮する必要がある重要な事実の 1 つは、人々がアドレスを変更し、アドレスの変更を事前に知らせたい場合があることです。これは公益事業会社、通信会社などに当てはまります。

この場合、住所を事前に設定し、正しい時点で自動的に切り替えることができるように、顧客の複数の住所を有効日付とともに保存する方法が必要です。これが要件である場合、(2) のバリエーションがそれをモデル化するための唯一の賢明な方法です。

Customer (id, ...)
Address (id, customer_id, address_type, valid_from, valid_to)

一方、これに対応する必要がない場合 (そして将来的にはそうしないと確信している場合) は、おそらく (1) の方が管理が簡単です。問題がないため、データの整合性を維持するのがはるかに簡単だからです。同じタイプのアドレスが 1 つだけ存在することを保証し、結合は 1 つのフィールドにのみ存在するため単純になります。

したがって、引っ越しが必要かどうかによって、(1) または (2) のどちらでもかまいませんが、(3) は避けたいと思います。住所の外観を変更する場合は、複数の列を追加する必要があります。パフォーマンスが若干向上する可能性がありますが、正直なところ、リレーショナル データベースで適切にインデックスが作成された結合を処理する場合、得られるものは多くなく、アドレスが必要ないシナリオでは速度が低下する可能性があります。顧客のレコード サイズが大きくなるためです。

于 2009-03-15T21:35:59.233 に答える
6

次のようなモデルを進めています。

Person (id, given_name, family_name, title, suffix, birth_date)
Address (id, culture_id, line1, line2, city, state, zipCode, province, postalCode)
AddressType (id, descriptiveName)
PersonAddress (person_id, address_id, addressType_id, activeDates)

ほとんどの人はこれを過剰だと考えるかもしれません。しかし、私たちが開発するアプリに共通する否定できないテーマは、人、組織、住所、電話番号などの基本的なエンティティをいくつか持ち、それらをさまざまな方法で組み合わせたいということです。そのため、ユースケースがあることを 100% 確信している一般化を事前に構築しています。

Address テーブルは、カルチャに基づいてアドレスを区別するために、階層ごとのテーブル継承スキームに従います。したがって、米国の住所には州と郵便番号のフィールドがありますが、カナダの住所には州と郵便番号があります。

人に住所を「与える」ために、別の接続テーブルを使用します。これにより、他のエンティティ (個人と住所) が他のエンティティとのつながりから解放されます。また、Address エンティティを他の多くの種類のエンティティ (People、Organizations など) に接続したり、リンクに関連付けられたさまざまなコンテキスト情報 (私の例の activeDates など) に接続したりすることがはるかに簡単になります。

于 2009-12-22T18:32:06.867 に答える
4

2番目のオプションは、おそらく私が行く方法です。また、万が一、ユーザーが追加の住所を追加できるようにすることもできます (あなたがそうしたい場合)。

于 2009-03-15T20:20:00.273 に答える
3

私は#1を好むでしょう。適切な正規化と明確な意図の伝達。このモデルでは、同じアドレス オブジェクト (行) を両方のアドレスに使用することもできます。これは、非常に価値のあることです。この情報を複製しすぎると、簡単に迷子になります。

于 2009-03-15T20:23:11.403 に答える
3

この種の質問に答えるとき、私はDDDの分類を使用するのが好きです。エンティティの場合は別の ID を持つ必要がありますが、値オブジェクトの場合はそうではありません。

于 2009-03-15T21:36:55.550 に答える
2

現在私が書いているほとんどのコードでは、すべての顧客が 1 つの物理的な場所しか持っていません。これは、当社のビジネスパートナーである法人です。したがって、通り、都市などを顧客オブジェクト/テーブルに入れます。多くの場合、これは機能する最も単純な方法であり、機能します。

追加の郵送先住所が必要な場合は、顧客オブジェクトが煩雑にならないように、別のオブジェクト/テーブルに入れます。

私のキャリアの早い段階で、配送先住所を参照する顧客を参照する注文を狂ったように正常化しました。これにより、物事は「きれい」になりましたが、使用するのが遅く、洗練されていませんでした。現在、すべての住所情報を含む注文オブジェクトを使用しています。顧客は自分の(デフォルトの?)住所を変更する可能性があるため、実際にはこれはより自然なことだと思いますが、2008 年に顧客が引っ越したとしても、2007 年に発送された出荷の住所は常に同じままである必要があります。

現在、VerySimpleAddressProtocol in out プロジェクトを実装して、使用されるフィールドを標準化しています。

于 2009-03-15T22:47:03.710 に答える
2

オプション 3 は制限が厳しすぎるため、スキーマを変更せずにオプション 1 を拡張して他のアドレス タイプを許可することはできません。オプション 2 は明らかに最も柔軟性が高いため、最良の選択です。

于 2009-03-15T21:04:12.600 に答える
1

私は最初のオプションを選びます。このような状況では、私は YAGNI に非常にうんざりしています (あなたは YAGNI を必要としません)。何年も前の「念のため」の 1 対多のテーブルを持つスキーマを見た回数は数え切れません。2 つだけ必要な場合は、最初のオプションを使用してください。要件が将来変更された場合は、その時点で変更してください。

于 2009-03-15T20:25:38.277 に答える
1

多くの場合と同様に、状況によります。

顧客が複数のアドレスを扱う場合は、対多の関係が適切です。住所が発送用または請求書用などであるかどうかを示すフラグを住所に導入できます。または、さまざまな住所タイプをさまざまなテーブルに保存し、顧客に複数の対 1 関係を持たせることもできます。

顧客の住所を 1 つだけ知る必要がある場合、なぜそれを対多にモデル化するのでしょうか? ここでは、対 1 の関係がニーズを満たします。

重要: 非正規化は、パフォーマンスの問題が発生した場合にのみ行ってください。

于 2009-03-15T20:56:14.447 に答える
1

オプション 1 を使用します。必要に応じて、アドレス履歴を保持するために少し変更することもできます。

Customer   (id, phys_address_id, mail_address_id)
Address    (id, customer_id, start_dt, end_dt, street, city, etc.)

住所が変更された場合は、現在の住所の日付を終了して、Addressテーブルに新しいレコードを追加します。phys_address_idandはmail_address_id常に現在のアドレスを指します。

そうすれば、アドレスの履歴を保持でき、データベースに複数の郵送先住所を保存できます (デフォルトは ですmail_address_id)。実際の住所と郵送先住所が同一の場合は、同じレコードを指すだけphys_address_idですmail_address_id

于 2009-03-15T21:19:49.303 に答える