前言
本周来了一个新需求,领导根据需求划分了开发小组,规范了开发流程,终于可以从头到尾完整地开发一个项目了。
(PS:之前的需求一直是做些零碎的开发,没啥总结的,现在可以完整记录下开发流程了;由于不知道哪些能写哪些不能写,导致此日记基本就是流水账形式了,不算技术类文章,大佬可直接忽略;当故事看看应该还可以吧。)
正文
昨天上午9:30(2020.7.6),领导组织大家开会,简要讲了下需求并群发了需求文档,划分了各模块的开发小组;并且在公司内网的敏捷版上开启了项目迭代流程,简单的说就是分配了大家每天需要完成的任务,每天都得填工时。
本周有两个任务,数据结构设计与接口设计,本周五要开会提交;划分了三个开发小组,各自负责一个模块,人员分别为3:3:4(是不是足球阵容?),并决定了各组组长。
昨天下午+今天一天,本人所在的小组先仔细阅读需求文档,然后开始确定数据结构,也就是数据库表结构,经过热烈的讨论,终于基本确定了——有2个数据库表及其对应的字段。
本人所在的小组负责2个前端页面与对应的java后台,看似简单,实际上手觉得还是有些值得研究的地方的,如果细分可以再拆出2个子页面,对应的接口也需要研究研究。
总结
4人的小组使用2天时间确认了需求文档、确定了数据库表结构,2张表与相应字段。
数据库主表比较好设计,不过其中有一对多对多的关系,因此拆出一张从表来,UUID当主键,将多对多强拆成一对一的结构了。(可能有重复数据,但不知道能不能继续优化了)
初步了解了下接口相关参数,还需要后续确定。
距周五提交,还有2天时间确定接口。
----------------------------------------------------------------------------------------
建表需求
要创建多个任务,一个任务对应多个课程,一个课程对应多个学员。(一对多对多)
表结构(初稿,大概能实现功能,不过后续可能有问题)
1.任务表task,保存课程信息,并直接存课程号(逗号隔开)。
2.课程表course,保存课程信息,并直接存学员号(逗号隔开)。
3.学员表student,保存学员信息。
实际的表结构
1.任务表task,只存任务信息,task_id是主键。
2.课程表course,只存课程信息,course_id是主键。
3.学员表student,只存学员信息,student_id是主键。
4.任务-课程表task_course,保存task_id与course_id,没有主键。(task_id不能为空而已,创建任务时可以暂时不加课程)
5.课程-学员表course_student,保存course_id与student_id,没有主键。(course_id不能为空而已,创建课程时可以暂时不加学员)
分析
*使用两张中间表后,会有重复数据,例如task_course表中,有多行数据,每行的task_id是相同的,不过对应的course_id不同,实现了一个任务对多个课程;(但是task_id就重复了,不知道还能不能优化)
*如果不使用这两张中间表,直接在基础表中用逗号隔开的方式,可以节省数据库空间,避免重复数据,也能实现业务需求。不过后期操作可能会不方便。
所以最后还是选择了使用中间表的方式,算是用空间换时间吧。
PS(摘抄)
1.Mysql使用UUID做主键的缺点:
因为uuid相对顺序的自增id来说是毫无规律可言的,新行的值不一定要比之前的主键的值要大,所以innodb无法做到总是把新行插入到索引的最后,而是需要为新行寻找新的合适的位置从而来分配新的空间。
这个过程需要做很多额外的操作,数据的毫无顺序会导致数据分布散乱,将会导致以下的问题:
①写入的目标页很可能已经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中,innodb在插入之前不得不先找到并从磁盘读取目标页到内存中,这将导致大量的随机IO
②因为写入是乱序的,innodb不得不频繁的做页分裂操作,以便为新的行分配空间,页分裂导致移动大量的数据,一次插入最少需要修改三个页以上
③由于频繁的页分裂,页会变得稀疏并被不规则的填充,最终会导致数据会有碎片
在把随机值(uuid和雪花id)载入到聚簇索引(innodb默认的索引类型)以后,有时候会需要做一次OPTIMEIZE TABLE来重建表并优化页的填充,这将又需要一定的时间消耗。
结论:使用innodb应该尽可能的按主键的自增顺序插入,并且尽可能使用单调的增加的聚簇键的值来插入新行
2.Mysql使用自增主键的缺点:
(1)因为自动增长,在手动要插入指定ID的记录时会显得麻烦,尤其是当系统与其它系统集成时,需要数据导入时,很难保证原系统的ID不发生主键冲突(前提是老系统也是数字型的)。特别是在新系统上线时,新旧系统并行存在,并且是异库异构的数据库的情况下,需要双向同步时,自增主键将是你的噩梦;
(2)在系统集成或割接时,如果新旧系统主键不同是数字型就会导致修改主键数据类型,这也会导致其它有外键关联的表的修改,后果同样很严重;
(3)若系统也是数字型的,在导入时,为了区分新老数据,可能想在老数据主键前统一加一个字符标识(例如“o”,old)来表示这是老数据,那么自动增长的数字型又面临一个挑战。
3.那么,MySql的主键用什么实现好?
答:用雪花算法。【https://my.oschina.net/u/4399909/blog/4258292】
SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高。