Каково соглашение для обозначения первичных отношений в отношениях «один ко многим» между таблицами? - PullRequest
1 голос
/ 07 февраля 2010

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


Я постараюсь прояснить мою реальную ситуацию. (К сожалению, фактический домен просто запутает вещи.) У меня есть 2 таблицы с множеством столбцов, скажем, Person и Task. У меня также есть проект, который имеет только несколько свойств. Один человек имеет много проектов, но имеет основной проект. Один проект имеет много задач, но иногда имеет одну основную задачу с альтернативами, а в других случаях нет основной задачи, а вместо этого последовательность задач. Нет задач, которые не являются частью проекта, но это строго не запрещено.

PERSON (PERSON_ID, NAME, ...)
TASK (TASK_ID, NAME, DESC, EST, ...)
PROJECT (NAME, DESC)

Кажется, я не могу найти способ смоделировать основной Проект, основную Задачу и последовательность Задач одновременно, не вводя ни слишком сложного, ни чистого зла.

Это лучшее, что я придумал до сих пор:

PERSON (PERSON_ID, NAME, ...)
TASK (TASK_ID, NAME, DESC, EST, ...)
PROJECT (PROJECT_ID, PERSON_FK, TASK_FK, INDEX, NAME, DESC)
PERSON_PRIMARY_PROJECT (PERSON_FK, PROJECT_FK)
PROJECT_PRIMARY_TASK (PROJECT_FK, TASK_FK)

Это просто слишком много таблиц для простой концепции.


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

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

Ответы [ 4 ]

3 голосов
/ 07 февраля 2010

Ну, мне кажется, что у Человека два отношения с Кредитной Картой. Во-первых, он принадлежит человеку, а во-вторых, он считает его своей основной кредитной картой. Это говорит о том, что у вас есть отношения один-к-одному и один-ко-многим. Отношение возврата для взаимно-однозначного отношения уже есть в кредитной карте из-за отношения «один-ко-многим», в котором оно находится.

Это означает, что я добавил бы primary_cc_id как поле в Person и оставил бы CreditCard в покое.

2 голосов
/ 07 февраля 2010

Две стратегии:

  1. Используйте битовый столбец, чтобы указать предпочитаемую карту.
  2. Используйте PrefferedCardTable, связывая каждого человека с идентификатором его предпочтительной карты.
0 голосов
/ 09 ноября 2010

Итак, вот что я попробовал с Northwind и C # Windows App, и у меня был выполнен только один запрос.

Мой код:

DataClasses1DataContext context = new DataClasses1DataContext();
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Product>(b => b.Category);
            context.LoadOptions = dlo;

            context.DeferredLoadingEnabled = false;

            context.Log = Console.Out;


            List<Product> test = context.Products.ToList();


            MessageBox.Show(test[0].Category.CategoryName);

Результат:

SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued], [t2].[test], [t2].[CategoryID] AS [CategoryID2], [t2].[CategoryName], [t2].[Description], [t2].[Picture]
FROM [dbo].[Products] AS [t0]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[CategoryID], [t1].[CategoryName], [t1].[Description], [t1].[Picture]
    FROM [dbo].[Categories] AS [t1]
    ) AS [t2] ON [t2].[CategoryID] = [t0].[CategoryID]
0 голосов
/ 07 февраля 2010

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

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

Person (SSN, Name)
CreditCard (CCID, AccountNumber)
P_CC (SSN, CCID, NoID)

Таким образом, это означает, что если вы подключите человека к кредитной карте, вам нужно будет указать NoID, например, «1», а затем разработать запрос, чтобы по умолчанию найти кредитную карту, которая принадлежит этому лицу с NoID '1'.

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

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

...