今天,是我实习的第三个星期,也就是星期一,公司在赶一个项目,短时间内需要快速融入公司的项目,了解整个大概,主要是要考自己能够快速看懂,并且理解。
在这过程中,看了这个项目的数据库后,我对数据库方面有了新的认识,而不单单是在学校所学的,在学校的时候,只懂得跟着书本上走,显示分析出整个系统的实体,然后画出所有的系统用例图,再根据用例图找出所有实体之间的联系,画出e-r图,再创建相应的表。实体与实体间的联系涉及到了是否要创建中间表,三种关系分别有一对一,一对多,多对多,一对一的额外属性可以添加于任意一方,一对多的额外属性添加于多的一方,多对多的关系则创建一张关联表(之所以创建关联表是因为怕造成数据冗余)。这就是还未实习前最原始的想法了。
但其实,上面这个法则并不是实际项目中真正需要的,尽管它也能实现数据库的设计。但是,
在性能等方面是有很大影响的,关联表虽然不会造成数据冗余,但由于其关联性,我们会进行多层查找,这样就会降低数据库的查询效率,还会加重服务器负担,所以,由于小项目中所涉及到的实体等相关数据比较少,就尽量不要建立关联表
,譬如可以将多对多的额外属性放在合理的一方。有一种情况就是,譬如用户‘、订单、模板和组件四者之间的关系,模板和组件都是实体,而且是不同的实体,每个订单有不同的组件和模板,用户和订单是一对多,订单和模板是多对多,订单和组件是多对多,模板和组件是一对多,并且每个订单都要包含模板和组件,那么问题来了,订单对于模板和组件来说都是多对多,额外的属性假设都只有数量这个属性,按照以前的思维,我会建立两张关联表,但是其实建立一张关联表就够了,可以直接将订单跟模板之间的额外属性直接添加在订单跟组件的关联表上,或者反过来也一样,这样假设或许有的人会吐槽不太合理,但是暂时想不到别的假设了,但是如果是以下情况可能就需要新建表。
如:PHP文章分类为什么要建一个分类表和一个文章表而且相互关联,把分类表的字段加在文章表里面不行吗?
但是,从数据库设计角度看,有几个问题你准备怎么处理?
如果需要列出文章分类怎么办?全表搜索然后去重?
如果文章很多,分类名长短差异大,直接使用字段存放分类名岂不是会浪费很大的存储空间?
如果分类的需求变成多层的,你怎么办?再加一个字段?如果分类层数不限的话怎么办?
如果要禁止向一个分类里再添加新文章怎么办?
如果要添加一个分类,但目前没有任何文章属于此分类又怎么办?
从业务抽象的角度来看,分类是文章的一个属性,它可使用的值是有限的,并且具有自己的一套属性,因此它应当是一个业务对象,对应到数据库就应当有相应的一个表或一组表。
一种情况是一个系统,有多种不同的点赞,比如评论点赞,视频点赞,新闻点赞等等许多的点赞,这个过程涉及到了发表者,点赞者,还有被点赞的东西,发表者和被点赞的东西是一对多的关系,假设它们就只有所属关系,没有其他关联属性了,点赞者和被点赞的东西是多对多的关系,关联属性有点赞的数量,这时,要是只有一种东西,也就是只有一种实体,那么没错,只要建立一张关联表就可以了,但是,现在是有很多种东西,评论,视频,新闻,他们的属性完全是不相似的,不可以将他们当成一个实体来看待的,那么你会不会建立很多个不同的点赞关联表,其实更明智的做法是创建一张关联表,将所有的点赞记录都放在这张表上,你或许会问那它们之间怎么区分开来,虽然它们也都有不同的id,但是它们id会重复啊,那么,你可以建立一张对象表,放不同的对象,标记不同的id,然后将这张对象表的id和被点赞的东西的id和点赞者id都放在这张表上,然后点赞数的属性自然是放在被点赞的东西的实体上。提示:每张表都应该有自己的一个id字段作为唯一识别。