1

私の問題を説明する前に、いくつかのことを整理したいと思います。

  1. 私は経験豊富な (専門家ではありませんが) データベース設計者です。リレーショナル モデルについてよく理解できたと思います。
  2. 私は、あらゆる状況で何をすべきかを正確に知っているほど、リレーショナル モデルをしっかりと理解しているわけではありません。まだ勉強してる。

月に 1 回銀行から Excel スプレッドシートを受け取るとしますが、常に同じ銀行からではありません。スプレッドシートには、銀行名、口座番号、口座残高、顧客 (口座名義人) の名前、顧客の SSN、口座名義人の住所の 6 つの列しかありません。各行には異なる口座番号があり、口座番号は複数の行に記載されていません。このスプレッドシートをデータベースにインポートして、将来いつでも「2010 年 10 月 13 日のジョン スミスの住所は?」と尋ねたいと考えています。

簡単にするために、すべての顧客が 1 つのアドレスしか持たず、すべての顧客が 0 個以上のアカウントを持つことができるとしましょう。少しの間、Excel シートのインポートを 1 回だけ行う必要があると仮定しましょう。これはばかげた前提ですが、ご了承ください。その場合は、次の設計で十分です。

bank
--------
id
name

account
--------
id
bank_id
customer_id
number
balance

customer
--------
id
name
ssn
address
city
state_id
zip

state
--------
id
name

私の質問の残りの部分は、そのスキーマが「正しい」ことに同意するという前提に基づいているので、問題ないことを願っています。

インポートが 1 回だけであれば問題ありませんが、銀行ごとに年間 12 回のインポートを行うことになります。これが私がそれを会計処理する方法をどのように考えていたかです:

bank
--------
id
name

account
--------
id
import_id
bank_id
customer_id
number
balance

customer
--------
id
name
ssn
address
city
state_id
zip

state
--------
id
name

import
--------
id
date
excel_file (blob)

これで、すべてのアカウントがインポートに関連付けられ、「アカウント 12345 は 10/13/10 のインポート 572 から発生した」などのことを確実に言うことができます。customerたとえば、テーブルを見ると、もう少しあいまいになる可能性があります。customerテーブル内の行数がテーブル内よりも少ないaccountため (一部の顧客は複数のアカウントを持っているため)、アカウントとインポートの場合のように、顧客とインポートの間に 1 対 1 の関係はありません。データが失われることも、データの整合性が失われることもないことはわかっていますが、それでも何らかの犠牲を払っているように感じます。

私の質問は (これは自由すぎるかもしれません):これはデータを保存する良い方法だと思いますか? 別の方法でやったでしょうか?

編集: これらのエンティティについて、知っておくべき重要な考え方があります。account時間をかけて存在する 1 つのアカウントと考えないでください。は、ある時点でのアカウントaccountのスナップショットと考えてください。したがって、残高 $100 のアカウント 12345 は、残高 $150 のアカウント 12345 と同じではありません。はい、実世界では両方の記録が同じ銀行口座に関連付けられていますが、私が保存しているのは、ある時点での口座のスナップショットです。顧客と同様の (ただし同一ではない) 状況。account

4

6 に答える 6

1

申し訳ありませんが、「各顧客の住所は 1 つだけです」と「『2010 年 10 月 13 日のジョン スミスの住所は?』と言いたい」という記述を一致させることはできません。インポートごとに、インポートで見つかった各個人に対して新しい顧客レコードを作成することを提案していますか? その場合、アカウント番号が異なる場合、あるインポートの John Smith が別のインポートの John Smith と同じであることがどのようにわかりますか?

また、同じ顧客の同じ顧客レコードを再利用する場合 (私には正しいと思われます)、以前の住所情報はどこで確認できますか?

【投稿者コメント・修正後】

よし、あと少しだ。顧客の住所を Account テーブルに追加する必要があります (実際には AccountImports などに名前を変更する必要があります)。これは、各インポートのアドレスが異なる可能性があるためです。

アドレスがインポートからインポートまで頻繁に同じままである場合、AccountImports にアドレスを格納することは少し異常です。その場合は、CustomerAddressHistory テーブルを追加できます。各インポート中に、CustomerAddressHistory で SSN の最新の住所を確認し、インポートと同じでない場合は、新しい住所をそのテーブルの新しいレコードに追加します。

于 2010-10-13T19:39:00.897 に答える
1

