Проектирование базы данных SQL - PullRequest
3 голосов
/ 02 марта 2010

Я создаю базу данных для программы, в которой я должен моделировать некоторые отношения в семье. например: Х является отцом для Y, Y является сыном для X

Итак, у меня есть таблица Members со всей информацией о каждом члене, поэтому я подумал о том, чтобы установить связь «многие ко многим» между таблицей Members и самой собой, чтобы Member_Member таблица моста будет иметь столбцы "FK_FromID, FK_ToID" в качестве составного ключа (это правильно?) И "FK_RelationType" в качестве внешнего ключа для RelationTypes таблица, которая будет иметь тип отношения «отец, мать, сын, дочь» и два отношения, идущие как один ко многим из таблицы Members к этим двум внешним ключам

Моя проблема : при удалении, если я выбрал каскадирование, я буду делать циклы, потому что если я удаляю элемент, то будет два прохода удаления к связанным записям в Member_Member bridge, зная, что в программе всякий раз, когда я вставляю отношение отца, я также вставляю отношение сына также в таблицу Member_Member, существует ли способ или обходной путь, позволяющий включить каскадирование, чтобы при каждом удалении члена я удалял связанные записи в Member_member независимо от того, записаны ли они в столбец с внешним ключом или из внешнего ключа

Итак, я не знаю, что делать, это правильный дизайн в первую очередь или как? , что я должен делать с ездой на велосипеде, а также, как вы думаете, что лучший дизайн для той же проблемы должен знать, что мне нужно указать, какие отношения между двумя сторонами

Большое спасибо за любую помощь, и извините за плохой английский Bishoy

Ответы [ 2 ]

2 голосов
/ 02 марта 2010

SQL не очень хорошо справляется с такими "сетевыми" проблемами.

Таблица моста члена-члена - ужасное имя. Это мост "член-родитель" (или "родитель-ребенок"). Мостовые таблицы не должны иметь «составного ключа». Мостовые таблицы имеют суррогатный ключ (просто порядковый номер) и пару ссылок FK на другие таблицы. Два FK должны иметь имена, такие как «member» и «parent», чтобы было совершенно ясно, каковы отношения в этой таблице.

У каждого есть родитель. Не у всех есть дети. Некоторые родители не будут иметь родителей в этой базе данных; они "лучшие родители".

Проще всего, если у верхних родителей есть строки в родительско-дочернем мосту с родительским FK NULL. Таким образом вы избегаете сверхсложных внешних объединений - у каждого члена есть хотя бы одна строка родитель-родитель; в идеале два.

Вы найдете много "цикличных" проблем, так как отношения переходные.

Обратите внимание, что вы не можете - в одном стандартном запросе SQL - найти всех членов семьи или всех родителей на вершине семьи или всех детей и внуков. Существуют расширения SQL, которые делают это возможным, но стандарт плохо с этим справляется.

Каскадное удаление не работает должным образом, потому что отношения в семье направляются двумя способами (родитель к детям, ребенок к родителям), но SQL имеет только один вид направления (ссылка FK).

Вы можете попытаться убедиться, что каждый член ДОЛЖЕН иметь как минимум одну (и максимум две) строки в "member-parent" и удаление члена удаляет две строки в "member-parent" « и ключи имеют правильные имена, вы можете сделать части этой работы.

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

Нет стандартного ответа. Удаление строк из связного графа оставляет элементы несвязанный. Для этого нужно выработать некоторые разумные правила.

Поскольку SQL не справляется с этой задачей, у всех проектов будут проблемы.

0 голосов
/ 02 марта 2010
  1. Предполагая, что у каждого участника может быть только одна мать и один отец, вы сможете получить все отношения, просто сохраняя поля mother_id и father_id в таблице members.

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

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

  2. У моста member_member, который вы предложили, есть одна серьезная проблема, поскольку он подразумевает направление отношений, поэтому, если X является отцом Y, Y также является сыном X. Вы предложили определить отношение дважды в обоих направлениях, но в целом это не рекомендуется. Это форма дублирования данных, и вы можете бороться за обеспечение ссылочной целостности с дублированием данных. Помните, что СУБД не знает, что X является отцом Y, то же самое, что Y является сыном X.

Я знаю, что это не полный ответ, а всего лишь несколько замечаний. Я полностью согласен с ответом С.Лотта , поскольку стандартного способа «решить» это с помощью реляционных баз данных не существует.

...