🦾 IT-Качалка Давида Шекунца 💪
2024-06-08 09:37
Сразу уточню, я говоря про реляционную консистентность (relational constraint) и самым ярким представителем является FOREIGN KEY ... ON DELETE CASCADE
Тут много тонких и философских поинтов, но расскажу о самых насущных:
Каскады непредсказуемы
Когда ты в коде написал db.xxx.delete() используя констрейнты ты абсолютно не знаешь сколько данных в реальности потрутся. Да, можно пойти в БД и визуализировать дерево каскадов, но (1) есть большая вероятность, что код уставшего человека / код ревьюера спокойно дойдет до прода и удалит половину данных или (2) у вас достаточно много таблиц, чтобы не понимать что реально произойдет
Забыл про GC, а он про тебя не забыл
db.xxx.delete() -> каскадом удалились сотни тысяч, связанных с xxx данных -> в БД запуститься Garbage Collector -> все таблицы лочаться и все ждут пока он закончит работу -> вы в говне
Слитый перформанс
Проверка констрейнтов на INSERT и большинистве UPDATE может сжирать до 30-50% времени операции
Как быть?
. Не используйте каскады
. Если вам нужно, чтобы при удалении каких-то данных в моменте потерлись другие, то прямо там и пишите весь код удаления
. Ставьте кроны, которые в моменты низкой нагрузки системы собирают и сразу большими пачками удаляют данные, оставшиеся после удаления основной сущности
. Используйте soft-delete
. Если ну очень нужно, то делайте ON DELETE SET NULL
Из приятных сайд-эффектов, научившись жить без реляций перед вами открывается мир множества распределенных баз данных
А это неопасно?
Объявив ON DELETE CASCADE сущность, на которую мы завязываемся, становится родительской и мы от нее зависим
Одновременно с этим, есть высокая вероятность, что когда мы запрашиваем данные в нашем приложении, то запрос начинается с получения родительской сущности, а если ее нет, то и связанные данные не будут попадать в результаты запроса, а значит не будут нам мешать
Опять же, это высокая вероятность, но не гарантия, поэтому вам стоит всегда держать в голове: "Мы не используем contraint, поэтому данные, которые я запрашиваю могут быть нерелевантны, надо убедиться, что это так"
P.S.
Кстати вот эти "оставленные" данные после удаления родительских называется "orphan data" (данные-сироты)