2015-12-14 33 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, 
相關問題