Что по умолчанию обычно используете в ON UPDATE / ON DELETE?
Часто ли это обосновано явно ТТ или это ваш личный выбор на основе представления о модели?
Здравствуйте, vaa, Вы писали:
vaa>Что по умолчанию обычно используете в ON UPDATE / ON DELETE? vaa>Часто ли это обосновано явно ТТ или это ваш личный выбор на основе представления о модели?
On update не нужен, т.к. штатных ситуаций изменения первичного ключа не бывает.
On delete — тут два случая:
1. Речь идёт о ссылке на справочник. Тут однозначно никаких cascade, т.к. никто не ожидает при удалении какого-нибудь ненужного адреса дропнуть половину истории заказов.
2. Речь идёт о ссылке на владельца (типа ссылка на SalesOrder из OrderItem). Тут, в принципе, можно сделать и cascade, т.к. без хозяина подчинённая сущность смысла не имеет.
Но по большому счёту особого преимущества такая реализация не даёт, т.к. при реализации сценария удаления не так уж и сложно выписать предварительное удаление всех детей вручную.
Зато ручное указание даёт два важных преимущества:
— Маинтейнеру приложения не нужно гадать, какие ещё записи подвергнутся удалению. В частности, при поиске всех мест, из которых удаляются записи таблицы X, достаточно искать delete X, а не delete Y, где X транзитивно достижим из Y через on delete cascade.
— Порядок блокировок определяется не слепым случаем, а явно выписанным намерением программиста. Это означает, что у нас меньше риска, скажем, словить deadlock, когда один поток пытается добавить позицию как раз в ту корзинку, которую сейчас удаляет другой поток.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>- Маинтейнеру приложения не нужно гадать, какие ещё записи подвергнутся удалению. В частности, при поиске всех мест, из которых удаляются записи таблицы X, достаточно искать delete X, а не delete Y, где X транзитивно достижим из Y через on delete cascade.
При длинных цепочках это тоже может быть неудобно — мы удаляем Order, у него знаем о наличии Items. Однако каждый item может ссылаться на какой-то ещё дочерний объект — например, запись о таможне. Та, в свою очередь, на запись о сертификации и т.п. Без исходного item эти вещи не имеют никакого смысла, поэтому тоже надо удалять. Код распухает до неприличия.
Здравствуйте, Mr.Delphist, Вы писали:
MD>При длинных цепочках это тоже может быть неудобно — мы удаляем Order, у него знаем о наличии Items. Однако каждый item может ссылаться на какой-то ещё дочерний объект — например, запись о таможне. Та, в свою очередь, на запись о сертификации и т.п. Без исходного item эти вещи не имеют никакого смысла, поэтому тоже надо удалять. Код распухает до неприличия.
Ну, мы же это пишем не на древнем SQL, а на современном ЯВУ, предусматривающем богатые возможности декомпозиции. Поэтому код будет выглядеть вполне пристойно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, vaa, Вы писали:
vaa>Что по умолчанию обычно используете в ON UPDATE / ON DELETE?
no action (собственно он по умолчанию и используется).
vaa>Часто ли это обосновано явно ТТ или это ваш личный выбор на основе представления о модели?
Не понял вопроса. Если речь про то — использовать ли каскадное, то ответ — нет, не использовать. Слишком опасно. Лучше руками удалить явно всё, что нужно. По крайней мере я пока не встречался с ситуацией, где мне хотелось бы, чтобы база удаляла каскадно.
Вообще для меня база это такая штука, которая должна быть максимально тупой и максимум, что не-тупого от неё нужно, это следить за согласованностью данных. А вся логика должна быть в приложении.
Здравствуйте, Sinclair, Вы писали:
S>Ну, мы же это пишем не на древнем SQL, а на современном ЯВУ, предусматривающем богатые возможности декомпозиции. Поэтому код будет выглядеть вполне пристойно.
Тогда не вижу разницы — что ходить по внешним колючам и их описаниям, что ползать по размазанной по коду логике
Почему-то никто не упомянул performance.
Reference integrity checks — это не бесплатно и может заметно афектить производительность если БД сильно нагружена по вставке/изменению данных.
У меня как-то был проект, где простым отключением всех reference constraint на двух десятках таблиц удалось повысить throughput на ~20%.
Здравствуйте, RushDevion, Вы писали:
RD>Почему-то никто не упомянул performance. RD>Reference integrity checks — это не бесплатно и может заметно афектить производительность если БД сильно нагружена по вставке/изменению данных. RD>У меня как-то был проект, где простым отключением всех reference constraint на двух десятках таблиц удалось повысить throughput на ~20%.
Вопрос кандидату на должность секретарши:
— Вы и правда набираете на компьютере со скоростью 600 знаков в минуту?
— Правда. Но такая фигня получается...
Ещё оптимизаторы performance любят везде with(nolock) использовать — тоже, говорят, ускоряет.
Есть же принцип — "в БД находятся только валидные данные". Это разграничивает области ответственности и упрощает поиск дефектов.
А отключая такие проверки, мы нарушаем этот принцип, и теперь потребитель данных должен следить за их целостностью? А если их несколько, то ещё и как-то договариваться между собой? Ну и смысл использовать БД тогда? Ещё быстрее будет просто в файлах хранить записи.
XZ>Вопрос кандидату на должность секретарши:
XZ>- Вы и правда набираете на компьютере со скоростью 600 знаков в минуту?
XZ>- Правда. Но такая фигня получается...
Таки посмеялся, спасибо.
XZ>Ещё оптимизаторы performance любят везде with(nolock) использовать — тоже, говорят, ускоряет.
Для мониторинга и грубой аналитики это имеет право на жизнь.
XZ>Есть же принцип — "в БД находятся только валидные данные".
Ню-ню. Логи в базу ни разу не складывали?
А слабоструктурированные данные? Аудит какой-нибудь.
И вот не надо про ELK, NoSQL и т.п. Бывает так, что решение уже есть, оно тормозит, а времени на переписать по уму никто не даст.
И, кстати, многие NoSQL как-то обходятся без внешних ключей.
XZ>Ну и смысл использовать БД тогда? Ещё быстрее будет просто в файлах хранить записи.
И транзакционку самим обеспечивать, а индексы руками строить? Оно, может и будет быстрее, но точно не в смысле времени на разработку.
А ещё бывают append-only схемы. Взять тот же event sourcing как вырожденный вариант.
А ещё бывает OLAP-like отчёты, прилепленные к изначально OLTP базе (или к ее реплике)
В общем, я ни к тому, что нужно сейчас же пойти и прибить все внешние ключи в БД
А к тому, что пользоваться ими или нет — зависит от целей и задач.