在表之间的一对多关系中指定主要关系的约定是什么?

发布于 2024-08-20 17:27:26 字数 979 浏览 5 评论 0原文

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


我会尽力澄清我的实际情况。 (不幸的是,实际的域只会让事情变得混乱。)我有 2 个表,每个表都有很多列,比如说“人员”和“任务”。我还有一个只有几个属性的项目。一个人有许多项目,但只有一个主要项目。一个项目有许多任务,但有时有一个主要任务和替代任务,而有时则没有主要任务,而是一系列任务。没有任何任务不属于项目的一部分,但这并不是严格禁止的。

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)

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


我发现以下问题涉及非常相似的情况:数据库设计:循环依赖

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

I understand how to design a database schema that has simple one-to-many relationships between its tables. I would like to know what the convention or best practice is for designating one particular relationship in that set as the primary one. For instance, one Person has many CreditCards. I know how to model that. How would I designate one of those cards as the primary for that person? Solutions I have come up with seem inelegant at best.


I'll try to clarify my actual situation. (Unfortunately, the actual domain would just confuse things.) I have 2 tables each with a lot of columns, let's say Person and Task. I also have Project which has only a couple of properties. One Person has many Projects, but has a primary Project. One Project has many Tasks, but sometimes has one primary Task with alternates, and other times has no primary task and instead a sequence of Tasks. There are no Tasks that are not part of a Project, but it isn't strictly forbidden.

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

I can't seem to figure a way to model the primary Project, primary Task, and the Task sequence all at the same time without introducing either overcomplexity or pure evil.

This is the best I've come up with so far:

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)

It just seems like too many tables for a simple concept.


Here's a question I've found that deals with a very similar situation: Database Design: Circular dependency.

Unfortunately, there didn't seem to be a consensus about how to handle the situation, and the "correct" answer was to disable the database consistency checking mechanism. Not cool.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

喜你已久 2024-08-27 17:27:26

嗯,在我看来,一个人与一张信用卡有两种关系。一是该人拥有它,二是他们将其视为他们的主要信用卡。这告诉我您有一对一和一对多的关系。由于存在一对多关系,一对一的返回关系已经在 CreditCard 中。

这意味着我将在 Person 中添加 Primary_cc_id 作为字段,而单独保留 CreditCard。

Well, it seems to me that a Person has two relationships with a CreditCard. One is that the person owns it, and the other is that they consider it their primary CreditCard. That tells me you have a one-to-one and a one-to-many relationship. The return relationship for the one-to-one is already in the CreditCard because of the one-to-many relationship its in.

This means I'd add primary_cc_id as a field in Person and leave CreditCard alone.

凉风有信 2024-08-27 17:27:26

两种策略:

  1. 使用位列来指示首选卡。
  2. 使用 PrefferedCardTable 将每个人员与其首选卡的 ID 相关联。

Two strategies:

  1. Use a bit column to indicate the preffered card.
  2. Use a PrefferedCardTable associating each Person with the ID of its preffered card.
-黛色若梦 2024-08-27 17:27:26

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

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

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

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

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

如果您详细阐述并提供有关您的专栏和想法的更多信息,也许会让事情变得更容易。

One person can have many credit cards; Then you'd need an identifier on each credit card to actually link that specific credit card to one individual - which I assume you've already made in your model (some kind of ID that links the person to that credit card).

Primary credit card (I assume you mean e.g. as a default credit card?) That would have to be some sort of manual operation (e.g. that you have a third table, that links them together and a column that specifies which one would be the default).

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

So that would mean that if you connect a person to a credit card, you'd have to specify the NoID, as say '1', then design your query to per default find the credit card that belongs to this individual with NoID '1'.

This is of course just one way of doing it, maybe you'd want to limit by 0, 1 - and then sort them by the date the credit card was added to that person.

Maybe if you'd elaborate and give more information about your columns and ideas it'd make it easier.

一城柳絮吹成雪 2024-08-27 17:27:26

因此,我在这里尝试使用 Northwind 和 C# Windows 应用程序,并且只执行了一个查询。

我的代码:

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]

So here what I tried out with Northwind and C# Windows App ,and I had just one query executed.

My Code:

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);

Result:

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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文