Sql 数据库模式-混合多对多和一对多关系
我有一个用户模型和一个任务模型 用户创建一个任务。这似乎很简单: 该任务具有用户id外键 但现在我们引入了共享。现在,任务与用户有多对多关系,但属于所有者 我可以: -将用户id保留在任务上(可能将其重命名为“所有者id”) -并使多对多联接表(用户任务或共享用户任务)仅对已共享的任务进行建模 或者我可以: -删除任务上的用户id -并将用户任务设置为纯多对多关系,并使用布尔值“is_owner”来告诉我该用户是否是所有者 或者我可以: -删除任务上的用户id -并使用户任务同时列出共享用户id和所有者id 这意味着对于某些记录,共享的用户id和所有者id将是相同的数字(比上面的查询更难) 根据最佳实践,哪个更可靠 谢谢你抽出时间Sql 数据库模式-混合多对多和一对多关系,sql,many-to-many,one-to-many,Sql,Many To Many,One To Many,我有一个用户模型和一个任务模型 用户创建一个任务。这似乎很简单: 该任务具有用户id外键 但现在我们引入了共享。现在,任务与用户有多对多关系,但属于所有者 我可以: -将用户id保留在任务上(可能将其重命名为“所有者id”) -并使多对多联接表(用户任务或共享用户任务)仅对已共享的任务进行建模 或者我可以: -删除任务上的用户id -并将用户任务设置为纯多对多关系,并使用布尔值“is_owner”来告诉我该用户是否是所有者 或者我可以: -删除任务上的用户id -并使用户任务同时列出共享用户id
而且,正如第一个答案所暗示的(尽管出于某种原因我有点不愿接受),从概念上讲,这两个角色是不同的。一个是任务所有者,另一个只是与他们共享任务的人。正确答案“正确”取决于这些表的使用方式,但听起来选项1应该是您的解决方案(task#table.owner_id和一个单独的M:M user#tasks表)。即使任务所有者和任务用户共享同一个源表,但它们在概念上是不同的,因此应该这样对待。通过这种方式,表连接的逻辑也会更清晰。将其规范化,以挽救局面!可能(不过,根据您的使用情况,可能存在对性能进行非规范化的范围) 表
用户
——存储有关用户(谁)的信息
表Tasks
——存储有关任务的信息(任务是什么、做什么等)
表UserTasks
--M->M映射
表UserTaskTypes
——存储(“所有者”、“共享”、“顾问”、“经理”等)
在UserTasks
上,可能看起来像这样(tsql)
根据您的业务规则,您可以添加检查约束,以强制每个任务只有一个所有者等
为此选择聚集索引可能与对PK进行聚集一样简单,但您将在插入中大量洗牌数据——您可能需要一个代理自动编号PK,并使用唯一约束强制唯一性。有趣的是,您说的概念不同-我同意。我可以看到将user_tasks表共享为user_tasks,我认为这在概念上与用户的任务不同。我还相信,有一个查询我无法轻松完成,即查找用户共享的所有任务。我将编辑我的原始问题,向您展示我的意思。请从定义您的任务以及如何实现最高效的SQL的角度来思考。如果任务创建者不再“共享”任务怎么办?在task_users表中使用ownership标志会使问题复杂化。感谢您的回答-我觉得这会倾向于使用布尔值的user_tasks是什么所有者(我们将只有所有者而不是所有者)。我似乎反反复复,无法证明用户-任务-用户任务是最合理的设置。我将与我的老板讨论,并根据我们最常询问的问题得出结论。
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])
)