将日期时间数据存储为数字

时间:2012-05-23 17:21:14

标签: sql database oracle database-design

我正在处理的当前项目使用Oracle DBMS来存储数据。在开发过程中,我发现Date信息不存储在Date字段中,而是存储在VARCHAR2列中,并且存在一些奇怪的格式。例如,请查看此表:

CREATE TABLE "A_TABLE"
  (    
    "OSERC_FEC_INICIO_OS"            VARCHAR2(14 BYTE),
    "OSERC_FEC_FIN_OS"               VARCHAR2(14 BYTE),
    "OSERC_FEC_REGISTRO_PETICION"    VARCHAR2(14 BYTE),
    "OSERC_FEC_APROBACION_PETICION"  VARCHAR2(14 BYTE),
    "OSERC_FEC_LIQUIDACION_OS"       VARCHAR2(14 BYTE),
    "OSERC_FEC_EJECUCION_OS"         VARCHAR2(14 BYTE),
)

字段OSERC_FEC_REGISTRO_PETICION, OSERC_FEC_APROBACION_PETICION, OSERC_FEC_LIQUIDACION_OSOSERC_FEC_EJECUCION_OS存储日期信息,但声明为VARCHAR2列。如果您检查数据,您会看到他们使用格式YYYYMMDDHHMMSS来存储该信息。

我很担心,因为我需要构建在WHERE子句中使用此日期的查询,而且我不确定该方法的索引性能是什么。那么,我提到的设计涉及哪些问题呢?最好是NUMBER而不是VARCHAR2的日期字段?

2 个答案:

答案 0 :(得分:5)

如果日期存储为日期会更好。将它们存储为数字而不是字符串会引入一组不同的问题。

如果您完全坚持使用存储为字符串的日期,为了允许使用列上的索引,您需要将您使用的日期作为参数转换为适当格式的字符串,然后依赖于事实上,以特定格式排序字符串与实际日期的预期排序顺序相匹配。如果您将字符串与日期或数字进行比较,您将获得隐式数据类型转换,这最多会导致性能问题,因为索引无法使用,最坏情况下会产生错误的结果或错误。

假设您避免数据类型转换,性能问题很可能是因为当您使用错误的数据类型时,优化程序很难估计基数。例如,Oracle知道在2012年1月1日到2013年1月1日之间有365天(或8760小时或525600分钟)。另一方面,'20120101000000'和'20130101000000'之间有数十亿个可能的字符串。这可能导致优化器在您希望它时不使用索引(反之亦然),使用错误的连接类型等。

答案 1 :(得分:1)

通常情况下,将它们存储为日期会更好。您可以使用以下方式转换它们:

to_char(<field>, <format string>)

我认为格式字符串'YYYYMMDDHHMISS'有效,但我不是肯定的。

但是,他们选择这种格式可能有原因。 Oracle将日期/时间存储为数字。提取年,月,日,小时和秒需要一些数学操作。根据处理环境,使用子字符串操作来提取日期组件可能要容易得多。

我的猜测是,如果代码使用这些字段,那么有多个使用字符串操作的示例。这似乎是一个有意的设计决定,因此在更改之前要仔细检查(更好的解决方案)。