Всем привет! В этой коротенькой статье я попытаюсь вам доказать, что, скорее всего, вам никогда не нужны внешние ключи (foreign keys) в СУБД.

TLDR

Гарантии внешних ключей (FK) не нужны при корректной архитектуре. При этом FK не бесплатны, БД постоянно проверяет, что родительские ключи существуют.

Что такое FK?

В ВУЗах на парах по базам данных студентам обязательно (наверно?) рассказывают про внешний ключ (далее также Foreign Key, FK). Рассказывают как-то так:

"Внешний ключ (foreign key) — это столбец или группа столбцов в одной таблице, значения которых ссылаются на первичный ключ другой таблицы. Это позволяет установить связь между двумя таблицами".

О цитате

Более корректное определение таково:

Внешний ключ (foreign key) — это столбец или группа столбцов в одной таблице (дочерней), который ссылается на первичный ключ или другую уникальную комбинацию столбцов в другой таблице (родительской). Это ключевой элемент реляционных баз данных для установления связи между таблицами и поддержания целостности данных, гарантируя, что значение в дочерней таблице существует в родительской

Я умышленно убрал часть определения, потому что большинство запоминают именно обрезанную версию :)

Что значит "установить связь", к сожалению, никто не понимает. В реальности же FK это гарантия валидности родительского ключа. Давайте разберем на примере. Скажем, мы разрабатываем интернет магазин с табличками user и order:

CREATE TABLE user(  
  id UUID PRIMARY KEY,  
  status TEXT NOT NULL,    
  
  balance BIGINT NOT NULL,  
  phone TEXT NOT NULL,  
  email TEXT NOT NULL  
  -- И другие поля
);

CREATE TABLE order(  
  id UUID PRIMARY KEY,  
  status TEXT NOT NULL,    
  
  user_id UUID NOT NULL,  
  amount BIGINT NOT NULL  
  -- И другие поля
);

Юный студент может захотеть для order добавить внешний ключ

FOREIGN KEY (user_id) REFERENCES user(id)

Что будет если добавить FK? Тогда при изменениях order и user будет проверяться, что order.user_id ссылается на существующий user.id. Иными словами FK гарантирует, что родительский ключ существует.

-- Операции, на которых FK может выдать ошибку
UPDATE user SET id = ?;
DELETE user;

INSERT INTO order; 
UPDATE order SET user_id = ?; 

Еще одна фича FK — on delete cascade - позволяет при удалении, например, user, сразу удалить все связанные order.
При этом делать join можно как с FK, так и без них. Внешние ключи в принципе никак не влияют на джойны и связи между таблицами

Так чем же мешают FK?

TLDR: они бесполезны.

По какой-то невиданной для меня причине, при изучении СУБД в университетах, всегда опускается клиент-серверная разработка, хотя она напрямую связана с проектированием СУБД. Из-за этого складывается ощущение, что FK — обязательная вещь в реальном проекте, хотя все наоборот — те гарантии, что дает FK, разработчик сам должен поддержать на стороне бэкенда. Иными словами — FK не дает дополнительных гарантий.

Давайте вернемся к нашему примеру с user и order и докажем, что при правильном ��роектировании бэкенда у нас не может быть нарушений консистентности.

Иммутабельность ID

Начнем с того, что у любой сущности ID должен быть иммутабельным. Не должно быть такого, что user поменял айдишник. (да и не понятно зачем и как это вообще возможно)

Таким образом иммутабельность айдишника гарантирует, что update на user никогда не сломает order.user_id.

UPDATE user SET id = ? -- невозможная операция 

Soft delete

FK могут помочь нам защититься от операций удаления из таблицы user, которые приведут к невалидным ссылкам в order. Но стоит ли вообще удалять данные из user?
Правильно, не нужно. Зачастую вместо delete используется подход, под названием soft delete. Например, вместо того, чтобы удалять юзера из БД, мы просто поменяем ему статус:

UPDATE user SET status = 'DELETED' WHERE id = ?

Это дает нам очень много преимуществ:

  • Если кто-то случайно удалил не то — информацию мы не теряем, юзеров можно восстановить

  • Проще отлаживать, потому что, опять же, мы не теряем информацию

  • Это может быть требование бизнес логики. Например, мы не хотим терять информацию о том, когда юзер был создан, даже если он удалится.

Не могу утверждать, что этот подход является общеприменимым, но я пока что ни разу не встречал больших проектов, которые используют какие-то иные подходы. Таким образом мы избавляемся от еще одной ситуации, когда FK может быть полезен — удаление юзера.

