Внешние ключи: предпочтения
От: vaa  
Дата: 30.12.21 06:47
Оценка:
Что по умолчанию обычно используете в ON UPDATE / ON DELETE?
Часто ли это обосновано явно ТТ или это ваш личный выбор на основе представления о модели?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Внешние ключи: предпочтения
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.12.21 08:54
Оценка: 24 (3) +3
Здравствуйте, 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, когда один поток пытается добавить позицию как раз в ту корзинку, которую сейчас удаляет другой поток.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Внешние ключи: предпочтения
От: Mr.Delphist  
Дата: 30.12.21 09:34
Оценка: 6 (1)
Здравствуйте, Sinclair, Вы писали:

S>- Маинтейнеру приложения не нужно гадать, какие ещё записи подвергнутся удалению. В частности, при поиске всех мест, из которых удаляются записи таблицы X, достаточно искать delete X, а не delete Y, где X транзитивно достижим из Y через on delete cascade.


При длинных цепочках это тоже может быть неудобно — мы удаляем Order, у него знаем о наличии Items. Однако каждый item может ссылаться на какой-то ещё дочерний объект — например, запись о таможне. Та, в свою очередь, на запись о сертификации и т.п. Без исходного item эти вещи не имеют никакого смысла, поэтому тоже надо удалять. Код распухает до неприличия.
Re[3]: Внешние ключи: предпочтения
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.12.21 10:10
Оценка: +1
Здравствуйте, Mr.Delphist, Вы писали:

MD>При длинных цепочках это тоже может быть неудобно — мы удаляем Order, у него знаем о наличии Items. Однако каждый item может ссылаться на какой-то ещё дочерний объект — например, запись о таможне. Та, в свою очередь, на запись о сертификации и т.п. Без исходного item эти вещи не имеют никакого смысла, поэтому тоже надо удалять. Код распухает до неприличия.

Ну, мы же это пишем не на древнем SQL, а на современном ЯВУ, предусматривающем богатые возможности декомпозиции. Поэтому код будет выглядеть вполне пристойно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Внешние ключи: предпочтения
От: vsb Казахстан  
Дата: 30.12.21 12:16
Оценка: +2
Здравствуйте, vaa, Вы писали:

vaa>Что по умолчанию обычно используете в ON UPDATE / ON DELETE?


no action (собственно он по умолчанию и используется).

vaa>Часто ли это обосновано явно ТТ или это ваш личный выбор на основе представления о модели?


Не понял вопроса. Если речь про то — использовать ли каскадное, то ответ — нет, не использовать. Слишком опасно. Лучше руками удалить явно всё, что нужно. По крайней мере я пока не встречался с ситуацией, где мне хотелось бы, чтобы база удаляла каскадно.

Вообще для меня база это такая штука, которая должна быть максимально тупой и максимум, что не-тупого от неё нужно, это следить за согласованностью данных. А вся логика должна быть в приложении.
Re[4]: Внешние ключи: предпочтения
От: Mr.Delphist  
Дата: 30.12.21 14:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ну, мы же это пишем не на древнем SQL, а на современном ЯВУ, предусматривающем богатые возможности декомпозиции. Поэтому код будет выглядеть вполне пристойно.


Тогда не вижу разницы — что ходить по внешним колючам и их описаниям, что ползать по размазанной по коду логике
Re: Внешние ключи: предпочтения
От: RushDevion Россия  
Дата: 30.12.21 15:43
Оценка: 9 (2)
Почему-то никто не упомянул performance.
Reference integrity checks — это не бесплатно и может заметно афектить производительность если БД сильно нагружена по вставке/изменению данных.
У меня как-то был проект, где простым отключением всех reference constraint на двух десятках таблиц удалось повысить throughput на ~20%.
Re[2]: Внешние ключи: предпочтения
От: Xander Zerge Россия www.zerge.com
Дата: 30.12.21 20:10
Оценка: +2
Здравствуйте, RushDevion, Вы писали:

RD>Почему-то никто не упомянул performance.

RD>Reference integrity checks — это не бесплатно и может заметно афектить производительность если БД сильно нагружена по вставке/изменению данных.
RD>У меня как-то был проект, где простым отключением всех reference constraint на двух десятках таблиц удалось повысить throughput на ~20%.

Вопрос кандидату на должность секретарши:
— Вы и правда набираете на компьютере со скоростью 600 знаков в минуту?
— Правда. Но такая фигня получается...

Ещё оптимизаторы performance любят везде with(nolock) использовать — тоже, говорят, ускоряет.

Есть же принцип — "в БД находятся только валидные данные". Это разграничивает области ответственности и упрощает поиск дефектов.
А отключая такие проверки, мы нарушаем этот принцип, и теперь потребитель данных должен следить за их целостностью? А если их несколько, то ещё и как-то договариваться между собой? Ну и смысл использовать БД тогда? Ещё быстрее будет просто в файлах хранить записи.
Серёжа Новиков,
программист
Re[3]: Внешние ключи: предпочтения
От: RushDevion Россия  
Дата: 30.12.21 21:02
Оценка:
XZ>

XZ>Вопрос кандидату на должность секретарши:
XZ>- Вы и правда набираете на компьютере со скоростью 600 знаков в минуту?
XZ>- Правда. Но такая фигня получается...

Таки посмеялся, спасибо.

XZ>Ещё оптимизаторы performance любят везде with(nolock) использовать — тоже, говорят, ускоряет.

Для мониторинга и грубой аналитики это имеет право на жизнь.

XZ>Есть же принцип — "в БД находятся только валидные данные".

Ню-ню. Логи в базу ни разу не складывали?
А слабоструктурированные данные? Аудит какой-нибудь.
И вот не надо про ELK, NoSQL и т.п. Бывает так, что решение уже есть, оно тормозит, а времени на переписать по уму никто не даст.
И, кстати, многие NoSQL как-то обходятся без внешних ключей.

XZ>Ну и смысл использовать БД тогда? Ещё быстрее будет просто в файлах хранить записи.

И транзакционку самим обеспечивать, а индексы руками строить? Оно, может и будет быстрее, но точно не в смысле времени на разработку.

А ещё бывают append-only схемы. Взять тот же event sourcing как вырожденный вариант.

А ещё бывает OLAP-like отчёты, прилепленные к изначально OLTP базе (или к ее реплике)

В общем, я ни к тому, что нужно сейчас же пойти и прибить все внешние ключи в БД
А к тому, что пользоваться ими или нет — зависит от целей и задач.
Отредактировано 30.01.2022 19:05 RushDevion . Предыдущая версия . Еще …
Отредактировано 30.12.2021 21:51 RushDevion . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.