0

我正在进行的当前项目使用 Oracle DBMS 来存储数据。在开发过程中,我发现日期信息没有存储在日期字段中,而是存储在带有一些奇怪格式的 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的日期字段会更好吗?

4

2 回答 2

5

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

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

Assuming you avoid data type conversion, the performance issues are likely to arise from the fact that the optimizer has a great deal of difficulty estimating cardinality when you use the wrong data type. Oracle knows, for example, that there are 365 days (or 8760 hours or 525600 minutes) between 1/1/2012 and 1/1/2013. On the other hand, there are billions of possible strings between '20120101000000' and '20130101000000'. That can cause the optimizer not to use an index when you would like it to (or vice versa), to use the wrong sort of join, etc.

于 2012-05-23T17:36:32.373 回答
1

一般来说,最好将它们存储为日期。您可以使用以下方法转换它们:

to_char(<field>, <format string>)

而且我认为格式字符串 'YYYYMMDDHHMISS' 有效,但我并不肯定。

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

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

于 2012-05-23T17:36:15.810 回答