前言
在应用开发完成之后,要改变数据库的物理模式相对地比较简单。但是,由于可能影响到应用程序代码中散布的大量的查询和更新操作,因此改变逻辑模式的任务执行起来常常更加困难。因此,在建立后续的数据库应用之前,慎重实施数据库设计阶段是非常重要的。
数据库在软件项目架构设计中,一般偏向于底层,在分层架构中,数据库之上会有一些数据访问层,会用到jdbc、odbc、mybatis、hibernate、SQLAlchemy、database/sql、gorm……等形形色色的数据访问工具。数据库中一旦模式(schema)发生变化(尤其是修改操作),对上层来说,通常是致命的。在测试领域,测试人员最怕听到的一句话大概就是:“程序改了底层逻辑”。因为这时候,基本意味着以前测过的内容需要重新再测一遍。
我在初次设计平台项目的数据库模式时,一直很纠结数据库表与表之间的关系究竟该怎么判定?实际义务中的一个语义,在数据库建模时,该用实体集还是用属性?
正文
表与表之间的关系?
这个不是本节的重点,不过通过实际项目的实战经验,建议不知道改用一对一、一对多还是多对多关系时,就用多对多关系。因为现在的数据访问层代码基本不会需要程序员去手写多表连接查询之类的复杂 SQL 了,ORM 框架已经包办了,调用简洁明了的接口就可以了。因此为了扩展性,直接选择使用多对多关系就可以了,通过前面,我们已经知道了,应用开发一旦过了初始阶段,几乎就不能改动数据库了。
实体集还是属性?
实体(entity)是现实世界中可区别于其他对象的一个“事物”或“对象”。
实体集(entity set)是相同类型即具有相同性质(或属性)的一个实体集合。
实体通过一组属性来表示。
属性(attribute)是实体集中每个成员所拥有的描述性性质。
实体集还是属性?举个例子说的好理解一点,手机号是应该作为一个人(table_person)表的字段(column_phone_num),还是单拎出来建一种新表(table_phone)与人(table_persion)表建关联关系?
一个人只是记录一下国内的手机号,那就作为属性;在一个人可能希望保存关于电话的额外信息,如它的位置,或类型(移动的、视频的或普通的老式电话),或共享该电话的所有的人时,将电话看做一个实体是一种更好的建模方式。因此,把电话视为一个实体比把它视为一个属性的方式更具通用性;而且当通用性可能有用的时候,这种定义方式就更为适合了。
由此自然而然就产生两个问题:什么构成属性?什么构成实体集?很遗憾,对这两个问并不能简单地回答。区分它们主要依赖于被建模的现实世界中的结构,以及被讨论的属性的相关语义。但通过前面手机号的例子,我们已经明白实际中遇到数据库建模问题时该往什么方向考虑了,这点至关重要!