DELETE user; -- Не возможно, потому что мы не удаляем юзеров 

Валидация на бекенде

У нас остается только 2 операции, в которых FK может выдать ошибку:

INSERT INTO order;
UPDATE order;

Например, мы создаем заказ, а юзера с указанным ID не существует. Но может ли такое произойти? Конечно нет.
Например, если запрос на создание заказа отправляется на бэкенд самим пользователем, то мы получаем его айдишник из авторизации, из JWT токенов. Как мы обсуждали ранее - айдишники иммутабельны, поэтому мы можем не бояться, что пользователь удалится, либо поменяет айди.

arch

Аналогично с обновлением заказа, хотя тут проще - не понятно как создатель заказа может поменяться. А даже если и может - проверка валидности user_id все равно должна находиться на стороне бэкенда.

Итог

В правильно сп��оектированном бэкенде не будет ситуации, когда FK может триггернуться и выдать ошибку. Таким образом FK не дают нам каких-либо преимуществ. При этом важно не забывать, что FK - не бесплатные, они чуть-чуть, но нагружают СУБД.

-- Операции, на которых FK может выдать ошибку
UPDATE user SET id = ?; -- Не возможно из-за иммутабельности ID 
DELETE user; -- Не удаляем юзеров 

INSERT INTO order; -- В любом случае проверяем на бекенде user_id 
UPDATE order SET user_id = ?; -- user_id не может поменяться

Стоит ли после прочтения этой статьи бежать и удалять FK из всех таблиц с прода? Нет конечно, скорее всего вы не заметите разницы в перформансе.

В принципе эта статья скорее не про то "как надо и не надо делать", а так, пофлудить :)

Для душнил

Ниже описаны ответы на вопросы, которые у вас могут возникнуть при прочтении статьи

В смысле мы данные не удаляем?

А как же ФЗ-152?

По законам о персональных данных мы должны удалять персональные данные пользователей, например, по их просьбе. Но мы не обязаны удалять все данные, только персональные. В нашем случае достаточно занулить телефон и почту:

UPDATE user SET phone = null, email = null WHERE id = ?;

Мы же не будем удалять заказы, чеки, платежи и так далее -_-.

А как же архивирование?

Что делать, если наша БД разрослась, и нам нужно удалить, например, старые платежи или хотя бы куда-то их перенести.
Скажем, есть таблица payment:

CREATE TABLE "payment"(  
  id UUID PRIMARY KEY,  
  status TEXT NOT NULL,    
  
  order_id UUID NOT NULL  -- И другие поля
);

Мы хотим заархивировать заказы и платежи

Архивация?

Под архивацией имеется ввиду перенос в более медленное либо холодное хранилище, например, из Postgres в Clickhouse

Нуууу....
Тогда нам точно не нужны FK? Наша реализация с soft-delete и отсутствием FK никак не помешает архивации, а FK, как и всегда, не дадут нам каких-либо преимуществ.

Что если кто-то зайдет в БД?

Если ваши джуны постоянно шастают по продакшен БД — я вам сочувствую. Но в таком случае даже лучше если не будет FK, потому что лучше джун удалит 1 запись из user, а не 1 запись из user и все связанные из order :)

В идеальном мире права на запись в продакшене должны быть у тимлида/девопса, а на удаление — ни у кого. Но даже имея FK можно накосячить с айдишниками, например, заменить один валидный order.user_id на другой, тоже валидный.

P.S.

Как подмечают в комментариях — FK может помочь защититься от ошибок со стороны неправильно работающего бэкенда, скриптов и тд.

С вами я скорее соглашусь. Да, FK не панацея, но его можно использовать как дополнительную защиту от ошибок.

