假设我们把校园卡管理数据库中所有的属性放在一张表中,用一个关系模式来描述校园卡管理将会怎样?如表3-1所示的关系模式R中,包含属性学生(student)、校园卡(card)、商户(business)和消费清单(salebill)等,其中,属性学生的子属性为学号(SID)、学生名(sname)、学院(college)、学院负责人职工号(MID),属性校园卡的子属性为校园卡号(CID)、密码(password)、余额(balance),属性商户的子属性为商户编号(BID)、商户名称(bname),属性消费清单的子属性为消费金额(payamount)、消费日期(saledate)。
表3-1 关系模式R
(续)
该表的设计是否合理?将所有属性存放在一张表中,貌似一目了然且省去了连接查询或嵌套查询的麻烦,其实不然。开发人员如果倾向于在尽可能少的表中挤下尽可能多的信息,表格将会患上电子表格“综合征”,即表中不仅存在大量的冗余数据,而且在每次数据库有很小的改变时,都要持续不断地重新设计。这可能导致数据的插入操作异常、删除操作异常和更新操作异常。
(1)插入操作异常。例如,当一个学生没有办卡,或者办了卡但是还没有消费,或者刚开业的商户还没有学生来消费时,都会因为主键为空而无法录入实体的基本信息。
(2)删除操作异常。与插入问题相反,删除操作可能会引起信息丢失。例如,一张校园卡注销了,在删除这张校园卡信息的同时,原来拥有这张校园卡的学生的基本信息也会被一起删除。
(3)更新操作异常。大量的冗余数据造成系统要付出很大的代价来维护数据一致性。例如,某学院想更换负责人,就需要更新表中与该学院学生相关的所有行中学院负责人职工号的列值。设该学院有300人,平均每个学生有50次消费记录,则我们需要修改15000个列值。
由此看来这个关系的表结构设计得不好,表中的属性之间存在不合适的依赖关系。一个好的表结构应该使表中的数据冗余尽可能少,不会发生插入异常、删除异常和数据不一致等情况。