Перед тем, как описать мою проблему, я хотел бы получить пару вещей из пути:Нормализация и исторические данные
- Я опытный (хотя и не эксперт) разработчик базы данных. Я считаю, что я хорошо разбираюсь в реляционной модели.
- У меня нет такого твердого понимания реляционной модели, что я точно знаю, что делать в любой ситуации. Я все еще учусь.
Предположим, мы получаем электронную таблицу Excel один раз в месяц из банка, но не всегда в том же банке. В электронной таблице всего шесть столбцов: название банка, номер счета, баланс счета, имя клиента (имя участника), имя пользователя SSN и адрес учетной записи. Каждая строка имеет другой номер учетной записи, и номер счета не указан более чем в одной строке. Мы хотим импортировать эту таблицу в базу данных и, в любое время в будущем, сказать: «Каким был адрес Джона Смита 13 октября 2010 года?»
Для простоты предположим, что каждый клиент имеет только один адрес и каждый клиент может иметь ноль или более учетных записей. И только на секунду, давайте притворимся, что нам нужно сделать только один лист Excel импорта КОГДА-ЛИБО, что является глупым посылкой, но нести меня. Если это так, то следующая конструкция будет достаточно:
bank
--------
id
name
account
--------
id
bank_id
customer_id
number
balance
customer
--------
id
name
ssn
address
city
state_id
zip
state
--------
id
name
Остальная часть моего вопроса основывается на том, что вы согласны, что эта схема является «правильным», так что надеюсь, вы хорошо с ним.
Теперь это было бы хорошо, если бы мы только делали импорт, но мы будем делать 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 пришел от импорта 572 на 10/13/10.» Это становится потенциально немного более неоднозначным, если вы посмотрите, скажем, на таблицу customer
. Поскольку в таблице customer
меньше строк, чем в таблице account
(поскольку некоторые клиенты имеют несколько учетных записей), у нас нет такой индивидуальной связи между клиентами и импортом, как мы делаем для учетных записей и импорта. Я знаю, что нет потери данных, и нет потери целостности данных, но она по-прежнему кажется какой-то жертвой.
Мой вопрос (и это может быть слишком открыто): Как вы думаете, это хороший способ хранения данных? Вы бы сделали это по-другому?
Редактировать: есть важные способы мышления об этих сущностях, о которых вы должны знать. Не думайте о account
как о одной учетной записи, которая существует с течением времени. Подумайте о account
как моментальный снимок учетной записи в определенный момент времени. Таким образом, счет 12345 с балансом $ 100 НЕ является тем же account
как счет 12345 с балансом $ 150. Да, обе записи привязаны к одному и тому же банковскому счету в реальном мире, но то, что я храню, является моментальным снимком учетной записи в определенный момент времени. Аналогичная (но не идентичная) ситуация с клиентами.
При последовательном импорте, как вы решите вставить или обновить адрес клиента? Тебе все равно? –
Очень хороший вопрос. Существует два способа: 1) создавать новые записи клиентов только в том случае, если что-то об изменениях клиента (например, имя или адрес) или 2) создавать новые записи клиентов каждый раз. Проблема, с которой я столкнулась, состоит в том, что я получаю дублирующиеся строки, что не так. –
Еще один важный факт: NOTHING EVER обновляется (как в инструкции UPDATE) в этой базе данных. Другими словами, мы никогда не возвращаемся и не говорим: «О, в 2008 году адрес Джона Смита был фактически X» - это никогда не случается. Когда он находится, он остается тем, чем он является. –