【发布时间】:2013-12-05 22:45:42
【问题描述】:
我有一个非常大的表,我想在其中添加一个时间戳列。这是一个比插入获得更多更新的表。我试图找出一种方法来做到这一点,而不会使桌子在很长一段时间内停止生产,这让我陷入了困境。我能做到:
alter table stuff add column mod_time timestamp;
好吧,我可以这样做,然后桌子被锁定 3-5 小时。对用户来说不是一个快乐的时光。
例如,对于添加 varchar 列,我可以创建一个新表,添加列,复制数据,然后用新表替换旧表。最后一次切换可以在缓慢的时间内在一两秒内完成。没有问题。当然,我可能需要分阶段进行复制。我可以做一个副本,然后复制第一个副本开始后更改的所有内容。我可以重复这个直到没有任何改变并进行交换。当然,如果我有一个“mod_time”列,则更容易确定发生了什么变化。
我真正想做的是:(1) 创建新表,(2) 复制数据,(3) 添加时间戳列,(4) 交换表。
但是第 (3) 步又需要几个小时。
我希望在添加此列之前更新行以将 mod_time 值设置为 NULL。
如果我在上述步骤中切换 (2) 和 (3),则交换是可行的,但是当我执行此操作以添加列时,我得到了 mod_time =。我想要 NULL。
我可以在进行交换之前尝试将值设置为 NULL,但当然,如果您更新行以将其设置为 NULL,则您正在更新行并且 mod_time 列设置为当前时间。 :-)
我希望我能做到:(1) 创建新表,(2) 添加“mod_time”作为日期时间列 (2) 复制数据,(3) 将 mod_time 更改为时间戳列,(4) 交换表格。
理论上 (3) 可以非常快速地完成(假设日期时间和时间戳的存储是兼容的),因为我在将列更改为 tmestamp 时真正所做的只是改变它在未来的行为,而不是它当前的存储。所以这根本不需要时间,是吗?应该不会吧。
澄清一下,如果我这样做了:
alter table stuff add column mod_time timestamp;
我明白了:
+----------+--------+----------+---------------------+
| col1 | col2 | col3 | mod_time |
+----------+----- --+----------+---------------------+
| 5001 | 50 | 2463 | 0000-00-00 00:00:00 |
| 5002 | 50 | 2467 | 0000-00-00 00:00:00 |
| 5003 | 50 | 2459 | 0000-00-00 00:00:00 |
这就是我想要的。只是alter语句会花费太长时间。我正在尝试的其他一切都给了我:
+----------+--------+----------+---------------------+
| col1 | col2 | col3 | mod_time |
+----------+----- --+----------+---------------------+
| 5001 | 50 | 2463 | 2013-12-05 18:11:21 |
| 5002 | 50 | 2467 | 2013-12-05 18:11:21 |
| 5003 | 50 | 2459 | 2013-12-05 18:11:21 |
【问题讨论】:
-
你的
stuff表有什么样的使用模式?它有很多 INSERT、UPDATE 和 DELETE 吗?时间戳是 INSERT 时间戳吗?或者你会在时间戳上做很多更新吗? -
创作相对较少,更新较多。
标签: mysql alter-table calculated-columns