Комментарии (36)


  1. ionicman
    28.10.2025 12:19

    И индексы тоже не нужны! Да и БД! Даешь просто текстовые файлы!!! )))

    Конечно нужны - это единственное, что бережет консистентность ваших данных в БД, а как известно из законов Мерфи - если что-то может случиться - это случиться.

    Джуны/кот/комета/шальной скрипт/не сработавшая тразакция - на страже всего этого стоят эти ключи, чтобы случайно и далеко не обязательно, что напрямую через шастанье в БД не превратить ваши данные в желе.


    1. TeaDove Автор
      28.10.2025 12:19

      В статье говорится, что ситуация, когда FK сработает — невозможна, либо около невозможна, а валидация в первую очередь должна быть на стороне бэкенда, а не БД.

      FK от шального скрипта никак не защищают, вы все также можете проставить неправильный айдишник, просто он должен существовать. Либо вообще удалить данные

      Защищаться от неправильных скриптов нужно через ограничение прав, а не FK

      P.S. индексы, очевидно, нужны


      1. ionicman
        28.10.2025 12:19

        Это просто еще одна ступень защиты (как и ограничение прав), естественно, а не серебрянная пуля, вы предлагаете ее отключить.

        А часто бывает, что скрипт при разработке что-то делает, и права там не мешают.

        Ну и есть еще плюшки от FK, например удаление цепочек.


        1. TeaDove Автор
          28.10.2025 12:19

          Да, согласен.
          Как доп. защиту FK можно использовать.


      1. norguhtar
        28.10.2025 12:19

        Мне больше всего нравится в статье то что у вас с базой работает один backend. А по факту вообще говоря СУБД проектировались для конкурентного доступа и более того в СУБД может лазить далеко не один и тот же софт. По этому уповать на корректность архитектуры одного backend фикция. То что сейчас чаще всего это не используется. А из-за микросервисной архитектуры СУБД упрощается до максимум десяти таблиц, ну извините это никак не отменяет использование FK


  1. dmitrijtest24
    28.10.2025 12:19

    Вам не нужны внешние ключи

    Так нужны или нет? Если вот не нужны, то покажите как вы с интернет магазином то решили вопрос.


    1. TeaDove Автор
      28.10.2025 12:19

      FK не необходимы, их можно использовать, но если вы правильно проектирует бэкенд, то FK не дадут вам каких-либо преимуществ.

      В правильно спроектированном бэкенде не будет ситуации, когда FK может триггернуться и выдать ошибку. Таким образом FK не дают нам каких-либо преимуществ.

      С интернет-магазином все просто — в архитектуру заложена гарантия валидности связанных таблиц


      1. thescarletarrow
        28.10.2025 12:19

        А что будет гарантировать консистенцию данных? Только поверить на слово бэкенду? И почему сразу тут юзеров использовать? Кроме них не существует случаев, когда нужны FK? А при удалении данных пользователя зачем удалять самого пользователя? Удалите всю информацию о нём из его таблицы


  1. Conung_ViC
    28.10.2025 12:19

    Так и вижу, что мне приходит заказ с каким-то непонятным юзер_айди, или любым другим ФК, и я сначала пытаюсь найти в базе эту энтити по ФК, чтоб понять, существует ли она, и только потом сохраняю....

    Т.е. вместо 1 запроса к бд, - сколько? пять? десять? а если таких полей у заказа штук 20?


    1. TeaDove Автор
      28.10.2025 12:19

      Так вам в любом случае нужно сходить в БД, чтобы проверить, что юзер авторизован и имеет право сделать заказ

      Если вы никак не верифицируете айдишники в системе, то злоумышленик может просто насоздавать заказов на чужих юзеров?
      Вам же так и так нужно верифицировать, что инпут в систему корректен


      1. Conung_ViC
        28.10.2025 12:19

        у заказа помимо юзера может быть еще 100500 связей.


        1. TeaDove Автор
          28.10.2025 12:19

          Да, безусловно, и их тоже нужно валидировать если вы не доверяете источнику!

          Например, у заказа может быть shop_id и delivery_id. Если юзер отправляет запрос вида `POST /order {"shopId": ..., "deliveryId": ..., "cartItems": []}` вам же все равно нужно сходить в БД и проверить, что такой shop существует, что он может принимать заказы, что в нем есть указанные товары.

          Вставить в БДшку поля без проверки можно только в случае, если мы доверяем отправителю, например, в приватной апишке между сервисами.


          1. Creeperasha
            28.10.2025 12:19

            По умолчанию проверками существования при вставке как раз FK и будут заниматься — если магазина нет, будет ошибка. Вы же предлагаете все такие проверки делать вручную — т. е. написать перед INSERT столько SELECT, сколько у таблицы есть связей. Это как усложняет код на бэкенде, так и требует больше времени из-за большего количества запросов. А если мы добавим связь — теперь нам везде нужно прописать ещё по одному SELECT.

            Вам не кажется, что цена проверки FK при вставке на стороне БД гораздо ниже, чем проверка, фактически, тех же FK на стороне бэкендов?


        1. gazkom
          28.10.2025 12:19

          Очень интересно как вы в таком случае будете на вызывающей стороне обрабатывать foreign key constraint error.


  1. tsbt
    28.10.2025 12:19

    Отвратительный пример про персональные данные как ни посмотри. Равно как и тема ненужности FK.

    Про бред по теме FK в комментариях уже вам прояснили, а на тему ПД будет пояснени ниже.

    Если вы персональные данные планируете периодически удалять - то эта логика должна быть изначально реализована в вашем решении или доработки должны без проблем это позволять сделать не в смысле возможности удаления, а чтобы все остальное не сломать и не городить производные костыли по смежной причине.

    А если вы это реализовали и теперь прекрасно обходиться можете без ПД, то правильный вопрос - а зачем тогда вы их собираете, если и без них все хорошо?

    То есть реально ПД нужны исключительно тогда и в тех решениях, когда их не требуется удалять даже при наличии запроса от физического лица. Все остальное - это избыточные запросы ПД для ваших теневых маневров или от недостатка понимания как можно сделать иначе.

    Если вы после удаления ПД позднее сможете однозначно определить какое лицо соответствует остаточным сущностям в вашей БД - значит у вас в модели данных есть поля, которые позволяют связать некоторое физическое лицо с какими-то объектами в вашей БД и фактически вы не смогли обезличить данные корректным образом.


    1. TeaDove Автор
      28.10.2025 12:19

      То есть реально ПД нужны исключительно тогда и в тех решениях, когда их не требуется удалять даже при наличии запроса от физического лица.

      Раскройте, пожалуйста, мысль не понял...

      Если мы говорим про воображаемый интернет-магазин, то ПД нужны для авторизации (телефон) и отправки чека (почта).

      После удаления аккаунта юзера, очевидно, эти ПД нам больше и не нужны, потому что юзер не будет авторизовываться и ему не будут отправляться чеки об покупках.

      В БД останется только его айдишник, по нему не получится связать его с реальным человеком


  1. LeshaRB
    28.10.2025 12:19

    3 года назад была статья
    Мягкое удаление чаще всего не нужно
    https://habr.com/ru/articles/677932/

    Зачастую вместо delete используется подход, под названием soft delete
    Там тоже есть минусы


    1. TeaDove Автор
      28.10.2025 12:19

      Крутая статья!

      У меня получилось что-то наоборот:)

      В комментариях автору, как мне кажется, корректно ответили, что не всегда мягкое удаление не нужно и его аргументы можно обойти.


  1. plustilino
    28.10.2025 12:19

    Допустим, есть таблица статей и таблица дат, когда статьи менялись. В таблице дат внешний ключ - id статей. Такая структура БД нужна, чтобы можно было создавать виды для просмотра дат изменений конкретной(ых) статьи(ей). Как разработать БД иначе, чтобы не было FK, при условии, что надо хранить все даты изменений каждой статьи?

    В статье акцент: как отсутствие FK уменьшает вероятность ошибок. Но у FK есть другие задачи.


    1. TeaDove Автор
      28.10.2025 12:19

      Сама БДшка будет буквально такой же, что и при FK, просто без FK.

      Разница будет только на стороне бекенда и только на операции удаления. Если вы не хотите использовать soft-delete, то на удаление статьи нужно будет сделать `delete from post_change where post_id = ?` (post_change - таблица дат). А после `delete from post where id = ?`.
      В остальном архитектура будет такой же, как и с FK

      Акцент у статьи я пытался чуть другим сделать — FK не уменьшает ошибки, FK не дает каких-либо гарантий, которые уже не были бы даны нормальным бэкендом.


  1. pumm
    28.10.2025 12:19

    "те гарантии, что дает FK, разработчик сам должен поддержать на стороне бэкенда. " - ахаха! При наличии ключа ошибочная операция обломится, а если всё доверить коду, данные поедут, и никто этого не заметит!


  1. atues
    28.10.2025 12:19

    Мне одному кажется, что автор этого опуса решил поиздеваться над здравым смыслом? Ну, тогда продолжу:
    1. на хрен Java, C, C++, Python и так далее - машина Тьюринга и достаточно
    2. или для слабаков - brainfuck

    И еще: давайте откажемся от использования в электрических сетях и проводках предохранителей. Будет же без них работать? Еще как! Правда, последствия от этого так себе, но принцип - главное.

    FK появились не просто так. Они дают определенные гарантии. Важные гарантии. Рискну предложить почитать

    но, боюсь, не в коня корм


  1. Akina
    28.10.2025 12:19

    Господи, ну зачем писАть о том, в чём не разборался? Внешние ключи - это разновидность ограничения (CONSTRAINT), создаваемого в структуре базы данных. А не то, как вы пытаетесь их определять.

    В реальности же FK это гарантия валидности родительского ключа.

    Бред. Всё с точностью до наоборот - внешний ключ обеспечивает валидность значения дочерней записи.

    Внешние ключи в принципе никак не влияют на ... связи между таблицами

    Вот именно. А потому определению "Это ключевой элемент реляционных баз данных для установления связи между таблицами ..." место в мусорном ведре.

    Иными словами — FK не дает дополнительных гарантий.

    Угу. До тех пор, пока взаимодействие с данными ведётся только и исключительно через ограниченный набор валидированного программного обеспечения, и при этом гарантия возникновения нештатной ситуации (например, сбоя) равна нулю. Как и любая идеальная абстракция - не существует.

    Начнем с того, что у любой сущности ID должен быть иммутабельным.

    Давайте лучше начнём с того, что внешний ключ в принципе не обязан ссылаться именно на первичный ключ. А с учётом этой простой вещи весь пункт можно выбросить за ненадобностью.

    И тэдэ, и тэпэ.


  1. Colt045
    28.10.2025 12:19

    А чего только FK?
    Я бы еще тогда пристально и неодобрительно посмотрел и на использование PK.
    Совершенно понятно, что при правильной работе с БД там все записи будут и так уникальными!


  1. DExploN
    28.10.2025 12:19

    ТС конечно ультанул и зря вкинул про "никогда не нужны", но немалая доля смысла в этом есть:

    1) Добавляют ли FK накладных расходов? Добавляют. Следствие, убирая FK- экономия на ресурсах и времени транзакций.
    2) Добавляют ли FK дедлоки? Да, такие сценарии присутствуют.
    3) FK говорит "до свидания" при партициях. Получается если система большая, нужно учиться работать без FK.
    4) Есть ли внешние ключи в распределенных системах ? Нет так как БД разные, и в целом нормально живут. Тогда почему в нераспределенных FK должны быть на всех связях, при этом вдруг становится неважным объем проекта и комманд. Почему команда оплат должна зашиваться связями с командой заказов. orderId или paymentId вполне могут быть не FK на стороне другого модуля и даже иметь неконсистентный Id, вопрос лишь как это обрабатывать при тех или иных сценариях.
    5) Нужно ли абсолютно всегда поддерживать консистентность БД? Нет. Например вполне можно удалять статью, а какой то комментарий оставить мусорным, банально сбой в удалении мусора. При этом мусорный комментарий нам проблем не даст, а на FK мы сэкономим при вставках.

    В общем как всегда - нет белого и черного, везде свои нюансы и подходы.


    1. GerrAlt
      28.10.2025 12:19

      А можете развернуть мысль про проблемы с FK при партиционировании? Если дело в необходимости уникального индекса, то кажется в ряде СУБД (например Oracle, Postgresql Pro) присуствует возможность строить индексы уникальные внутри таблицы даже в случае если таблица партиционированная


  1. Uolis
    28.10.2025 12:19

    Как выше уже заметили, бэкенд вовсе не обязательно может быть один. А значит что? А значит всё, приплыли.

    Из этого же следует очевидное - ключи, структура БД, ограничения, и прочее - ЭТО И ЕСТЬ БЭКЕНД. И в нем всё что вы в своем личном велосипеде (зачеркнуто) бэкенде придумали уже есть.

    И я даже знаю откуда это всё идёт... Из всех этих майскьюэль и прочих кастрированных БД, где ради скорости записи урезано было всё (времена были тяжелые). Потом конечно опомнились, но поздно, теперь всю консистентность данных на этих проектах приходится реализовывать самим, или мигрировать на БД с "встроенным" бэкендом.


  1. Akuma
    28.10.2025 12:19

    Вводные автоматы у вас дома стоят? А зачем? Правильно спроектированная электрика не даст перегрузок или замыканий.

    Тормоза в машине почему ещё не отключили? Правильно рассчитать скорость - и вы остановитесь у пункта назначения.

    Возможно это будет новостью, но БД - это и есть бекэнд. За этим слоем уже ничего нет и, если возможно, как раз тут и нужно обеспечить валидность данных.

    Но статья интересная :)


  1. Fzero0
    28.10.2025 12:19

    Прежде чем спорить о инструментах. Может вернемся к истокам проектирования любой системы: требованиям? И начинаются они не с выбора технологий, а с ответа на вопрос — что важнее: код или данные?

    Если ваша система управляет критически важными данными, которые должны сохранять целостность и пережить множество циклов разработки, миграций и переписываний кода (например, финансовые транзакции, медкарты, документы), то ваш выбор — реляционная СУБД.

    Реляционная СУБД — это инструмент, ядром философии которого являются ACID и гарантии целостности. Платя за такую систему, вы по умолчанию покупаете встроенные механизмы, обеспечивающие "C" (Consistency) и "D" (Durability). Сознательно отказываясь от FK, вы не "оптимизируете" систему — вы вручную выламываете из нее один из ключевых предохранителей, превращая бронированный сейф в картонную коробку.

    С другой стороны, если ваша главная цель — скорость прототипирования и гибкость, а целостность данных на decades не является приоритетом, тогда вам действительно могут быть не нужны FK. Но тогда задайте себе честный вопрос: а ту ли СУБД вы вообще выбрали?

    Использовать тяжелую реляционную систему с ее overhead, но при этом отключать ее основные защитные механизмы — это как купить промышленный фрезерный станок, чтобы забивать им гвозди.

    Ваш идеальный бэкенд без FK — это не инженерное решение, а симптом. Симптом того, что вы, возможно, пытаетесь применить инструмент не по назначению. Может, вам нужна не PostgreSQL, а документная база или key-value хранилище? Начните с требований к данным — и выбор инструмента станет очевиден.


  1. Ananiev_Genrih
    28.10.2025 12:19

    потому что лучше джун удалит 1 запись из user, а не 1 запись из user и все связанные из order :)

    А нечего при создании FK явно самому себе стрелять в ногу в виде доп опции:

     ... on delete cascade

    и будут FK уберегать от таких кейсов сторожа консистентнось


    1. Akina
      28.10.2025 12:19

      А какая собственно разница, удалятся orders или нет? всё одно они останутся ни к чему не прислонённые. Более того, без специальной процедуры поиска таких "висячих строк" их и не обнаружишь... разве что детальные итоги перестанут биться и агрегированными - впрочем, это только обнаружит факт, но не сами записи.

      Да и вернуть их будет тупо некуда.


      1. acsent1
        28.10.2025 12:19

        Восстановить только записи users существенно проще


  1. USGrant
    28.10.2025 12:19

    Забавно наблюдать, как статья начинается с классического «внешние ключи бесполезны», а заканчивается «ну, вообще FK можно использовать как дополнительную защиту». Чем громче заголовок, тем тише концовка.

    Вы, конечно, вправе считать внешние ключи пережитком академического прошлого — особенно если вся практика ограничивается CRUD-приложениями, где один бэкенд и один разработчик «всё контролирует». Но, знаете, жизнь суровее лабораторных.

    Жаль, не указали, где вы работаете. Не из любопытства, а чтобы я заранее знал, какими продуктами лучше не пользоваться: слишком страшно доверять системе, где консистентность данных держится исключительно на вере в идеальность бэкенда.


  1. Arbeiter
    28.10.2025 12:19

    Да, если следовать сухой теории построения отношений в БД, то FK очень полезная штука.
    Но лодка "красивой теории" разбивается о "быт" реализации конкретной СУБД и особенностей работы, с блокировками в частности, а также прямоты рук архитектора БД и разработчиков, особенно при реализации систем с высокой конкуренцией.

    Использование FK (например в MS SQL) ведет к дэдлокам, и проблемам с производительностью БД, которые очень трудно диагностировать, постоянному сканированию индексов, даже при том что данные не менялись, накладным расходам на индексы и другим занятным штукам.

    Примеры можете найти здесь:
    https://sqlperformance.com/2014/06/sql-performance/the-snapshot-isolation-level
    https://sqlserverfast.com/blog/hugo/2006/07/snapshot-isolation-a-threat-for-integrity-part-1/
    https://sqlserverfast.com/blog/hugo/2006/07/snapshot-isolation-a-threat-for-integrity-part-2/


    1. GerrAlt
      28.10.2025 12:19

      Незнаю насчет MS SQL, но рискну предположить (коль скоро это всетаки production-ready система), дедлоки появляются не от FK, а от того как эти FK конкретный разработчик спроектировал, иначе у вас классическое "ложки делают людей толстыми".


  1. deepmind7
    28.10.2025 12:19

    Статья из области

    "Тестирование не нужно. Ведь можно писать код без багов"