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的值不一样的情况。

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

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

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

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

五、总结

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

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

转载于:https://www.cnblogs.com/VergiLyn/p/6017270.html

【个人想法】个人关于数据库字段类型选择的想法相关推荐

  1. java.sql.Types,数据库字段类型,java数据类型的对应关系

    原文地址为: java.sql.Types,数据库字段类型,java数据类型的对应关系 以下转自:http://kummy.itpub.net/post/17165/172850 本文在原文基础上有增 ...

  2. sqlite数据库字段类型

    数据库字段类型: 字符型字段 topic=models.CharField(max_length=)#需要传入参数,设置字符串的最长长度 email=models.EmailTield()#电子邮箱字 ...

  3. Mysql字段类型选择

    1.字段类型选择 1.1尽量少的占据存储空间 int整形 年龄:tinyint(1个字节)0--255之间 乌龟年龄:smallint(2个字节)0--2的16次方 mediumint(3个字节)0- ...

  4. 查询时注意 查询字段传值参数类型,尽量和数据库字段类型一致

    查询时注意 查询字段传值参数类型,尽量和数据库字段类型一致. 数据量越大查询问题会越严重,到几十万的数据时,类型一致和不一致会是千倍差距 转载于:https://www.cnblogs.com/i60 ...

  5. golang xorm框架对应pg数据库字段类型参照表

    1.左边是golang字段类型,右边是pg数据库字段类型 int integer time.Time timestamp int8 smallint float64 numeric(8,3) (只要是 ...

  6. java中常见数据库字段类型与java.sql.Types的对应

    转自:http://blog.csdn.net/hbzyaxiu520/article/details/5457225 常见数据库字段类型与java.sql.Types的对应 Oracle与java. ...

  7. Django创建数据库(Django数据库字段类型)

    创建默认数据库 项目中数据库的配置在 你的项目/settings.py 中 DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3 ...

  8. mysql中数据库字段类型详解

    mysql中数据库字段类型详解 1,blob字段 mysql中blob是一个二进制大型对象,是一个可以储存大量数据的容器,它能容纳不同大小的数据. mysql中blob的四种类型除了存储数据的大小有区 ...

  9. 实体类与数据库字段类型

    实体类 /*实体类*/ @Column(precision = 12, scale = 3) private BigDecimal rate; //数据库字段类型 rate decimal(12,3) ...

  10. 数据库字段类型、JDBC类型、Java类型映射关系

    数据库字段类型:指的就是数据库字段设置的类型. JDBC类型:java database connector的缩写. 不同的数据库为了能让Java 程序链接并使用数据库, 各个数据库厂商自己提供的驱动 ...

最新文章

  1. Python多线程(3)——Queue模块
  2. linux 正则 设置密码复杂度,Ubuntu修改密码及密码复杂度策略设置方法
  3. 再见了SpringMVC,这个框架有点厉害,甚至干掉了Servlet!
  4. 灯光工厂滤镜插件knoll light factory
  5. vs2015网站发布时,设置页面合并后程序集的文件版本
  6. bash shell基础之三字符串测试及for循环
  7. 大数据应用项目创新大赛_第二届海南大数据创新应用大赛收官
  8. 设计模式-行为型模式-责任链模式
  9. php接口防止app重复提交,AOP防止接口重复提交
  10. docker mysql镜像 使用_docker下MySQL镜像的使用方法
  11. 防火墙审计策略和应用场景介绍(USG6307E)
  12. chrome网页另存pdf_如何在Google Chrome中将网页另存为PDF
  13. STM32F407进入低功耗模式以及唤醒(RTC+中断)
  14. Windows分布式协调器
  15. hazelcast java_Hazelcast
  16. 在线计算机容量单位换算,体积换算 | 容量计量单位转换器 —在线工具
  17. HBase快速导入巨量数据—— Bulk Loading
  18. 亲爱的老狼-ctrl的快捷键用法大全
  19. 解决typescript 提示 Object is possibly ‘null‘
  20. 【Rust日报】 2019-06-01:知乎开源了Rust实现的搜索引擎 rucene

热门文章

  1. java exchangedeclare_Exchange服务器之RabbitMQ四种Exchange类型之Topic (Java)
  2. 完全二叉树的叶子节点数公式_二叉树基础知识
  3. label之间展示间距_工法样板如何做?碧桂园质量工法样板展示区做法标准
  4. 支持向量机SVM原理(参数解读和python脚本)
  5. 阿里云云计算6 ECS的概念
  6. android开发第一个程序,Android开发入门之第一个android程序
  7. 用python写WordCount的MapReduce代码
  8. 第三章CDMA的原理与应用(2)
  9. 华为鸿蒙巴龙麒麟,华为5G新机强势曝光:麒麟985+巴龙5000+鸿蒙系统,颜值性能炸裂...
  10. android studio | openGL es 3.0增强现实(AR)开发 (3) OpenGL es3.0基本知识介绍