假设有两个表:
Student:
StudentID(Primary Key)
Name
StudentTeams:
StudentID(Primary Key, Foreign Key)
TeamName
StudentTeams 表中的 StudentID 引用 Student 表的主键。就关系完整性而言,这种结构的优缺点是什么?
假设有两个表:
Student:
StudentID(Primary Key)
Name
StudentTeams:
StudentID(Primary Key, Foreign Key)
TeamName
StudentTeams 表中的 StudentID 引用 Student 表的主键。就关系完整性而言,这种结构的优缺点是什么?
澄清一下:使用此设置,每个学生都可以有 0 或 1 个关联的 TeamName 值。
让没有 StudentID 作为外键的 StudentTeams 将允许具有无效学生 ID 的记录,因此这可能是一个专业人士。同样,如果 StudentID 不是 StudentTeams 的主键,则可以将一个学生附加到多个团队名称,也可能是专业人士(假设这些是您的业务规则)。
但是,如果这实际上是表结构,那么将 TeamName 作为 Student 表中的一个字段实际上会更好,允许 NULL 值。每个学生可以有 0 或 1 个 TeamName 值,并且不需要单独的关系(或表)。所以,这是一个骗局。
根据我的经验,我只见过几种情况,让 TableA 具有 A_ID 的主键,然后让 TableB 使用 A_ID 作为主键和外键:
性能:如果 TableA 在很多地方被应用程序的许多部分使用,并且 TableB 中的数据只在应用程序的一个孤立部分中使用(一组只有 2% 的用户群可以访问的命令,或者仅在年末使用),并且TableB 中的每一行都很大(例如,如果 Student.Name 的平均长度为 40 个字符,StudentTeams.TeamName 的平均长度为 4000 个字符),则查询如果它不在 Student 表中,不需要 TeamName 可能会执行得更快。
并行表:如果 TableA 的结构不受您的控制,因此您不能将 TeamName 添加到其中,则将 TableB 维护为“并行表”(我自己的术语;如果 TableA 中有匹配的行,则单独的表将只有一行) 可能是做事的唯一方法。当我需要构建一个使用来自第三方供应商应用程序的数据的应用程序时,我曾经设置了许多这样的表,但我们的应用程序需要提供供应商应用程序中不存在的额外数据。外键是必要的,因为它可以使您的信息正确地与供应商的数据相关联(级联更新和删除),而无需修改供应商的应用程序。
逻辑分离: 如果 TableA 和 TableB 中的数据是相关的,但用途却截然不同,那么将它们存储在单独的表中可能是有意义的。和前面的例子一样,将TableA的主键设为TableB中的主键和外键保证了如果TableA条目存在,您将只有一个TableB条目,并且您必须消除TableB行才能删除TableA行。我使用的系统有一个任务表(包含要完成的工作列表)和一个单独的 TaskHistory 表(包含有关完成任务的条件、任务使用的消耗品等的信息)。这样可以简化业务规则;TaskHistory 中的字段可以不为空,即使在任务完成之前无法填写该字段;如果该字段在任务表中,则必须存在特殊的业务规则,保证一旦任务达到完成状态某些字段不为空。请注意,这通常是逻辑和性能的混合:应用程序中有许多查询只需要访问任务表。
进一步的关系要求:正如 ypercubeᵀᴹ 在评论中所指出的,可以使用它来允许第三个表使用 StudentTeams 表中的 StudentID 作为外键,确保第三个表只链接回团队中的学生。就个人而言,我不确定我是否会以这种方式实现结构。这可能会导致对 StudentID 含义的混淆;它总是会链接回 Student 记录,但不会总是链接回 StudentTeam 记录(尽管不可否认,在第三个表的上下文中,它总是会同时链接回 Student 和 StudentTeam)。我倾向于在 StudentTeams 中创建一个 StudentTeamID 值,并链接到该值,因为它的含义会立即清楚(它只会链接到团队中的学生)。
StudentTeams 是一个坏名字,就像复数一样。
通过这种设计,学生可以加入 0 或 1 个团队。
如果多个学生在同一个团队 (TeamName) 重复。两个学生可能在同一个团队中,但有人可能会错误地输入 TeamName,因此您不会知道。
我要么
它将完全按照您现在所拥有的 - 0 或 1 TeamName
团队表和连接表
团队:
ID(PK)
名称
StudentTeam :
SudentID(PK、FK 到 Student.ID)
TeamID(FK 到 Team.ID)
如果您想允许一个学生加入多个团队,那么只需将 TeamID 添加到 PK。
或者您可以跳过 StudentTeam 并将 TeamID 放在学生表中。至少您只输入一次 TeamName。
学生:
ID(PK)
名称
TeamID(FK 到 Team.ID)允许为空