使postgresql时间戳唯一

使postgresql时间戳唯一,postgresql,Postgresql,我有一个600多万行的数据集,包括从2003年到现在的时间戳。2014年,数据库迁移到postgresql,由于时间戳的精度更高,时间戳列变得唯一。原始ID列未迁移。大约300k的时间戳至少重复一次。我想通过添加精度来修改timestamp列,使它们是唯一的(所有非唯一的时间戳只转到第二个) 我有这个 ts message --------------------|--------------- 2014-02-01 07:40:37 | message1

我有一个600多万行的数据集,包括从2003年到现在的时间戳。2014年,数据库迁移到postgresql,由于时间戳的精度更高,时间戳列变得唯一。原始ID列未迁移。大约300k的时间戳至少重复一次。我想通过添加精度来修改timestamp列,使它们是唯一的(所有非唯一的时间戳只转到第二个)

我有这个

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

这应该行得通,但我想速度会非常慢:

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;
ctid
是Postgres维护的一个(实际上是行的物理地址)


您可能需要添加另一个
where
条件,以仅选择需要修改的行

这应该行得通,但我想速度会非常慢:

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;
ctid
是Postgres维护的一个(实际上是行的物理地址)


您可能需要添加另一个
where
条件,以仅选择需要修改的行

一个简单的解决方案是尝试在时间戳中添加一个随机间隔:

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

碰撞的可能性很小。如果出现这种情况,请使用一个简单的解决方案,即尝试在时间戳中添加一个随机间隔:

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

碰撞的可能性很小。如果出现这种情况,请使用

真正的问题是,您是否绝对确定要使用时间戳作为键(我假设这就是您需要它们唯一的原因)?这些可能不是唯一的,原因不止一个…可能会创建一个“按ts选择组”并循环结果,然后执行另一个选择并向每个记录添加1?真正的问题是,您是否绝对确定要使用时间戳作为键(我假设这正是您需要它们唯一的原因)?这些可能不是唯一的,原因不止一个……可能会创建一个“按ts选择组”并循环结果,然后执行另一个选择并将1添加到每个记录中?我是否正确,这将修改每一行,并将其基本上乘以其行数?@DannyDyla:是的,它将更新每一行,这就是我添加的原因最后的“您可能想添加另一个where条件”。它不会将值与行号相乘。乘法计算添加到时间戳值的每一行的毫秒数(基本上是第一行:+1毫秒,第二行:+2毫秒,第1000行:+1秒等等),我会使用
date\u trunc('second',ts)=ts
作为第二个条件,我是否正确,这将修改每一行,并基本上乘以它的行号?@DannyDyla:是的,它将更新每一行,这就是为什么我添加了“您可能想添加另一个where条件”“最后。它不会将值与行号相乘。乘法计算添加到时间戳值的每一行的毫秒数(基本上是第一行:+1毫秒,第二行:+2毫秒,第1000行:+1秒,依此类推),我将使用
date\u trunc('second',ts)”=ts
作为第二个条件