Циклические зависимости во внешних ключах: использовать или избегать?
мое приложение загружает много данных из базы данных в сложные структуры данных. Структура данных в памяти восстанавливает структуру базы данных, что означает, что если база данных содержит следующие таблицы:
- таблица 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/