1

我有一个用户模型和一个任务模型。

用户创建任务。这看起来很简单:任务有一个 user_id foreign_key

但现在我们介绍共享。现在一个任务与用户有多对多的关系,但属于一个所有者。

我可以: - 将 user_id 保留在任务上(也许将其重命名为 'owner_id') - 并且让多对多连接表(user_tasks 或 shared_user_tasks)仅对已共享的模型任务进行建模。

或者我可以: - 删除任务上的 user_id - 并使 user_tasks 与布尔值“is_owner”建立纯粹的多对多关系,以告诉我该用户是否是所有者

或者我可以: - 删除任务上的 user_id - 并使 user_tasks 同时列出 shared_user_id 和 owner_id 这意味着对于某些记录,shared_user_id 和 owner_id 将是相同的数字(比上面更难的查询)

根据最佳实践,哪个更合理?

感谢您的时间。

而且,正如第一个答案所暗示的(尽管出于某种原因我有点不愿接受),从概念上讲,这两个角色是不同的。一个是任务所有者,另一个只是与他们共享任务的人。

4

2 回答 2

1

规范化拯救!可能.....(尽管根据您的使用情况,性能可能会有非规范化的范围)

Users——存储有关用户(谁)的信息

Tasks——存储有关任务的信息(任务是什么,它做什么等)

UserTasks——M->M 映射。

UserTaskTypes——商店(“所有者”、“共享”、“顾问”、“经理”等)

onUserTasks可能看起来像这样(tsql)

CREATE TABLE UserTasks (
    [TaskID] INT,
    [UserID] INT,
    [UserTaskTypeID] INT,

    FOREIGN KEY FK_UserTasks_TaskID ([TaskID])
            REFERENCES Tasks ([TaskID]),

    FOREIGN KEY FK_UserTasks_UserID ([TaskID])
            REFERENCES Users ([UserID]),

    FOREIGN KEY FK_UserTasks_UserTaskTypeID ([UserTaskTpyeID])
            REFERENCES UserTaskTypes ([UserTaskTypeID]),

    PRIMARY KEY PK_UserTasks ([TaskID], [UserID], [UserTaskTypeID])
 )

并且根据您的业务规则,您可以添加 CHECK CONSTRAINTS 以强制每个任务只有一个所有者等。

为此选择一个聚集索引可能就像聚集 PK 一样简单,但是您会在插图上大量打乱数据——您可能需要一个代理自动编号 PK 并使用 UNIQUE CONSTRAINT 强制唯一性。

于 2013-06-04T20:48:13.260 回答
1

“真正的”正确答案将取决于这些表的使用方式,但听起来选项 #1 应该是您的解决方案(task_table.owner_id 和单独的 M:M user_tasks 表)。尽管任务所有者和任务用户共享同一个源表,但它们在概念上是不同的,应该这样对待。这样,表连接的逻辑也会更清晰。

于 2013-06-04T20:14:25.017 回答