我有一个用户模型和一个任务模型。
用户创建任务。这看起来很简单: 该任务有一个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将是相同的数字(比上面的查询更难)
根据最佳做法哪个更健全?
感谢您的时间。
而且,正如第一个答案所暗示的那样(尽管我有点因为某些原因而不愿意接受),从概念上讲,这两个角色是不同的。一个是任务所有者,另一个是与他们共享任务的人。
答案 0 :(得分:1)
“真正的”正确答案将取决于这些表的使用方式,但听起来选项#1应该是您的解决方案(task_table.owner_id和单独的M:M user_tasks表)。即使任务所有者和任务用户共享相同的源表,它们在概念上也是不同的,应该这样对待。表连接的逻辑也会更加清晰。
答案 1 :(得分:1)
正常化到救援!可能.....(虽然根据您的使用情况,可能存在对性能进行非规范化的余地)
表Users
- 存储有关用户(谁)的信息
表Tasks
- 存储有关任务的信息(任务是什么,它做什么等)
表UserTasks
- M-> M映射。
表UserTaskTypes
- 商店(“所有者”,“共享”,“顾问”,“经理”等)
UserTasks
上的可能看起来像这样(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强制执行唯一性。