Про отказ от foreign keys на уровне базы
Слушая доклады и обсуждения книг по архитектуре, я все чаще встречаю концепцию, что база должна быть «глупая», то есть являться просто хранилищем данных. Вся логика должна быть на бэкенде. Понятно, что вряд ли кто-то сейчас пишет в новых проектах хранимые процедуры, но к логике в БД относятся не только они. На заре карьеры разработчиком я сталкивалась с большим проектом с хранимыми процедурами и триггерами. Было непривычно писать, тяжело искать баги и отлаживать.
Кстати, помню пост на Хабре, как в 2020 ЛингваЛео переписали на хранимые процедуры в PostgreSQL существенную часть бэкенда. Эта история вызвала бурное обсуждение. Большинство коллег не считали это решение правильным (проблемы с масштабированием, отладкой и др). ЛингваЛео перестали вести блог на Хабре, поэтому не знаю, как у них дела.
Люди, которых я считаю авторитетами в архитектуре, говорят о том, что вообще отказываются от foreign keys, реализуя необходимые проверки в коде. На практике я не сталкивалась с отказом от внешних ключей, но задумалась, в каких случаях это может быть оказаться полезно. Вот что придумала:
➖когда у нас много операций вставки, то наличие foreign key может замедлять их, так как базе нужно проверять их
➖когда мы собираемся шардировать базу, потому что foreign keys не могут поддерживаться между разными шардами.
Например, у нас есть таблица товаров и таблица брендов. У каждого товара есть ссылка на бренд. Если мы будем шардировать базу и разнесем товары на разные шарды по хэшу от их идентификатора, то товары одного бренда уедут на разные шарды, и ключ не будет работать. Нужно будет переносить все товары одного бренда вместе. А таких связок у товаров может быть много, не только с брендами. В результате и без того сложная задача шардирования станет совсем неподъёмной.
➖ когда мы собираемся разделять базу, например, переходим от монолита к микросервисам или делим какой-то микросервис на два (с таким я сталкивалась).
Продолжая пример с таблицами товаров и брендов. Бренды остаются тут, а товары уезжают в другой микросервис. Теоретически можно забрать бренды вместе с товарами, но:
- это не всегда соответствует логике разделения
- если у нас много связок, то станет проблемой распутать этот клубок
Идея отказа от foreign key может показаться радикальной. Но современная концепция база — это хранилище, не нужно писать код с расчетом на логику в базе мне кажется здравой и полезной.
Сталкивались ли вы с логикой в базе? Что думаете по поводу отказа от foreign keys на уровне базы? Как реализовано у вас на проекте?
Post #43
2K
- 👍 15
- ❤🔥 3
- ❤ 3
- 🔥 1