代码之家  ›  专栏  ›  技术社区  ›  Nagaraj Tantri

检查实体数据的完整性

sql
  •  3
  • Nagaraj Tantri  · 技术社区  · 14 年前

    我在一个大学数据库里有三张桌子,学生,系和课程… 学生有一个uid作为主键->,它是学生的唯一ID 部门的部门ID是主键->是部门编号 课程的主键是C_id->,这是课程/主题ID

    我需要把每门课程中每个学生的学生、系和课程的主键关联起来,将分数存储在表格中。

    UID Dept_id C_id marks
    1    CS     CS01  98
    1    CS     CS02  96
    1    ME     ME01  88
    1    ME     ME02  90
    

    问题是,如果我为标记创建这样的表,那么我觉得数据操作符可能会插入错误的学生主键组合,例如

    UID Dept_id C_id marks
    1    CS     CS01  98
    1    CS     CS02  96
    1    ME     CS01  88 //wrong C_id (course id) inputted by the DBA
    1    ME     ME02  90
    

    在这种情况下,我怎样才能阻止他这样做呢? 还有没有其他方法来为每个学生存储标记?我的意思是:

    UID Dept_id CS01 CS02
    1    CS      98   96
    3    CS      95   92
    
    4 回复  |  直到 14 年前
        1
  •  5
  •   Mark Byers    14 年前

    如果可能,应避免在数据库中复制数据:

    UID Dept_id C_id marks
    1    CS     CS01  98
         ^^     ^^
    

    你可以:

    • 将课程ID更改为两列键(部门、课程编号),例如(“cs”,“01”)。

    或:

    • 保持课程名称不变,但将部门ID字段放在 course 把它从你的表中去掉 marks 表。如果需要计算特定部门的总分,您仍然可以通过向查询中添加联接来轻松地计算总分。

    你最后的建议似乎是个坏主意。对于每个课程,表中都需要一列,并且大多数值都为空。

        2
  •  2
  •   Thomas    14 年前

    我不知道如果课程表明你需要这个部门,为什么你需要这个表中的部门。所以,为什么你的桌子不是:

    UID C_id marks
    1    CS01  98
    1    CS02  96
    1    ME01  88
    1    ME02  90
    

    这张表缺少的是一些时间指示。例如,如果一个学生第一次不及格,他可以上同一门课两次。因此,您需要额外的列来指示学期和年份。

        3
  •  1
  •   HLGEM    14 年前

    你的建议将是一场噩梦。每次在课程表中添加新课程时,都必须添加新的列。很多时候查询也会比较困难。

    如果要确保每个课程都适合部门,可以在触发器(确保处理多个记录插入或更新)或应用程序中执行此操作。这仍然不能防止所有数据输入错误(当您指CS98时,可以选择CS89),但它将减少错误量。在这种情况下,数据不太可能来自应用程序以外的任何地方,因此我可能会选择在应用程序中强制执行规则。一个下拉列表,在其中他们选择了该系,只有该系显示的课程可以做到这一点。

        4
  •  0
  •   Brian Hooper    14 年前

    您可以向表中添加外键约束,以确保为学生ID、课程ID和部门ID输入有效值。您还可以向表中添加唯一约束,以确保不会创建意外的重复项。但最终你不能阻止不正确的数据被插入;如果你知道它是不正确的,你就不需要请求它。

    例如:1957年2月29日不能是我的生日;2025年7月15日不能是我的生日;1974年9月27日不能是我的生日。