Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 数据库模式-混合多对多和一对多关系_Sql_Many To Many_One To Many - Fatal编程技术网

Sql 数据库模式-混合多对多和一对多关系

Sql 数据库模式-混合多对多和一对多关系,sql,many-to-many,one-to-many,Sql,Many To Many,One To Many,我有一个用户模型和一个任务模型 用户创建一个任务。这似乎很简单: 该任务具有用户id外键 但现在我们引入了共享。现在,任务与用户有多对多关系,但属于所有者 我可以: -将用户id保留在任务上(可能将其重命名为“所有者id”) -并使多对多联接表(用户任务或共享用户任务)仅对已共享的任务进行建模 或者我可以: -删除任务上的用户id -并将用户任务设置为纯多对多关系,并使用布尔值“is_owner”来告诉我该用户是否是所有者 或者我可以: -删除任务上的用户id -并使用户任务同时列出共享用户id

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

用户创建一个任务。这似乎很简单: 该任务具有用户id外键

但现在我们引入了共享。现在,任务与用户有多对多关系,但属于所有者

我可以: -将用户id保留在任务上(可能将其重命名为“所有者id”) -并使多对多联接表(用户任务或共享用户任务)仅对已共享的任务进行建模

或者我可以: -删除任务上的用户id -并将用户任务设置为纯多对多关系,并使用布尔值“is_owner”来告诉我该用户是否是所有者

或者我可以: -删除任务上的用户id -并使用户任务同时列出共享用户id和所有者id 这意味着对于某些记录,共享的用户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])
 )