我需要将数据类型从浮点数更改为当前获得10亿条记录的数据库的十进制数。有没有不可预见的问题?感谢
答案 0 :(得分:6)
这需要很长时间,并需要进行大量精心规划。如果你非常小心,你应该计划多天。如果您只是执行ALTER TABLE,它可能会运行一周然后崩溃。我不是在开玩笑。
你能避免这样做吗?你能创建一个将float列显示为十进制的视图吗?你会很聪明地试图避免它。
如果你必须继续这样做,你应该尝试在表中添加一个新列而不是改变现有列。假设您的旧列名为metric
,新列称为dmetric
。进一步假设您的metric
列定义为NOT NULL。
然后创建新列,使其允许NULL。
然后在新列上添加一个索引。
然后运行此UPDATE查询大约五十万次,直到它不处理任何行。
UPDATE table SET dmetric = metric
WHERE dmetric IS NULL
LIMIT 2000
这将以合理大小的块进行转换,并保持交易(如果您在innodb世界中)变得太大。
请在表格副本上试试。
答案 1 :(得分:1)
另一种方法,如果你的千兆行表有ID号或其他可用的主键,它将起作用。这样您就可以在没有太多停机时间的情况下升级精度。
创建一个新表 - 称之为precision_value
- 有两列:
id BIGINT NOT NULL pk
dmetric DOUBLE (or DECIMAL(10,3))
将需要更高精度的查询更改为此类内容。
SELECT a.id, ...,
COALESCE(b.dmetric, a.metric) dmetric,
...
FROM your_big_table a
LEFT JOIN `precision_value` b ON a.id = b.id
LEFT JOIN
和COALESCE
的使用将首先在新表中查找每个值,然后在现有表中查找。如果存在更高精度的值,您将从新表中获取它,否则您将获得原始值。为此创建视图可能很方便。
然后,将新到的高精度数据值,新观察值等插入到新表格和现有表格中
INSERT INTO your_big_table (metric, whatever) VALUES ('1.234567890', 'whatever');
INSERT INTO precision_values (id, dmetric) VALUES (LAST_INSERT_ID(), '1.234567890')
这个新表基本上是一个用于更高精度数据的旁视表。
最后,将输出适当地舍入到您的应用程序中。例如,如果你想要三个小数位,那就可以了。
SELECT a.id, ...,
ROUND(COALESCE(b.dmetric, a.metric),3) dmetric,