最佳方法:使用Java 8在MySQL中檢索、加密和更新數(shù)百萬條記錄
P粉211600174
2023-08-27 00:17:18
<p>我們有一個(gè)需求,需要從MySQL數(shù)據(jù)庫中讀取大約1000萬條記錄,對(duì)這些記錄進(jìn)行加密,并將加密后的值更新回字段中。
如何以最高效的方式實(shí)現(xiàn)這個(gè)需求。</p>
<p><strong>1</strong>:使用AES_ENCRYPT從MySQL數(shù)據(jù)庫進(jìn)行字段級(jí)別的加密:據(jù)我了解,AES_ENCRYPT在varbinary上可以有效地工作,但我們的字段只是varchar類型。
因此排除了這個(gè)選項(xiàng)。</p>
<p><strong>2</strong>:之前在我們的一個(gè)應(yīng)用程序中已經(jīng)使用了Java中的Executor功能來實(shí)現(xiàn)批量插入。但記錄數(shù)不超過5萬條。我們被要求使用類似的方法。因此排除了使用Spring Batch來實(shí)現(xiàn)。</p>
<p>我正在尋找在Java 8 / MySQL數(shù)據(jù)庫中需要考慮的可能特性。</p>
<p>Java 8:使用Executor進(jìn)行多線程處理,使用CompletableFuture進(jìn)行異步處理,使用Streaming。</p>
<p>MySQL:創(chuàng)建索引...</p>
- 對(duì)10M行數(shù)據(jù)進(jìn)行任何操作都需要很長(zhǎng)時(shí)間,并且可能會(huì)導(dǎo)致超時(shí)。
- 如果您正在存儲(chǔ)到MySQL中,您只能使用
VARBINARY
或BLOB
。
- 確保聲明的數(shù)據(jù)類型至少比源數(shù)據(jù)大一點(diǎn)。(
SELECT MAX(LENGTH(col)) FROM tbl
)可以給出最大長(zhǎng)度。
- 考慮創(chuàng)建一個(gè)新表,在復(fù)制數(shù)據(jù)時(shí)將其轉(zhuǎn)換為新表中的其他列。然后進(jìn)行測(cè)試。
- 考慮每次迭代處理1000行數(shù)據(jù),使用
PRIMARY KEY
來跟蹤“上次停下來的位置”,如果可行的話。(不要使用OFFSET
)。有關(guān)分塊的更多信息:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks
- 是的,使用某種批量插入方式。但是將批量的總大小限制在1MB左右。(16MB很難通過)。這可能會(huì)使您的數(shù)據(jù)量低于上面提到的1K。
- 對(duì)整個(gè)表進(jìn)行操作所需的時(shí)間不會(huì)與一次性操作相比,每次處理1K行有很大的區(qū)別。
- 在加密數(shù)據(jù)時(shí),將數(shù)據(jù)壓縮也可能值得一試。這可能會(huì)使磁盤占用空間縮小3倍。
點(diǎn)贊 +0
P粉211600174