Триггеры против хранимой процедуры против встроенного SQL в DAL для обновления таблиц в базе данных с историей - PullRequest
2 голосов
/ 03 февраля 2011

Скажите, если у меня есть база данных с таблицами истории:

[SomeTable]

SomeColumn1
SomeColumn2
UpdatedDTM
UpdatedUserID
IsObselete

[SomeTableHistory]

SomeColumn1
SomeColumn2
UpdatedDTM
UpdatedUserID
AuditedDTM

Когда обновляется строка в SomeTableдолжно произойти следующее:

  • Строка в SomeTable требует вставки в SomeTableHistory.
  • Строка в SomeTable нуждается в обновлении с новыми значениями.
  • ОбновленоDTMВ столбце SomeTable необходимо установить текущее время.

Сначала я подумал о том, чтобы использовать хранимые процедуры:

add_sometable_entry(SomeColumn1, SomeColumn2, UserID)
update_sometable_entry(ID, SomeColumn1, SomeColumn2, UserID)
expire_sometable_entry(ID, UserID)

Затем я подумал: а не использовать ли триггеры вместо этого, разрешивобычные вызовы sql «вставлять в sometable» и «обновлять sometable» для работы с SomeTable и с автоматически работающими механизмами истории.

Или, конечно, есть возможность просто встроить sql, чтобы сделать это для каждой таблицы историив DAL.

В настоящее время я склоняюсь к хранимым процедурам, поэтому могу поддерживать DAL в чистоте, а также разрешаю только вставлять / обновлять / удалять доступ к данным.основываться на хранимых процедурах, которые помогут помешать дистрибьюторам / покупателям «поиграть» и напрямую манипулировать столами.

Что думают люди об этом?

Я используюPostgreSQL (хотя это не имеет никакого отношения, не так ли? ..)

Ответы [ 4 ]

3 голосов
/ 04 февраля 2011

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

Триггеры на это не способны.

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

Единственное обстоятельство, при котором стоит учитывать триггеры, - это когда у вас не-SQL, например, нет транзакций и нетсохраненные процы (если он был одина не другой, я бы все равно нормализовал сегменты кода).При таких обстоятельствах, конечно, разверните код для ведения исторических таблиц в триггерах, а остальные в другом месте.

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

  • Существует отдельное требование, чтобы DAL не предпринимал недопустимых действий, которые тратят ресурсы сервера;и поэтому он должен проверить или проверить каждое действие, прежде чем пытаться его выполнить.Это не «дублирование» такого кода проверки, который может существовать в верхней части каждой транзакции;это экономит время взаимодействия с пользователем и ресурсы сервера.
1 голос
/ 03 февраля 2011

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

Можно утверждать, что хранимые процедуры будут лучше.

Но если вы собираетесь писать «код», вы можете утверждать, что (а не в SP) гораздо приятнее помещать код в DAL, где легче получить контроль версий, модульное тестирование, отладку и т. Д. .

Наконец, если вы посмотрите, что «все обновления (someentity) должны быть записаны как (someentityhistory)» как бизнес-правило (так называемое доменное правило), то вы можете утверждать, что на уровне бизнес-логики (он же логика домена) слой) у вас должен быть код, который реализует это правило. Так что это переместит код выше DAL в бизнес-уровень. (чтобы он имел дело с объектными объектами, а не с SQL).

Следует учитывать один фактор: если кто-то импортирует данные или выполняет массовое обновление данных, собираются ли они сделать это через бизнес-уровень (через API или что-то еще) или с прямым доступом к базе данных? Если это прямой доступ к базе данных, и вы все еще хотите, чтобы это правило сработало, то это может быть аргументом для триггеров.

В итоге: вы могли бы поспорить.

0 голосов
/ 03 февраля 2011

Для хранения истории может быть полезно дополнение tablelog .http://pgfoundry.org/projects/tablelog/

0 голосов
/ 03 февраля 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...