У меня есть требование разработать систему. Часть системы состоит в том, что каждый день рассчитывается плата за человека (человеку присваивается $ x.xx в день на основе некоторых правил) и сохраняется в таблице транзакций, которая в настоящий момент состоит из personId, сумма и дата.Настольная конструкция для эффективности
CREATE TABLE DailyTransaction
(
DailyTransaction INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
PersonId INT NOT NULL,
TransactionDate DATE NOT NULL
)
Есть 8000 людей в системе прямо сейчас, так что каждый день, 8000 строк записываются с помощью процесса к столу.
Думаю, хранение даты, повторение слишком много. И могут быть запросы на эту дату позже. Итак, я бы хотел создать таблицу «DailyRun», которая содержит дату, а также идентификатор (и больше столбцов позже, если необходимо). Итак, когда я делаю ежедневную платежную вставку для заполнения 8000 строк, я сначала создаю запись DailyRun с датой, а затем присваиваю этот идентификатор для этой строки таблице транзакций.
CREATE TABLE DailyRun
(
DailyRunId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
RunDate DATE NOT NULL
)
CREATE TABLE DailyTransaction
(
DailyTransaction INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
PersonId INT NOT NULL,
DailyRunId INT NOT NULL
)
Так что, если я хотел, чтобы все строки на определенную дату, я считаю дату в таблице DailyRun, а затем получить все записи, связанные с ней, с помощью внешнего ключа, в таблице транзакций.
Это кажется хорошо до сих пор (если кто-то не видит проблему?)
НО, теперь вопрос.
Другое требование заключается в том, что в течение дня в таблицу транзакций можно добавить специальный платеж. Итак, дополнительный разовый платеж. Но он не создается как Run. Таким образом, ни одна строка в таблице DailyRun. Идея - это унифицированный идентификатор DailyRun в таблице Transaction, но ... когда мне нужно получить все транзакции на определенную дату - ну, нет поля даты ... и теперь RunID установлен .. так что это не будет найденный.
Что я могу сделать, это разрешить Null RunID, а также поле с нулевым значением «AdHocPaymentDate». Итак, если это Adhoc-платеж, я могу оставить RunID null и заполнить AdHocPaymentDate?
И если это запланированный платеж, я заполняю RunID и оставляю AdHocPaymentDate равным нулю?
Но, не являются ли поля, допустимые для нитевидности, медленными или не рекомендуется по какой-либо причине?
Есть ли лучший способ справиться с этим? Может быть, отдельная таблица «Ad Hock Payment», которая содержит специальные платежи, в дополнение к таблице, которая содержит регулярные ежедневные платежи?
«Я думаю, что хранение даты повторяется слишком много» - это, наверное, плохое предположение. Для «даты» требуется 3 байта для хранения («datetime» требует 8, 'datetime2' между 6 и 8 байтами) - по сравнению с накладными расходами на создание новой таблицы, эффективно индексируя ее и помещая FK на место? И, как и в случае с любым вопросом производительности, единственный способ узнать это - попробовать все * свои * данные в * вашей * среде. Слишком редко работает удаленная настройка производительности с помощью хаков и чувств. –
Спасибо Damien. Дополнительная таблица также может содержать дополнительные данные, которые я бы нашел полезными, например, обработанный флаг состояния (был ли этот запуск обработан и отправлен платеж по форме?). Но я согласен - если у него просто дата - это может быть не полезно. – Craig
Даже если вам нужно будет хранить много дополнительной информации в таблице DailyRun позже, то для эффективности запросов я бы дублировал TransactionDate в таблице DailyTransaction (используя ваш первый проект). В наших устаревших структурах данных есть несколько таблиц (строк документов), глобальная PITA запрашивает строки и заголовок ссылки только для получения даты оттуда. – Arvo