`

数据库日期类型字段设计,应该如何选择?

阅读更多

 

  
       当设计一个产品,其中很多地方要把日期类型保存到数据库中,如果产品有兼容不同数据库产品的需求,那么,应当怎样设计呢?
 
(1)
当然,首先想到的是,使用数据库的Date或DateTime类型,可是看看不同数据库这些类型间的区别吧,真让人望而止步。

mysql数据库:它们分别是 date、datetime、time、timestamp和year。
date :“yyyy-mm-dd”格式表示的日期值
time :“hh:mm:ss”格式表示的时间值
datetime: “yyyy-mm-dd hh:mm:ss”格式
timestamp: “yyyymmddhhmmss”格式表示的时间戳值
year: “yyyy”格式的年份值。

date “1000-01-01”到“9999-12-31” 3字节
time “-838:59:59”到“838:59:59” 3字节
datetime “1000-01-01 00:00:00” 到“9999-12-31 23:59:59” 8字节
timestamp 19700101000000 到2037 年的某个时刻 4字节
year 1901 到2155 1字节




oracle数据库:
Date类型的内部编码为12
长度:占用7个字节
数据存储的每一位到第七位分别为:世纪,年,月,日,时,分,秒
TIMESTAMP是支持小数秒和时区的日期/时间类型。对秒的精确度更高
TIMESTAMP WITH TIME ZONE类型是TIMESTAMP的子类型,增加了时区支持,占用13字节的存储空间,最后两位用于保存时区信息
INTERVAL 用于表示一段时间或一个时间间隔的方法.在前面有多次提过.INTERVAL有两种类型.
YEAR TO MONTH 能存储年或月指定的一个时间段.
DATE TO SECOND存储天,小时,分钟,秒指定的时间段.


sql server:datetime和smalldatetime
datetime数据类型所占用的存储空间为8个字节,其中前4个字节用于存储1900年1月1日以前或以后的天数,数值分正负,正数表示在此日期之后的日期,负数表示在此日期之前的日期;后4个字节用于存储从此日零时起所指定的时间经过的毫秒数。
smalldatetime数据类型使用4个字节存储数据。其中前2个字节存储从基础日期1900年1月1日以来的天数,后两个字节存储此日零时起所指定的时间经过的分钟数。
smalldatetime数据类型与datetime数据类型相似,但其日期时间范围较小,从1900年1月1日到2079年6月6日。此数据类型精度较低,只能精确到分钟,其分钟个位为根据秒数四舍五入的值,即以30秒为界四舍五入。


     如果没有兼容多种数据库这个要求,我会毫不犹豫的使用数据库的Date类型。因为如果使用Java框架产生代码,对数据库中定义为Date类型的字段,甚至能在页面上产生出JS的时间选择框,的确能节省很多开发时间。
     而兼容不同数据库,就希望产品在由一种数据库,迁移到另外一种数据库时,尽可能小的代价,使用了Date,看来就很困难了。
    有一个疑问,不知道目前流行的ORM对这个处理得是不是好?因为工作不怎么涉及这方面,所以不大了解。
 
 
     在之前的设计开发中,因为有支持多种数据库这种需求,所以首先否定了日期时间这样的类型。
 
(2)
     曾经使用过毫秒数(java的 System.currentTimeMillis())这种方式,但是选用这个方式,考虑的不是使用起来是否方便或者数据迁移,而是考虑到下面的原因:
 
     java取到的毫秒数是对时间点的一种准确描述。定义如下:
 
      java.lang.System.currentTimeMillis(),
     它返回从 UTC 1970 年 1 月 1 日午夜开始经过的毫秒数。
 
     我们可以看到,这个定义,保证了这个时间值能够被后续设计开发的人员正确和准确的理解,能够为所有的应用正确理解,能够在所有时区上正确反映为正常的时间形式。
 
     当时的产品设计是有海外客户的,所以当时的设计,在数据库里保存的,应该是一个“准确的时间”。例如20120926080000”实际上并没有严格的表示出时间,因为北京时间2012年9月26日8点和格林威治时间2012年9月26日8点显然是不一样的。
     虽然我们都是在一个确切的时区里,例如中国都是使用东八区时间,但是需要考虑的是:
(一)有些产品是可能有海外客户的
(二)产品所运行的机器,时区的设置未必都是东八区。
 
在这种情况下,如果数据库里的时间不准确,会给程序运行带来问题。
这种方式最大的缺点在于:
  •    不方便对时间进行分组查询,比如按月统计、按季 统计
  •     DBA在维护时,不能直观的根据返回的行结果,看到简单明了的结果(看到的是毫秒数)
 
使用这种方式的特点是牺牲一点易用性和可理解性(不易于维护和理解),满足了查询结果的直观性和准确性要求,同时最大限度考虑运行效率。
     为了解决这个问题,我设计了一个辅助的措施,就是建立一个数据库函数来进行时间转换,把毫秒数的时间转为制定时区和格式的时间串,DBA在维护时可以使用。测试了Oracle和DB2上,都可以这样。
    例如之前的查询的时候为:
 
      SELECT username,user_addtime from userinfo
       这个查询显示的是毫秒数
       使用内置函数后写成:
         SELECT username,date2str(user_addtime) from userinfo
    这样返回的就是东八区、预先定义好格式的字符串了。
(3)
在之后的设计里,还使用过YYYYMMDDHHmmSST格式,其中的“T”指时区,加入时区,带来的影响有:
1)日期时间字段就不能在使用数值来存储了,字符串比数字存储和检索的效率都要低。
2)应用程序需要加上额外的处理
带来的好处是:
1)便于DBA维护
2)到什么时候,即便没有看到数据库设计文档,都能看明白并准确理解数据库中一条信息中,这个字段保存到确切信息 
使用这种方式的特点是牺牲一点效率,满足了查询结果的直观性和准确性要求。
总结一下,字段类型的选择,还是根据场景的需要来选择,从功能、效率要求、持续开发的要求、维护的要求几个方面综合考虑。

 

 

分享到:
评论
1 楼 victor0535 2014-05-06  
   总结的不错!

相关推荐

    达梦数据库_SQL语言手册

    数据类型的实际最大长度由数据库页面大小决定,具体最 大长度算法如表 的区别在于前者长度不足时,系统自动填充空 格,而后者只占用实际的字节空间。 表 数据库页面大 实际最大长度 注:这个限制长度只针对建表的...

    2数据库设计规范.doc

    创建、修改(+修改说明)、删除(+删除说明) 目 录 1 编写目的 1 2 数据库策略 1 2.1 数据库对象长度策略 1 2.2 数据完整性策略 1 2.3 规范化设计与性能之间的权衡策略 1 2.4 字段类型的定义与使用策略 1 3 命名...

    图书管理系统数据库表设计.docx

    1管理员表(L_Administrator) 字段名 字段说明 数据类型 约束 备注 a_id 管理员编号 int Primary Key Identity(1000,1) a_name 管理员姓名 nvarchar(20) Not null a_pwd 管理员密码 varchar(20) Not Null 2读者表...

    执法案件管理系统-数据库设计.docx

    不同的表用于相同内容的字段应该采用同样的名称、字段类型定义。 命名规范 命名规范概述 项 目 名 称 命 名 规 范 表名 由前缀和名称两部分组成,前缀为业务模块的拼音缩写,名称采用中文名称的拼音缩写,中间用"_...

    BBS论坛系统数据库设计.doc

    BBS论坛系统数据库设计 0.后台用户管理(TAB_USER) "序号 "字段名称 "字段英文名 "数据类型"长度"PK(Y/N) "NULL(Y/N)"备注 " "1 "自增ID "id "int " "Y "N " " "2 "用户帐号 "usercode "varchar "20 " "N "登录用 " ...

    数据库设计三大范式应用实例剖析

    数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入、删除和更新操作异常。第一范式:数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本...

    数据库应用系统设计与实现

    数据库应用系统设计与实现 实验类型:设计型 实验地点:2楼312 实验时间:12月14日、21日周五1-3/5-7节 实验内容: 系统概述: 某银行需要开发ATM存取款机系统实现如下功能: 1)开户(到银行填写开户申请单,卡号...

    数据库课程设计教职工管理系统.doc

    基本信息表 " "字段名 " "类型 " "宽度 " "Null " " " "zgh " "字符型 " "10 " " " " " "xm " "字符型 " "10 " " " " " "xb " "字符型 " "10 " " " " " "mz " "字符型 " "10 " " " " " "csrq " "日期型 " "8 " " " ...

    数据库设计参考模板.doc

    〖数据库定义规范〗 1、数据库(Database)的定义 数据库命名约定:数据库名长度不能超过20个字符,单词首写字母大写,单词加前 缀"APPDB_",命名规则为: 数据库名称 = "APPDB_" + 数据库内容标识(首字大写) 例如:...

    数据库学生成绩管理系统课程设计.doc

    字段名称 字段类型 字段宽度 xh 字符型 10 xm 字符型 6 xb 字符型 2 csrq 日期型 8 bj 字符型 4 2) 课程登记表——课程表.dbf。 字段名称 字段类型 字段宽度 kch 字符型 2 kcm 字符型 10 js 字符型 10 xf 字符型 10...

    固定资产管理系统数据库设计文档.doc

    固定资产管理系统数据库设计文档 版本:1.0 "作者: " "日期: " " "审批: " "日期: " " 变更记录 "日期 "版本 "变更说明 "作者 " " "1.0 "创建 " " " " " " " " " " " " 目录 1.概述 4 1.1 目的 4 1.2 数据库的...

    固定资产管理系统数据库设计.docx

    作者: 日期: 审批: 日期: 变更记录 日期 版本 变更说明 作者 1.0 创建 固定资产管理系统数据库设计全文共12页,当前为第2页。 固定资产管理系统数据库设计全文共12页,当前为第2页。 目录 固定资产管理系统...

    8数据库设计规范.doc

    创建、修改(+修改说明)、删除(+删除说明) 目 录 1 编写目的 1 2 数据库策略 1 2.1 数据库对象长度策略 1 2.2 数据完整性策略 1 2.3 规范化设计与性能之间的权衡策略 1 2.4 字段类型的定义与使用策略 1 3 命名...

    CMS之数据库设计.docx

    ps:CMS的字段说明 CMS之数据库设计全文共5页,当前为第4页。 表编号 字段编号 字段名 中文名 类型 大小 默认值 允许空 说明 5000 0 CMS_Channel 网站栏目 5000 10 ChannelID 主键 int 4 1 0 主键,自增 5000 20 ...

    进销存的数据库设计文档.doc

    物理设计 5.1销售人员信息表 "字段名称 "数据库字段名 "数据类型 "是否为主键 "备注 " "销售人员ID "SalemanID "Char(10) "是 "销售人员的编 " " " " " "号 " "姓名 "Salename "varchar(50) "否 "姓名 " "密码 ...

    会议管理系统数据库设计文档.doc

    在oracle数据库设计中,一 般来说,对于定长的字符数据字段,取字符类型(char),对于不定长的,取变长字符类 型(varchar)。 2.对于以分类形式出现的字段,建议不使用字符类型,而使用数字类型。如:货物 是否配送为...

    数据库原理课程设计-图书馆管理系统.doc

    libraryinfo (图书馆基本配置记录) studentinfo (学生资料) 2)数据库表详细设计 admininfo,管理员资料记录表 "字段名称 "数据类型 "说明 "长度 " "id "自动编号 "管理员标识号 "长整型 " "adminname "文本 ...

    数据库设计说明书模板

    数据库设计说明书 版本:V1.0 文 档 编 号 保 密 等 级 作 者 最后修改日期 审 核 人 最后审批日期 批 准 人 最后批准日期 修订记录 日期 版本 修订说明 修订人 目 ...

    数据库设计命名规范.docx

    注:在MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放65532个字节的数据,起始位和结束位占去了3个字节 建议在大 数表中含有如下字段 数据库设计命名规范全文共6页,当前为第5页。...

    仓库管理数据库设计.docx

    仓库管理数据库设计 专卖品牌管理数据结构分析草稿 表名 WZJBXX_1 关键字段 所属品牌,品牌类型, 名称,款式,型号,颜色 中文表名(功能描述) 序号 字段名称 字段描述 字段类型 长度 允许空 缺省值 1 品牌编号 int 4 ...

Global site tag (gtag.js) - Google Analytics