为了账号安全,请及时绑定邮箱和手机立即绑定

数据库设计问题,不通过外键如何维护关系

数据库设计问题,不通过外键如何维护关系

一只萌萌小番薯 2019-04-13 08:46:19
现在有几张表:学生表、班级表、专业表、院系表其中学生信息要实现批量导入功能,导入的信息中的班级、专业、院系等都是名称,而不是id,所以在学生表中没有班级、专业、院系的外键,是直接在三个字段中存入名称。但是在其他地方还要用到班级、专业、院系的信息,所以这三个必须建表。这样怎么保证学生表和其他三个表中数据的一致性。
查看完整描述

2 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

泻药。
数据一致性墨菲定律:任何数据只要存储了超过1次,那么数据的一致性就算再精心维持,也迟早会受到破坏,没有例外。
真正有效的文本数据应当并仅允许存储1次。关系应当并仅允许使用ID来维持。任何冗余的数据都只应当用作缓存。学生表中必须只存储班级·专业·院系的ID。这一点没有任何的商量。
应对其他的需求,应当在程序设计方法上见招拆招,而不是动摇数据库设计的原则——
导入时应当识别班级·专业·院系的名称并转换为ID。
在学生表格的最后加入一个缓存列,存储班级·专业·院系的名称用于显示时快速调用,而不应当拆掉学生表格原本的结构。
缓存列任何时候想刷掉就刷掉,绝对禁止视为有效数据,如果可能应当禁止导出。重要场合应当强制刷新甚至禁止缓存。
缓存不是人应该看的东西,在数据表中占地越少越好。比如这个需求,缓存数据就应当用JSON编码后挤在1列里,而不应当啰嗦的存3列。
考虑到班级·专业·院系名称种类相对较少,记录变动也不频繁,也可以考虑使用Redis/Memcached等各种缓存方案。
最后提一下:数据库的外键约束可以使用,但绝对不能作为维持数据关系的可靠方法,只能在小规模数据库中作为兜底的手段。断不可写出“try{$record->insert();}catch(MySQLForeignKeyException$e){...}”这样的代码。
                            
查看完整回答
反对 回复 2019-04-13
?
绝地无双

TA贡献1946条经验 获得超4个赞

你应该在学生表里面存班级、专业和院系的id,如果为了方便展示,也可以存入班级、专业和院系的名字。
一般来说(我指的是要面向很多用户的互联网产品)我们不会使用数据库的forignkey功能,而是采用程序逻辑来维护这些东西的一致性,比如在修改班级名称的时候也记得把所有存了班级名称的数据全部修改过来。这里面并没有什么巧,就是简单的通过程序逻辑(甚至是程序员的自觉性)来保证。
总之,没什么好建议,如果要这么做,小心的写代码吧。
                            
查看完整回答
反对 回复 2019-04-13
  • 2 回答
  • 0 关注
  • 450 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信