Answers
对于这个简单的系统, 班级、专业、院系都用字符串存储是没有问题的, 而且简化了你的业务逻辑. 只有在班级、专业、院系修改时出现了数据的不同步. 但这种情况不不常见, 也不难解决.
如果将班级、专业、院系都转化为ID来存储, 那么占用更少的空间, 但使用每次读取都要连接表才能显示出来.新增,更新, 删除这些字段都变得复杂了. 用ID来存储的另外一个问题是存档, 用户可能会提问, 为什么软件上看到的资料跟自己以前打印出来的纸质版不同. 例如有个人从1班调到2班了, 那么你连接出来的资料全部变成了2班的, 这是需要考虑考虑了.
泻药。
数据一致性墨菲定律: 任何数据只要存储了超过 1 次,那么数据的一致性就算再精心维持,也迟早会受到破坏,没有例外 。
真正有效的文本数据 应当并仅允许存储 1 次 。关系 应当并仅允许使用ID来维持 。任何冗余的数据都只应当用作缓存。学生表中必须只存储班级·专业·院系的ID。这一点没有任何的商量。
应对其他的需求,应当在程序设计方法上见招拆招,而不是动摇数据库设计的原则——
- 导入时应当识别班级·专业·院系的名称并转换为ID。
- 在学生表格的最后加入一个缓存列,存储班级·专业·院系的名称用于显示时快速调用,而不应当拆掉学生表格原本的结构。
- 缓存列任何时候想刷掉就刷掉,绝对禁止视为有效数据,如果可能应当禁止导出。重要场合应当强制刷新甚至禁止缓存。
- 缓存不是人应该看的东西,在数据表中占地越少越好。比如这个需求,缓存数据就应当用 JSON 编码后挤在 1 列里,而不应当啰嗦的存 3 列。
- 考虑到班级·专业·院系名称种类相对较少,记录变动也不频繁,也可以考虑使用Redis/Memcached等各种缓存方案。
最后提一下:数据库的
外键
约束可以使用,但绝对不能作为维持数据关系的可靠方法,只能在小规模数据库中作为兜底的手段。断不可写出“
try { $record->insert(); } catch (MySQLForeignKeyException $e) { ... }
”这样的代码。