美文网首页
关系数据库如何应对业务变动

关系数据库如何应对业务变动

作者: 北交吴志炜 | 来源:发表于2019-05-02 20:47 被阅读0次

    前言:
    不知道现在的大学里面,在学习关系数据库时,还提不提数据库三范式
    第一范式:列不可拆
    第二范式:主键唯一
    第三范式:外键关联,避免数据冗余

    数据库发展到现在,无论是从数据库本身的设计层面,还是业界对于数据库的使用层面,上述三范式中,除了主键唯一这个范式还被遵守,其余的两个都已经被突破了。首先,"列不可拆",MySQL 5.7 之后引入JSON类型,突破。其次,"外键关联,避免数据冗余"这点,在分布式应用,分库分表的场景下,比如陆金所,应用层禁止一切关联查询。其他的一些大厂,禁止三张表以上的关联查询,而且为了减少DB IO次数,在设计上会支持一定程度的数据冗余,第三范式也被突破。

    业务需求变动的时候数据库设计面临的问题

    很多的系统,从分层上都是这样的,见下图。


    image.png

    有句话叫“世界上唯一不变的是变化本身”,软件系统也不例外,当系统上线之后,产品经理跑过来说"XXYYZZ,很简单的。",然后你从DB开始进行变更,然后到SQL,加上DAO,SERVICE,WEB层的各种DO,DTO一路改下去;没过几天,产品经理又来了,循环往复。那么从设计上有没有办法来规避呢?

    数据库设计如何应对需求变动

    1.主表,拓展表
    在设计的时候,将主要属性,或者说第一个版本的属性,直接放入主表,后续有新加的字段,直接放入拓展表中。
    以员工表为例,主表中存姓名,年龄,入职日期这些字段,后续需求变动,产生的新字段直接以key,value的形式存在拓展表中。比如需要加一个职级,就在拓展表里加一条记录,key="emp_level",value=”研究员“。


    image.png

    那么在应用层面,拓展表的信息是怎么体现的呢?在DO层面有一个Map属性,用来存拓展信息

    public class Employees {
        private Integer empNo;
    
        private Date birthDate;
    
        private String firstName;
    
        private String lastName;
    
        private String gender;
    
        private Date hireDate;
    
        private Map<String, String> extInfo = new HashMap<String, String>();
    }
    

    每一个查询,需要两个sql,一个sql查主表,一个sql去查拓展表,查完之后,再将拓展表的查询结果装配进extInfo属性中。

    这种方案我个人认为比较复杂,数据库层面多了一个表,而且一组key:value就需要增加一条记录,会增加数据量级;应用层面的问题是,需要有一个装配拓展属性的工作量。

    2.JSON类型的字段
    这种方案是,在主表上直接预留一个JSON类型的字段,如果数据库版本不支持,直接使用String字段。


    image.png

    需求变动的时候,json本身就是一个变化的结构,可以很好的应对。
    这时候,DO变成了下面这样,之前的Map属性直接变成一个json串。

    public class Employees {
        private Integer empNo;
    
        private Date birthDate;
    
        private String firstName;
    
        private String lastName;
    
        private String gender;
    
        private Date hireDate;
    
        private String extInfo;
    }
    

    相较于主表,拓展表的形式,此种方案在表结构上,就一个表;应用层面,一次查询即可,也无需开发属性填充的功能。如果调用方可以直接解析json,这种模式在面对变动的时候,一行代码都不用改。

    总结:面对需求变动,如果一条线改到底,开发工作量大,测试风险也会变大。主表拓展表的方案,在数据库和应用层,复杂度提高了,我个人认为最优解是json结构的字段。当然具体问题还需要具体分析,每一种方案都有其缺点,以json方案为例,如果需要对json中的字段作为查询条件,那么其性能还需要进行特殊处理,后续有时间会再研究下mysql的json字段。

    相关文章

      网友评论

          本文标题:关系数据库如何应对业务变动

          本文链接:https://www.haomeiwen.com/subject/etlonqtx.html