使用しているDBはわかりませんが、次のとおりです。インポートを として保存しませんでした。これは、期待するファイルのタイプとしてblobを処理する必要があるため、既存のデータとリンクする能力を妨げるためです。blob他のデータと結合する前に。既に持っているIDと日付フィールドとともに、データをインポートテーブルに直接インポートします。同じ日付の重複を防ぐためkeyに、ID、次にunique compound index日付、銀行、口座を入力します。

インポートが年に 12 回しかないことが確実にわかっている場合 (月だと思いますか?)、2 つの計算フィールドを作成することで整合性を高めることができます。年のみ)、unique compound index銀行 ID、口座、date_month、および date_year を作成します。これにより、同じ月のデータが別の日付に誤って再インポートされるのを防ぐことができます。たとえば、10 月のインポートが月曜日に行われ、誰かが火曜日に再度行った場合などです。また、「ボタンをもう一度クリックしてしまった」または「今月のデータを先月のデータとしてインポートしてしまった」というシナリオも防ぐことができます。計算フィールドのチェックを高速化するには、date_month と date_year に一意のインデックスを配置します。

顧客テーブルに大騒ぎせずに常に現在の住所を反映させたい場合は、顧客アカウント (または SSN など) によってインポート テーブルを検索し、TOP 1日付で並べ替えられた住所を選択する計算フィールドを address にしますDESC。アドレス フィールドに対する、またはアドレス フィールドを含むクエリを高速化する場合は、インデックスを配置します。

于 2010-10-13T20:27:42.793 に答える
0
  1. 各インポートは特定の銀行に関連付けられているため、bank_idをインポートテーブルに配置し、アカウントテーブルから除外することを検討する場合があります。
  2. 過去の住所データを考慮したい場合で、そのデータをインポートから排他的に取得する場合は、住所フィールドをアカウントテーブルに追加し、顧客テーブルから削除することができます。確かに、複数のインポートで同じアドレスを使用している場合、そうすると重複が発生する可能性があります。それを大いに気にする場合は、別のテーブル、おそらく「address」を追加できます。おそらく、customer_idとaddress_idの複合主キーを使用します。次に、インポートテーブルにaddress_idフィールドが追加され、インポートコードでアドレスがすでに存在するかどうかを確認する必要があります。
于 2010-10-13T19:00:10.150 に答える
0

顧客の住所が 1 つしかないという考えには注意が必要です。(これは私の実生活の経験では真実ではありません)。ロードごとに顧客を更新して取得した最新の住所を保存する必要があります。または、住所を新しいテーブルに分割して顧客にリンクすることを検討する必要があります。その住所は有効だと思いました。

また、アカウントに import_id を設定しないと思います。これを行うと、顧客から銀行への接続ごとに多数の行 (x12) が得られます。あなたが望むものではないと思います。代わりに、アカウントとインポートのリンク テーブルを配置して、このアカウントがこれらのインポートの 1 つ以上にリストされていることを知らせることができます。

于 2010-10-13T19:27:22.517 に答える
0

CustomerAddressという新しいテーブルを作成し、住所情報を顧客からこの新しいテーブルに移動します。

次に、AccountテーブルとCustomerAddressテーブルに、 StartDateEndDateの 2 つの新しい列を追加 します。

こうすることで、顧客の 1 行の残業を維持し、各顧客のアカウントと住所の残業を簡単に追跡できます。顧客の複数のコピーを保持しようとすると、混乱しすぎます。

于 2010-10-13T22:59:37.710 に答える
0

一般的に、デザインは私にはよさそうです。

import/import_id 自体は、日付を保存する以外に意味がありますか? そうでない場合は、テーブルを完全に除外して、アカウント テーブルに import_date を配置してはならない理由がわかりません。

また、過去の住所情報が必要な場合は、顧客テーブルにも import_id (または import_date :) ) が必要になります。

アップデート

コメントに記載されているように、import_id を追加しても、過去の住所データは考慮されません。

必要なのは、変更される可能性のあるデータを格納し、外部キーを介して顧客テーブルにリンクする、ある種の customer_history テーブルです。

customer
------
id
first_name
last_name (assuming name wouldn't change--it certainly could)


customer_history
-----------------
id
customer_id
import_id (or date)
(address fields)

アカウントの詳細が時間の経過とともに変化する可能性がある場合は、そのための履歴テーブルも必要になります。

于 2010-10-13T19:16:45.507 に答える