вести историю в базе данных - PullRequest
7 голосов
/ 11 апреля 2009

Я проектирую эту базу данных, которая должна вести историю заработной платы сотрудников и перемещений внутри организации. По сути, в моем дизайне 3 таблицы (я имею в виду, что таблиц больше, но для этого вопроса я упомяну 3, так что потерпите меня). Таблица сотрудников (содержит самую последнюю зарплату, данные о должности и т. Д.), Таблицу SalaryHistory (зарплата, дата, причина и т. Д.) И MovementHistory (заголовок, отдел, комментарии). Я буду использовать Linq to Sql, поэтому я думал, что при каждом обновлении данных о сотрудниках старые значения будут копироваться в соответствующие таблицы истории. Это хороший подход? Должен ли я сделать это, используя Linq to SQL или триггеры? Спасибо за любую помощь, предложение или идею.

Ответы [ 5 ]

8 голосов
/ 11 апреля 2009

Взгляните на http://www.simple -talk.com / sql / администрация базы данных / архитектура базы данных на определенный момент времени .

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

* DateCreated – the actual date on which the given row was inserted.
* DateEffective – the date on which the given row became effective.
* DateEnd – the date on which the given row ceased to be effective.
* DateReplaced – the date on which the given row was replaced by another row.
* OperatorCode – the unique identifier of the person (or system) that created the row. 

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

6 голосов
/ 11 апреля 2009

Хорошая идея - хранить эту логику внутри базы данных: именно поэтому существуют триггеры. Я говорю это осторожно, однако, поскольку есть много причин, чтобы держать это внешним. Часто - особенно с такой простой технологией, как LINQ-to-SQL - легче писать код извне. По моему опыту, больше людей могли бы написать эту логику в C # / LINQ, чем могли бы сделать это правильно, используя триггер.

Триггеры быстрые - они скомпилированы! Тем не менее, ими очень легко злоупотреблять, и они делают вашу логику слишком сложной, чтобы производительность могла быстро ухудшаться. Учитывая, насколько прост ваш вариант использования, Я бы предпочел использовать триггеры , но это я лично.

2 голосов
/ 11 апреля 2009

Я думаю, это относится к базе данных по двум причинам.

Во-первых, промежуточные уровни приходят и уходят, но базы данных вечны. В этом году Java EJBs, в следующем году .NET, через год что-то еще. Данные остаются, по моему опыту.

Во-вторых, если база данных является общей, ей не нужно полагаться на каждое приложение, которое использует ее, чтобы знать, как поддерживать целостность данных. Я бы посчитал это примером инкапсуляции базы данных. Зачем навязывать знания и вести историю каждому клиенту?

2 голосов
/ 11 апреля 2009

Триггеры, скорее всего, будут быстрее, и для их выполнения не требуется «посредник», исключающий хотя бы один шанс на ошибки.

В зависимости от выбранной вами базы данных, вы можете просто использовать одну таблицу и включить для нее OID, а также добавить еще два столбца, «flag» и «previous». Никогда не обновляйте эту таблицу, только вставьте. Добавьте триггер так, чтобы при добавлении строки для employee #id, для всех записей с employee #id был установлен флаг «old», а для новых строк «предыдущие» значения устанавливались в предыдущую строку.

1 голос
/ 11 апреля 2009

Триггеры облегчают переход вашего интерфейса на что-то другое, и они будут поддерживать согласованность базы данных независимо от того, как данные вставляются / обновляются / удаляются.

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

...