sql脚本导入 MySQL手动生成sql脚本一次性导入并更新超大量数据
MySQL手动生成sql脚本一次性导入并更新大量数据(八千万条)
目录
需求
这两天一个以前的项目有了新需求,需要给项目的数据库进行一下改造,其中主要涉及到超大数据量的一次性更新,之前这个项目也涉及了超大量数据的插入,正好统一记录一下
需求是需要将服务器一个目录下的大约八千万个文件的路径导入到数据库里sql脚本导入,文件名就是这个文件在数据库里的一个唯一标识字段。(数据库里已经有了这些文件的信息,但是没有路径)
思路
怎么搞呢?我最开始打算用的办法是先新建一个专门用来存路径的表,先写一个文件搜索脚本把文件路径信息序列化成json文件,在用 mybatis 标签进行批量导入,后来发现这么大数据量用 mybatis 这么搞太不现实,又慢又有风险。
遂开始思考,一般情况下 MySQL 会涉及到超大规模数据导入的,那就是数据库的备份与恢复。
数据库的恢复会用到 source 命令,比如
mysql> source /data/tables.sql
这里用的 sql 文件一般是使用 dump 工具备份的数据库文件,我找来了一个这样的 sql 用文本编辑器打开看了看内部的结构
好家伙,这不就是一个超大量的 sql 脚本吗,先删表然后重新 create ,再锁表,然后就是一排排的
insert into table_name values (),(),()...();
insert into table_name values (),(),()...();
一个 insert 大约是插入一千条左右的数据。
原来 source 就是一个本地执行 sql 脚本的命令,现在知道了 sql 结构,那么我们理论上就能自己写一个脚本,把这样的 sql 文件生成出来,用服务器跑 source 命令,实现超大数据的导入。
本地文件路径序列化 json
说干就干,我们用 C# 写一个搜索程序用来生成 json(其实当时是用 Java 写的,这两天用 C# 重写了遍)
internal class Program
{
static int dataindex = 0;
static void Main(string[] args)
{
Directory.CreateDirectory("data");
FileInfo configFile = new("config.json");
if (!configFile.Exists)
{
Console.WriteLine("配置文件不存在");
return;
}
var configJson = File.ReadAllText(configFile.FullName);
var config = JsonConvert.DeserializeObject<Config>(configJson);
if (config == null) return;
Console.WriteLine(config.scan_path);
config.scan_type = config.scan_type ?? "all";
if (config.scan_path == null)
{
Console.WriteLine("没有指定路径");
return;
}
else if (!Directory.Exists(config.scan_path))
{
Console.WriteLine("指定的路径不存在");
return;
}
var uriList = new List<string>();
ScanFile(config.scan_path, config.scan_type, uriList);
if (uriList.Count > 0)