Я обычно проектирую свои базы данных по следующим правилам:
- Никто кроме db_owner и sysadmin не имеет доступа к таблицам базы данных.
- Роли пользователей контролируются на уровне приложений. Я обычно использую одну роль БД для предоставления доступа к представлениям, хранимым процедурам и функциям, но в некоторых случаях я добавляю второе правило для защиты некоторых хранимых процедур.
- Я использую TRIGGERS для первоначальной проверки критической информации.
CREATE TRIGGER <TriggerName>
ON <MyTable>
[BEFORE | AFTER] INSERT
AS
IF EXISTS (SELECT 1
FROM inserted
WHERE Field1 <> <some_initial_value>
OR Field2 <> <other_initial_value>)
BEGIN
UPDATE MyTable
SET Field1 = <some_initial_value>,
Field2 = <other_initial_value>
...
END
- DML выполняется с использованием хранимых процедур:
sp_MyTable_Insert(@Field1, @Field2, @Field3, ...);
sp_MyTable_Delete(@Key1, @Key2, ...);
sp_MyTable_Update(@Key1, @Key2, @Field3, ...);
Считаете ли вы, что в этом случае стоит использовать DEFAULT CONSTRAINTs, или я добавляю дополнительную и ненужную работу на сервер БД?
Обновить
Я понимаю, что с помощью ограничения DEFAULT я даю больше информации кому-то еще, кто должен управлять базой данных. Но я в основном заинтересован в производительности.
Я предполагаю, что база данных всегда проверяет значения по умолчанию, даже если я предоставляю правильное значение, поэтому я делаю одну и ту же работу дважды.
Например, есть ли способ избежать ограничения DEFAULT при выполнении триггера?
sql-server
иtsql
поскольку код в вашем вопросе очень специфичен для этой СУБДОтветы:
Хм, с чего ты это взял? ;-). Учитывая, что существуют значения по умолчанию для предоставления значения, когда столбец, к которому они присоединены, отсутствует в
INSERT
выражении, я бы предположил прямо противоположное: они полностью игнорируются, если вINSERT
выражении присутствует соответствующий столбец .К счастью, никому из нас не нужно ничего предполагать из-за этого утверждения в вопросе:
Вопросы о производительности почти всегда можно проверить. Поэтому нам просто нужно подготовить тест, чтобы SQL Server (настоящий авторитет здесь) мог ответить на этот вопрос.
НАСТРОИТЬ
Запустите следующее один раз:
Выполните тесты 1A и 1B индивидуально, а не вместе, так как это искажает время. Запустите каждый из них несколько раз, чтобы получить представление о среднем времени для каждого из них.
Тест 1А
Тест 1Б
Выполните тесты 2A и 2B по отдельности, а не вместе, так как это искажает время. Запустите каждый из них несколько раз, чтобы получить представление о среднем времени для каждого из них.
Тест 2А
Тест 2В
Вы должны увидеть, что нет реальной разницы во времени между тестами 1A и 1B или между тестами 2A и 2B. Так что нет, нет снижения производительности, чтобы иметь
DEFAULT
определенный, но не использованный.Кроме того, помимо простого документирования предполагаемого поведения, вам необходимо помнить, что в основном вы заботитесь о том, чтобы DML-выражения полностью содержались в ваших хранимых процедурах. Поддержка людей не волнует. Будущие разработчики могут не знать о вашем желании инкапсулировать все DML в эти хранимые процедуры или не беспокоиться, даже если они это знают. А тому, кто поддерживает эту БД после вашего ухода (другой проект или задание), может быть наплевать, или он не сможет предотвратить использование ORM, независимо от того, сколько он протестует. Таким образом, значения по умолчанию могут помочь в том, что они дают людям «аут» при выполнении
INSERT
, особенно ad-hocINSERT
сделанном представителем службы поддержки, поскольку это один столбец, который им не нужно включать (именно поэтому я всегда использую значения по умолчанию при аудите столбцы даты).И мне просто пришло в голову, что довольно объективно можно показать, проверяется или нет
DEFAULT
флажок, когда вINSERT
выражении присутствует связанный столбец : просто укажите недопустимое значение. Следующий тест делает именно это:Как видите, если указан столбец (и значение, а не ключевое слово
DEFAULT
), значение по умолчанию игнорируется на 100%. Мы знаем это, потому что этоINSERT
удается. Но если используется значение по умолчанию, возникает ошибка, поскольку он в конечном итоге выполняется.Хотя необходимость избегать ограничений по умолчанию (по крайней мере, в этом контексте) совершенно не нужна, для полноты можно отметить, что можно было бы «избежать» ограничений по умолчанию только внутри
INSTEAD OF
триггера, но не внутриAFTER
триггера. Согласно документации для CREATE TRIGGER :Конечно, используя
INSTEAD OF
триггера потребует:AFTER
триггера, который включает ограничениеОднако я бы точно не рекомендовал это делать.
источник
CURRENT_TIMESTAMP
столбцов datetime. Таким образом, «простой» тест с использованием недопустимого выражения там не сработает (и недопустимое значение не может быть использовано,CREATE TABLE
поскольку он проверен), и у меня нет времени на создание теста производительности. Но я подозреваю, что большинство РСУБД будут относиться к ним одинаково.Я не вижу существенного вреда в наличии ограничений по умолчанию. На самом деле, я вижу одно конкретное преимущество - вы определили значение по умолчанию на том же уровне логики, что и само определение таблицы. Если у вас есть значение по умолчанию, которое вы предоставляете в своей хранимой процедуре, кто-то должен пойти туда, чтобы узнать, каково значение по умолчанию; и это не то, что было бы очевидно для кого-то новичка в системе, обязательно (если, например, вы унаследуете миллиард долларов завтра, купите свой собственный тропический остров, выйдете и переедете туда, оставив какой-то другой бедный сок, чтобы понять вещи) самостоятельно).
источник