2013-06-12 32 views
2

我看到這個linkthis沒有時間存儲日期使用更少的字節?

如果你沒有時間部分指定日期值,則默認 時間是午夜。如果您指定的日期值沒有日期,則默認日期是當月的第一天。

Oracle日期列始終包含日期和時間字段。如果您 查詢使用日期格式,沒有時間部分,則必須 確保DATE列的時間字段設置爲午夜。

解決的辦法是在日期數據類型上對列進行約束,並在插入或更新表中的行時創建觸發器(使用TRUNC())。

如果我用這個解決方案我有一個Oracle並存儲較少的字節,不包括時間日期保修?

有了這個標準的datetime類型的Oracle創建歧義。創建日期類型(僅包含日期)非常困難?這是我的意見(我來自MSSQL)。

+0

看看[這個問題](http://stackoverflow.com/questions/10429276/date-type-without-time-in-oracle)幫助。 [SQL Server 2012中(http://msdn.microsoft.com/en-us/library/ms186724.aspx)確實有一個日期類型,沒有時間。 – DOK

+0

我已經編輯你的問題,沒有那麼多,但我已經回答了這個問題,以及我希望你能確認我的編輯都是你問什麼嗎? – Ben

+0

是的。感謝您的修改。 – Blocked

回答

7

不,你沒有任何的保修......無論發生什麼甲骨文將要存儲事實,這是午夜。你不能沒有時間存儲日期。

如果您創建下表:

create table a (dt date); 
insert into a values(sysdate); 
insert into a values(trunc(sysdate)); 

,然後再運行此查詢:

select dt, dump(dt) from a 

SQL Fiddle

返回的值是:

 
+-----------------------------+------------------------------------+ 
|    DT    |    DUMP(DT)    | 
+-----------------------------+------------------------------------+ 
| June, 12 2013 18:03:15+0000 | Typ=12 Len=7: 120,113,6,12,19,4,16 | 
| June, 12 2013 00:00:00+0000 | Typ=12 Len=7: 120,113,6,12,1,1,1 | 
+-----------------------------+------------------------------------+

DUMP()返回數據類型,以字節爲單位的長度和數據的內部表示。

換言之,與時間的日期,和已被截斷的日期,均具有7個字節。它們長度相同。


作爲一點一點,我會建議不要銷燬潛在有用的數據,因爲你擔心空間。

+0

因此,我使用date.Simply所有我的日期時間字段。 – Blocked

+0

對於所有日期和所有日期時間字段,您使用日期,是@Blocked。這對你沒有任何影響。 – Ben

+0

如果甲骨文存儲日期類型(7個字節),那麼爲什麼要爲我們的截斷插入的數據觸發的長度相同?這是addtion時間我query.Why不只是在選擇使用TRUNC()? – Blocked

1

僅存儲日期可節省空間如果使用table compression

下面是示出僅存儲日期可以減小段大小的一個示例:

create table a (dt date) compress; 
create table b (dt date) compress; 

--Insert 20 million rows, with time 
begin 
    for i in 1 .. 20 loop 
     insert /*+ append */ into a 
     select sysdate + numToDSInterval(level, 'second') 
     from dual connect by level <= 1000000; 
     commit; 
    end loop; 
end; 
/

--Insert 20 million rows, date only 
begin 
    for i in 1 .. 20 loop 
     insert /*+ append */ into b 
     select trunc(sysdate + numToDSInterval(level, 'second')) 
     from dual connect by level <= 1000000; 
     commit; 
    end loop; 
end; 
/

select segment_name, bytes/1024/1024 MB 
from dba_segments 
where segment_name in ('A', 'B') 
order by segment_name; 

SEGMENT_NAME MB 
------------ -- 
A    256 
B    224 

甲骨文基本表壓縮只壓縮整個值,並且如果有較少的不同值然後壓縮可以更好地工作。但從來沒有完全相信任何壓縮演示 - 你需要在自己的數據上嘗試一下。這可能是最好的情況,壓縮可能根本無助於您的數據。

表壓縮有許多不足之處 - 它需要企業版,DML比較慢,你不能將列添加到表等

此外,作爲本建議,你應該執行日期只與規則檢查約束而不是觸發器。它會更簡單,更快速,並且不會阻止使用基本表壓縮所需的直接路徑寫入。

+0

什麼是壓縮'和'創建表B(DT INT)compress'創建並充滿整數值'TRUNC(SYSDATE + B'表的大小... )-to_date(1, 'J')'? –

+0

@EgorSkriptunoff 216 MB。根據Julian日期存儲日期差異會使值變得更小,只有一個或兩個字節。但由於數據已經被壓縮,這對整個表格的大小沒有太大的幫助。看起來這裏存在大量的存儲開銷,阻止了基本表壓縮的真正幫助。也許混合柱狀壓縮會更好,但我沒有Exadata系統來測試它。 –

+0

每20行每行216 MBytes是每行11個字節。我認爲它太多了。我不明白Oracle存儲的垃圾和用戶數據是什麼樣的。 –