2016-01-20 89 views
1

我有一個包含6M +行的數據集,包括從2003年到當前的時間戳。 2014年,由於時間戳的精度更高,數據庫已遷移到postgresql並且時間戳列變得唯一。原始ID列未被遷移。大約300k的時間戳至少重複一次。我想修改時間戳列,以便通過添加精度來保證它們的唯一性(所有非唯一時間戳僅轉到第二個時間戳)。使postgresql時間戳唯一

我有這個

ts     message 
--------------------|--------------- 
2014-02-01 07:40:37 | message1 
2014-02-01 07:40:37 | message2 

我想這

ts       message 
-------------------------|--------------- 
2014-02-01 07:40:37.0000 | message1 
2014-02-01 07:40:37.0001 | message2 
+3

真正的問題是,你絕對確定你想使用時間戳作爲鍵(我假設這就是你需要他們是唯一的)?由於多種原因,這些可能不是唯一的... – CptBartender

+1

也許使用'select group by ts'並循環結果並執行另一個select並將每個記錄添加1? – kometen

回答

0

這應該工作,但是這將是可怕的慢我猜:

update the_table 
    set ts = ts + '1 millisecond'::interval * x.rn 
from (
    select ctid, row_number() over (order by ts) as rn 
    from the_table 
) x 
where the_table.ctid = x.ctid; 

ctidinternal unique identifier (實際上是該行的物理地址)由Postgres維護。

您可能想要添加另一個where條件來只挑出那些需要修改的行。

+0

我是否正確,這將修改每一行,只是乘以它的行號? –

+0

@DannyDyla:是的,它會更新每一行,這就是爲什麼我在最後添加了「你可能會添加另一個條件」。它不會將_value_與行號相乘。乘法計算每個被添加到時間戳值的行的毫秒數(基本上第一行:+1毫秒,第二行:+2毫秒,行#1000:+1秒等等) –

+1

我將使用'date_trunc ('second',ts)= ts'作爲第二個條件 –

0

一個簡單的解決辦法就是儘量隨機間隔添加時間戳:

update t 
set ts = ts + random() * interval '1000000 microsecond' 
where ts = date_trunc('second', ts) 

碰撞的機率是非常低的。如果它發生使用@a_horse's answer