2015-12-14 35 views
3

我需要将数据类型从float更改为数据库的十进制,目前有10亿条记录。有没有不可预见的问题?谢谢我需要将数据类型从float更改为数据库的十进制,目前有10亿条记录

+3

啊是的,Rumsfeldian系统管理。已知的未知数,未知的未知数...... –

+2

确保在执行此操作之前在另一个环境中测试此操作! – Randy

+0

Innodb? MyISAM数据?现有的FLOAT列是否定义为允许NULL?推动这种转换要求的确切数字情况是什么? –

回答

3

这将需要很长时间,并采取了大量的精心策划。如果你非常仔细地做,你应该计划多天。如果你只是做一个ALTER TABLE,它可能会运行一个星期然后崩溃。我不是在开玩笑。

你能避免这样做吗?你能创建一个视图来显示float列作为小数吗?你会很聪明,试图避免它。

如果您必须继续这样做,您应该尝试在表中添加新列而不是更改现有列。假设您的旧列名为metric,新列名为dmetric。进一步假设你的metric列被定义为NOT NULL。

然后创建新列,以便它允许NULL。

然后把一个索引放在新列上。

然后运行此UPDATE查询大约50万次,直到它不处理任何行。

UPDATE table SET dmetric = metric 
WHERE dmetric IS NULL 
LIMIT 2000 

这将做合理大小的块转换,并且过于庞大保持事务(如果你在InnoDB的世界是)。

请在表的副本上尝试此操作。

+0

感谢Ollie,如何拥抱浮动浮动(10,3),你知道任何休息会发生?谢谢Phuong –

+0

'FLOAT(10,3)'和'DOUBLE'是一样的。如果您将列转换为“DECIMAL(10,3)”,您将会遇到类似的问题,将列从“FLOAT”转换为该格式。 –

+0

感谢Ollie,我们需要更改为数据类型的原因是因为它是浮点数,所以默认情况下它只有6位数,因此值曾经低于999.999。现在它的计数高达1000.01(因为6位数字将精度截断为2位数字),我的雇主始终需要3位数的精度来保证数据的准确性...然后旧数据类型Float肯定会倾向于以适应未来的准确性问题。我们有56列Float需要更改为Decimal,我不知道我该如何安全地做... –

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 JOINCOALESCE将寻找每个值先在自己的新表,然后在现有的表。如果存在更高精度的值,您将从新表中取回,否则您将获得原始值。为此创建一个视图可能很方便。

然后,将您的新到达的高精度数据值,新的观测等,为您的新表,以及现有的一个

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, 
相关问题