Циклические зависимости во внешних ключах: использовать или избегать?

мое приложение загружает много данных из базы данных в сложные структуры данных. Структура данных в памяти восстанавливает структуру базы данных, что означает, что если база данных содержит следующие таблицы:

  • таблица A, ключ A1
  • таблица B, ключ B1, один из столбцов является внешним ключом к [ключу] таблицы a
  • таблица C, ключ C1, один из столбцов является внешним ключом к [ключу] таблицы b

Затем Я есть классы A, B и C, и:

  • элемент данных B (B:: m_a) является указателем на
  • элемент данных C (C:: m_b) является указателем на B

Это означает, что если я загружаю базу данных, я должен загрузить ее в правильном порядке. Если я сначала загружу C, то он будет жаловаться, что не может установить значение C::m_b, потому что экземпляр, на который он должен указывать, не был загружен.

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

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

прочитав о хорошем дизайне (например, книгу "крупномасштабный дизайн программного обеспечения c++"), мне кажется, что это плохая идея иметь круговые ссылки вообще. Е. Г. если файл Х. Ч. включает в Ю. ч, но Ю. Ч. также включает в х. ч вы, наверное, плохой дизайн; если класс X зависит от класса Y, и наоборот, вы, вероятно, имеют плохую конструкцию, которая должна быть решена путем извлечения этих зависимостей и введения третьего класса Z, которая зависит от X и y (x и Y не зависят от друг друга больше).

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

4 ответов


циклическая ссылка нужна только при создании иерархической структуры, такой как организационное дерево.

Table Employees
   EmployeeID   <----------|
   SupervisorEmployeeID ---|

с точки зрения моделирования данных нет ничего принципиально "неправильного" с зависимостью circualr. Это не значит, что модель неверна.

к сожалению, большинство SQL DBMSs не могут эффективно реализовать такие ограничения, потому что они не поддерживают несколько обновлений таблиц. Обычно единственный способ обойти это-временно приостановить одно или несколько ограничений (например, используя "отложенный" внешний ключ или аналогичные функции) или изменить модель, чтобы сделать часть ограничение необязательно (помещая один из столбцов ссылок в новую таблицу). Это просто обходной путь для неприятного ограничения SQL, однако это не означает, что вы сделали что-то неправильно для начала.


У вас есть модель данных. Если в данных есть круговое отношение (например, каждая фотография принадлежит папке; но каждая папка имеет одну фотографию обложки), то правильно моделировать это как круговое отношение в базе данных.

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

http://www.databasesandlife.com/circular-dependencies-on-foreign-key-constraints-oracle/


да, циклические зависимости в базах данных являются хорошим предлогом для переосмысления дизайна.