1

我了解如何设计一个在其表之间具有简单的一对多关系的数据库模式。我想知道将该集合中的一个特定关系指定为主要关系的约定或最佳实践是什么。例如,一个人有许多信用卡。我知道如何建模。我如何将其中一张卡指定为该人的主要卡?我提出的解决方案充其量似乎并不优雅。


我会尽量澄清我的实际情况。(不幸的是,实际的域只会混淆事物。)我有 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)

对于一个简单的概念来说,它似乎太多了。


这是我发现的一个问题,它处理非常相似的情况:Database Design: Circular dependency

不幸的是,对于如何处理这种情况似乎没有达成共识,“正确”的答案是禁用数据库一致性检查机制。不酷。

4

4 回答 4

3

好吧,在我看来,一个人与信用卡有两种关系。一个是这个人拥有它,另一个是他们认为它是他们的主要信用卡。这告诉我你有一对一和一对多的关系。一对一的返回关系已经在 CreditCard 中,因为它是一对多的关系。

这意味着我将在 Person 中添加 primary_cc_id 作为字段,并单独留下 CreditCard。

于 2010-02-07T10:35:09.850 回答
2

两种策略:

  1. 使用位列指示首选卡。
  2. 使用 PrefferedCardTable 将每个人与其首选卡的 ID 相关联。
于 2010-02-07T10:36:23.700 回答
0

一个人可以拥有多张信用卡;然后,您需要在每张信用卡上都有一个标识符,以便将该特定信用卡实际链接到一个人 - 我假设您已经在您的模型中制作了该标识符(某种将个人链接到该信用卡的 ID)。

主要信用卡(我假设您的意思是例如默认信用卡?)这必须是某种手动操作(例如,您有第三张表,将它们链接在一起,并有一列指定哪个是默认信用卡)。

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

因此,这意味着如果您将某人连接到信用卡,则必须指定 NoID,例如“1”,然后将查询设计为默认情况下查找属于此人的信用卡,NoID 为“1” '。

这当然只是一种方法,也许您希望限制为 0、1 - 然后按信用卡添加到该人的日期对它们进行排序。

也许如果您详细说明并提供有关您的专栏和想法的更多信息,它会更容易。

于 2010-02-07T10:40:18.700 回答
0

所以在这里我尝试了 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]
于 2010-11-09T02:19:40.417 回答