团队:洋芋好想飞
成员:乔祥硕 石高飞 杨慧慧 梁家豪 潘景渝
整理:乔祥硕
PM乔祥硕:
10月25日14:30到17:30,10月27日14:30到17:30,11月1日14:30到17:30,这九个小时我们只做了一件事——设计数据库。
在开始数据库设计前,我们小组成员都进行了简单的构思,实名点赞梁家豪同学,他直接将自己的数据库设计整理成文档,为我们提供了一个大致的方向。我也在讨论过程中作了记录,下面是10月25日会议的记录内容:
关于数据库设计的会议记录
总体来说,我觉得我们的数据库设计像是一个分三次迭代的项目,每一步推进都经由临时的“深思熟虑”,然后幸运地得到项目指导老师周老师、数据库设计指导老师尹老师、讨论课指导老师黎老师的指导意见,让我们认识到思维的局限性,从而进一步推进数据库设计进度,使我们的数据库设计不断走向完善。
项目原型已经基本完善、项目需求已经基本成型,数据库设计似乎没有太大的工作量。在开始数据库设计之前的我的这个想法被证实是错误的,我们也在数据库设计的激烈讨论中渐渐认识到数据库的设计会在很大程度上影响实现难度,同时数据库中的字段设计无不能体现细节,我们必须由“手机端上传噪声数据到服务器”细化到“手机端每五秒上传一次噪声数据到服务器,该数据需要记录这五秒内的噪声最大值、最小值、平均值,上传时间、上传者,并且需要以某种形式记录上传位置信息”,而这其中的每一个字段的确定都实属不易。
数据库中一些看似很简单的表的设计同样经过了“各抒己见-出现分歧-据理力争-达成共识”这一过程。令我印象比较深刻的是下图所示的区域表:
区域表
我们采用的方案是根据湖南大学的各个标志性建筑的经纬度范围将湖南大学划分为多个区域,用于将噪声数据的上传位置进行分类。但我们最初并不是这样设想的——很明显,直接记录噪声数据所对应的经纬度更易实现,同时位置信息直接作为噪声数据的字段可以降低数据库设计难度,但我们经过多次讨论,考虑到噪声数据的显示页面如果直接提供详细的经纬度,那么会很不直观,因此否掉了这一方案,而是在保留经纬度信息的情况下,引入下图所示的区域的概念:
设计数据库时引入的区域的概念
在处理用户头像信息时,我提出了建立头像表给出若干张可供选择的头像,用户只能从中选择其一。这样做一是可以使头像的管理更为简单高效,而是实现起来更为简单,我们不必再去考虑对每一用户自定义的头像的存储与相对应的对头像表的增删改查,而仅仅需要一个外键指向一个固定的表或一个关系表。
头像表
类似的设计细节还有很多。正是小组成员的相互配合以及在“各抒己见”过程中的“不留余地”,我们的数据库设计不断完善,为我们项目的开发打下了良好的基础。革命尚未成功,前路同样当努力如斯。
石高飞:
在数据库设计时,我们和指导老师周老师,还有负责教我们的数据库设计的尹老师,交流了很多次,给了我们很多宝贵的意见,比如,表的结构方面应该逻辑清晰,针对需求进行表的设计,要考虑需求点是否真的可行有效。这也很大程度上推进了我们数据库设计的进度以及设计方案的改良。
因为数据库的设计会直接影响到页面数据的显示的操作难度,所以我们在设计时也是再三斟酌。
噪声数据与用户关系表
针对我们的系统核心,也就是噪声数据的存储表,我们也是十分慎重,花费了很多时间来考虑其构成。考虑到地图显示和曲线生成,我们将原始数据存入噪声数据表,每个5s记录一个噪声信息;考虑到用户上传记录的增删改查,我们又设计了上传记录表;再考虑到地图标识的巨大运算量,我们决定不进行实时更新,而采取存储地图标识的相关数据的方法来提高运行速度……
值得一提的是,我们在商讨用户上传信息的记录时,我提出直接存储某段录音的最大值,最小值和平均值,虽然在讨论中认为这个数据并没有很大的作用,并不能够体现出某些场景的具体信息,想要删除此表,但是经过需求分析后发现,对于手机用户,这个数据可能是最有用也是最直观的。抓住这个点,我们最后定下了如下的表结构,完成了此部分的数据库设计。
用户上传记录表
归根到底,我们在数据库设计上采取的方法是:
针对某一页面进行思考:它需要呈现哪些数据?数据库中应该存储哪些数据?页面和数据库之间的操作逻辑是否简单和明确?
在此基础之上,进行表的增删以及字段与数据类型的设定。
诸如此类的讨论还有很多,此处就不再一一列举。
通过这些逻辑性,合理性的思考,我们在讨论中提高了自己思维的严谨性,更强化了我们对于自己的观点进行清晰表达的能力!我相信,这次团队项目中获得的经验一定会让我在当下收获,未来受益。
杨慧慧:
我们的数据库设计是一个由简单到复杂、由粗略到具体的过程。
由于我们都是初学者,在这个数据库设计的过程中,我们前后经过了很多次讨论修改,即使是最终基本上定下来的时候,还是会对数据库进行修改,比如增加一些字段或者删掉一些字段,来适应我们的需求。
最初设计之前,是在我们组梁家豪想的一些表的基础上进行讨论、增添和删除。
最初的数据库设计构思
在这个图片的基础上,我们进行了长达四个多小时激烈的讨论,最终定下了我们数据库所需要的表及其字段。当时我们是以编辑共享的Excel表的形式来完成这一步。类似于这种。当时针对噪音数据表,我们几番争执不下,尤其是对噪音数据表和上传记录表。最后,我们综合各种条件,根据所提出的理由,完成这些字段的确定。
数据库设计(EXCEL表示)
当完成这些表的时候,我们就去咨询数据库设计的尹老师,请老师给我们提出意见。尹老师首先指出,我们使用的工具不对,用Excel完全体现不出这些表之间的关系,同时,我们既然已经下载好了PowerDesigner,这个工具正好适合现阶段的设计。另外,尹老师和我们说,如何判断数据库设计的是否完整,那就是根据原型界面,看看这个界面所需要的数据,是否能够从数据库取出。如果全部都能取出,那么数据库完整性就保证了,后面的就是考虑是否合理,如何提高效率。于是,在尹老师的建议下,我们用powerDesigner制作了一个简单的图来表述我们的设计内容。
数据库设计(CDM表示)
在这个界面的基础上,我们经过不断的讨论完善,根据功能点,确定了现在的终极版本。
小组成员共同完成的数据库设计
数据库设计不是一个一次性就能完成的工作,尤其对于我们这种初学者,一起讨论,一起研究,确定需要修改的东西,在这个过程中,一定能学到很多东西。
梁家豪:
在小组开始设计项目数据库之前,我就根据自己对整个项目的理解和小组内先前的会议讨论先整理出了整个项目数据库中的大致的表内容和字段内容。本以为提前将数据库的构造完成以后,在接下来的数据库的具体设计和完善中会比较顺风顺水。但是令我意想不到的是我的框架仅仅起到了一些参考作用,并且在数据库的不断完善和需求的不断改动的过程中,数据库也在不断地为了契合需求而进行调整。其中花费时间最多,改动最大的便是我们核心的数据——噪声数据的存储方式。
在我的最原始的数据库的构造中,我参照了前辈们的思路,在手机录音时一秒钟存储一次噪声的分贝数据,上传到数据库中。而在会议过程中,由于对数据库的设计没有太多经验,因此使用的是Excel来进行数据库的字段显示,因此在字段的具体内容方面没有进行深入地讨论。
ECEL表示的数据库表格
在接下来的会议中,当我们深入地想要探讨数据库对需求的实现时发现了,噪音数据表中的记录时间具有很大的模糊性。它究竟指的是一段时间还是一个时刻?若指的是一个时刻,那么用户在查询自己的上传记录的时候难道我们给用户查看的数据是用户每秒上传到的数据吗?若指的是一段时间,那么数据的灵活性又会受到极大的限制。一个个问题扑面而来,至此我们也深刻了解到,设计数据库就应该使用专门的工具,比如powerdesigner。
在发现了数据库与需求上的不契合以后,我们开始重新思考如何进行噪音数据的存储。在经过了一个下午的讨论以后我们决定,新增一个上传记录表用于存储用户在一个录音过程中的数据的极值和平均值,这个表的作用仅仅是为了在用户查询上传记录时能够有一个好的显示效果和更加体现出数据的精确性。至此我明白了,在数据库的设计中我们有时会根据一个需求的需要而添加一个原本不需要的实例。
上传记录表
然而这还没有完。我们原先的设想为在用户录音的期间,仅仅在手机上进行数据的存储,只有在用户停止录音以后才将相应的数据从手机上传至数据库。这个想法在一开始看起来没有问题,但是随着我们的多次讨论渐渐发现了它的不合理,举个简单的例子,如果某个用户将程序放置后台录音并且一直没有中断录音,那么无论他记录了多少的数据最终都不会上传到数据库。因此我们把数据的上传方式更改为了在录音过程中每5秒进行一次噪音数据的上传,在录音结束后才进行上传记录的数据的上传。因此,我们又更改了最原始的噪音数据表。至此我也知道了,在数据库的设计中我们有时会根据技术的实现方式的变化进行数据库的更改。
噪声数据表
一个简简单单的噪音数据存储问题我们就进行了多次的改动,可见数据库的设计是需要跟随项目的具体变化而进行多方面的呃调整的。这次的数据库设计经历也让我得到了很多宝贵的经验。
潘景渝:
这次数据库的设计之后收获颇多:
第一,数据库的设计是紧紧与需求绑定的,在设计数据库之前要对需求有完善的确立,将需求讨论明白了才能将数据库给设计好;
第二,在使用power designer进行cdm转pdm的时候如果是一对一关系,在设计表时可以使用外键关系,如果是一对多关系或多对多关系且需要在关系中新增属性来记录的化可以用association来设计;
如下面的两张图:是一个多对多关系,且需要新增一个属性于是这样使用association之后再使用自动转pdm功能就可以自动生成一个关系表;
实体表与关系表
第三,在设计数据库的时候对于主键的把握也很重要,对于不同情况的表主键有不同的设计方法比如对于基本不会变动的表,如头像表,区域表在创建表时就会把相应的数据导入,且基本不会变动这个时候使用逻辑主键如自增int型,就是一个很好的选择,用来作为外键也很方便;但是对于用户表,这种要实时更新的表使用这种类型的主键就不太合适,例如要注册一个用户,那么判断注册用户是否是重复的账号时要去与表中数据一一匹配才能知道,如果把账户设置为主键,那么通过主键索引可以一下就知道是否是重复;从这个例子中我们可以看出设计主键时对于基本不变的表可以使用逻辑主键,对于需要实时变动的表,我们更好选择业务主键;
第四,在设计表的时候对于字段类型也要仔细思考,对于char的长度要仔细考量,还有对于浮点型的小数位数也要仔细考虑;
第五,对于数据库的设计还有更重要的一点是明白,数据库只是数据库,他不是万能的,只是用来存储数据的仓库,要明确他的职责与适用范围,对于逻辑过于复杂的问题,就不要用数据库来完成,更多大的使用代码去完成。