zoukankan      html  css  js  c++  java
  • 【个人想法】个人关于数据库字段类型选择的想法

    ps: 本来前几天打算写一片关于整个项目设计的个人想法(其实是想吐槽工作到现在几家公司的垃圾*3的开发模式),但磨磨唧唧的就写了一点,实在下班后太懒不想写就夭折了…><!

      首先,此文只是自己简单的想法。我所参与的项目数据库设计都是一坨shit,也不知道好的表设计到底是怎么样的。个人技术就是两坨shit,为什么要写这篇只是想坚持写下去。不知道写什么,不太想写的时候先找点简单的写着。

      不废话了,开始。

      以下可能部分是针对oracle说的,但其实主要不是这。这文章的主题只有一个:设计表的时候,应该要严格字段类型、长度、默认值、是否可以空、是否唯一性,宁愿要错误的数据不进数据库,也别让数据库存在错误的数据

      严格的好处(其实是精心的表设计的带来的好处,不是说日期类型的一定要用date):

        1、保证数据库数据的严谨、正确性。

        2、应该能减少很多逻辑判断代码。

      缺点:

        1、适用性/灵活性低。(这其实是当初设计时考虑不周带来的后果)

        2、可能不友好,因为会让正行数据直接不保存到数据库。

    一、字段类型、长度、默认值选择

      用最符合的字段类型,别一味的用varchar或必将模糊的类型

      类型选择,字符串就选择varchar、nvarchar、BLOB等,数字就用number、integer、float,文本CLOB、BLOB。日期,除开特别的比如row的updatetime、createtime等用timestamp、date外(为什么oracle的timestamp不支持自动更新,我查到的基本都说要自己写触发器等)。其实我个人不喜欢用date的类型,比较推荐用java对应long,数据库可能是number(varchar2也是可以,但还是喜欢number)。原因:1、单纯只是写sql不喜欢日期类型的。 2、不管怎么样,前端交互到后台,后台到数据库都会格式化次日期,所以单纯喜好java-long,oracle-number的日期。

      长度,这要根据需求来定。但针对某些确定的,比如手机号、身份证等,可能页面验证了、后台也验证了。但数据库还最好严格最大11位、18位,还是那观点宁愿错误数据别进数据库,也别保存错误的行数据

      默认值(基本和非空一起),可能很多都不在意默认值,而且默认值也比较难设置。但还是尽量有默认值。

        ex: 银行卡账户余额bank.balance –> java BigDecimal,就算是新卡应该是0而不是null。这牵涉到的问题在于,后台代码是否要再去判断非null。如果只要没存过钱到卡里面这余额都是null,那么意味着我要用这字段的时候,我先要做的是判断这个字段是不是null,如果是null则当0处理。如果不判断,很有可能存在NullPointerException(就算你保存的是否赋值0,但谁知道在什么地方可能进去null的数据了)。这其实变相减少了代码,也防止了错误数据进数据库。

    二、非空

      非空这基本都可能存在默认值,但也不一定,比如业务流水号(系统自动生成),一定非空,但默认值没法设置。(有默认值,强烈建议字段非空。)

      这和前面一样,可以有效减少使用字段时候的判断(但可能,保存的校验代码就多了。)。就算代码量差不多,那我为什么不保证数据库数据的正确性了?

    三、唯一性

      最近被这折磨的不行。设计的A-B两张把是OneToOne,根据fieldA-varchar的。但是,表之间没外键关系,没唯一性约束。加上项目混乱,现在在B表的fieldA有重复,导致关联错误。绝大部分sql都是这关联关系(项目中还有别的可以关联到),根本不可能改sql关联改的过来。维护了几次数据库,还是会出现fieldA重复。

      所以,既然当初设计是明确的。为什么不把唯一性约束加上呢?

      确实,针对现在的项目加上唯一性的问题是:

        1、因为A-B表都不是物理删除,而是逻辑删除。每张表都有字段isDeleted=true/fale。所以逻辑删除后,可能fieldA要保持不变。所以正常是会重复。但也可以解决,比如删除的流水号更新成fieldA+”(旧)”等等方式。

       (直到现在,我们那表还没唯一性,还是不知道哪些地方可能产生重复数据保存进数据库。可想而知,我们开发模式问题之大。)

    四、外键(范式/反范式)

      今天(2016-11-02)突然想起了还有外键,就简单写下自己的看法。重点看: 大家设计数据库时使用外键吗?

      其实看这么多回答讨论后,我就感觉一个观点:要时间还是空间。(个人简单理解的此处的范式与反范式: 范式--牺牲时间节省空间,反范式--牺牲空间加快时间)

      ex:  很常见的场景,快递单有很多信息,有签收人的姓名、电话。 此时是把这些字段直接保存到快递单(快递单就冗余了字段、而且可能产生快递单的姓名和客户表的姓名不一致),还是快递单关联客户信息表。

        1、范式sql: select a.id,a.name,b.bname from tableA a  inner join tableB b on a.bid = b.id …

        2、反范式: select a.id,a.name,a.bname from tableA a

        很明显,范式因为存在外键关联,肯定会影响查询速度。虽然反范式查询速度快,但可能出现bname的值不一样的情况。

      那么,同样的外键:物理外键、逻辑外键呢?  在那提问中有写回答很好的,可在去仔细看下。

      我自己的想法其实不确定: (建议是物理外键)

        物理外键的好处是严谨、低效率(但在我所参与的系统这个低不存在任何影响)、繁琐(必须要先保存主表才能保存从表,要先删子表才能删主表。当然,也可以修改策略)。

        逻辑外键好处是没有过多的约束,但响应的数据库肯能有很多冗余数据。可能经常物理/逻辑删除了主表,而从表没做任何操作。

    五、总结

      感觉写出来的和我想写的差好多,都不知道写了些什么。

      就保持一个观点吧:宁愿要错误的数据不进数据库,也别让数据库存在错误的数据

  • 相关阅读:
    Android Native Hook技术(一)
    Android Native Hook技术(二)
    Dalvik源码阅读笔记(一)
    Dalvik源码阅读笔记(二)
    Android反调试笔记
    /dev/mem可没那么简单
    jenkins使用邮件功能
    docker 安装 oracle
    jstack
    docker network
  • 原文地址:https://www.cnblogs.com/VergiLyn/p/6017270.html
Copyright © 2011-2022 走看看