Как представить текущее состояние или статус и сохранить целостность данных / ссылок?- Дизайн базы данных - PullRequest
2 голосов
/ 30 сентября 2011

У меня есть таблица для ведения определенных бизнес-транзакций, назовем ее LOANS. Каждая запись может в любой момент времени иметь одно из нескольких «состояний», например «в состоянии повторной оплаты / открытия», «по умолчанию», «аннулировано» или «оплачено».

Статус записи может измениться только из-за «события» или действия, предпринятого пользователем приложения (некоторые события не вызывают изменения состояния, например, платеж изменяет запись, но не изменяет состояние). Отслеживая текущее состояние, также важно, чтобы мы могли легко отслеживать «событие», которое переводит транзакцию в это состояние.

Я видел другие настройки баз данных, в которых LOANS содержит столбец состояния, а буква (или даже внешний ключ к таблице возможных состояний) используется для обозначения текущего состояния. Тогда в таблице EVENTS есть столбец от FK до LOANS.

Это решение работает, но я обеспокоен тем, что это допускает возможную потерю целостности данных. Другими словами, ничто не мешает установить статус «по умолчанию» без EVENT для поддержки изменения. Это было бы предоставлено исключительно приложению, чтобы гарантировать, что этого никогда не произойдет (в этом решении, на мой взгляд, нет ссылочной целостности).

Мое альтернативное решение - очистить столбец состояния в LOANS и использовать вместо него столбец lastEvent, который является FK для EVENTS. Таблица EVENTS будет поддерживать «тип» события, который, в свою очередь, будет описывать изменение состояния (например, если lastEvent имел тип «payoff», то, естественно, состояние «оплачивается»).

Мои вопросы:

  1. Должен ли я вообще беспокоиться о целостности данных (это обычное дело, потому что это нормально)?
  2. Озвучено ли предложенное мной решение или есть лучшее решение?
  3. Есть ли какие-либо подводные камни в моем решении, о которых мне следует знать?

Если это имеет значение, я использую MS SQL SERVER 2005.

Ответы [ 2 ]

1 голос
/ 30 сентября 2011
  1. Только вы знаете, каковы риски, если у вас нет ссылочной целостности здесь - но в целом, да, стоит разработать вашу базу данных, чтобы вы могли использовать ссылочную целостность. Это уменьшает количество ошибок и увеличивает вероятность того, что будущие разработчики поймут вашу схему.

  2. У меня была бы схема, аналогичная ...

    Кредиты


    Loan_Id (PK)

    сумма ....

    События


    Event_id (PK)

    Loan_ID (FK)

    Event_type_id (FK)

    Дата

    status_id (fk)

    event_type


    event_type_id (pk)

    описание

    состояние


    status_id (pk)

    описание

Чтобы узнать текущее состояние любой нагрузки, вам нужно найти самую новую запись в таблице событий для этого займа. Чтобы просмотреть историю изменений статуса ссуды, вы можете запросить таблицу событий.

Когда вы записываете события, которые не меняют статус, запись с новым событием просто содержит текущий статус события - так что вы можете получить таблицу типа:

Event_id   Loan_ID Event_type_id    Date         status_id 
 ------------------------------------------------
 1               1           NEW   1 Jan 2011   NEW
 2               1       APPROVE   2 Jan 2011   NEW
 3               1       DEFAULT   1 Feb 2011   DEF
...

Таким образом, вы всегда получите текущий статус, найдя самую последнюю запись.

Это значительно снижает риск ошибок - если ваша логика «событий» меняется, а событие меняет статус ссуды, вам нужно изменить это только в одном месте - код, который создает запись в событии база данных. Вам также не нужно помнить, чтобы также изменить запись о ссуде.

Что касается производительности - я бы оптимизировал ее только в том случае, если вам действительно нужно - в хорошо настроенной базе данных join и max не должны показывать пробки.

Вы можете уточнить модель, создав таблицу, которая отображает действительные изменения состояния и связанные с ними события; в зависимости от вашей базы данных, вы можете применить это через триггеры.

Я думаю, что это лучше, чем внешний ключ "последнего события", потому что он избыточен - по определению, последним событием является запись с МАКС (дата) для этого кредита.

0 голосов
/ 30 сентября 2011

Я думаю, что ваше беспокойство о честности оправданно. Вы указали бизнес-правило, которое гласит, что на самом деле Status не является записываемым свойством, которое оно выводит из событий.

Я бы сделал это вычисляемым столбцом на основе ваших данных о событиях.

Можно только догадываться о вашей реализации базы данных, поэтому другой альтернативой является столбец с обновленным триггером, но как тогда вы убедитесь, что он доступен только для чтения? (предположительно с блокировками / разрешениями)

...