目录
-
- 摘要
- 一、数据导入导出概述
-
- [1.1 支持的数据格式](#1.1 支持的数据格式)
- [1.2 导入导出函数](#1.2 导入导出函数)
- 二、CSV文件操作
-
- [2.1 导入CSV](#2.1 导入CSV)
- [2.2 导出CSV](#2.2 导出CSV)
- [2.3 大文件导入](#2.3 大文件导入)
- [2.4 CSV导入实战](#2.4 CSV导入实战)
- 三、JSON文件操作
-
- [3.1 导入JSON](#3.1 导入JSON)
- [3.2 导出JSON](#3.2 导出JSON)
- [3.3 嵌套JSON处理](#3.3 嵌套JSON处理)
- 四、Parquet文件操作
-
- [4.1 导入Parquet](#4.1 导入Parquet)
- [4.2 导出Parquet](#4.2 导出Parquet)
- [4.3 Parquet优势](#4.3 Parquet优势)
- 五、数据库同步
-
- [5.1 MySQL同步](#5.1 MySQL同步)
- [5.2 PostgreSQL同步](#5.2 PostgreSQL同步)
- 六、批量导入导出
-
- [6.1 批量导入](#6.1 批量导入)
- [6.2 定时同步](#6.2 定时同步)
- 七、数据格式转换
-
- [7.1 格式转换](#7.1 格式转换)
- [7.2 数据清洗](#7.2 数据清洗)
- 八、性能优化
-
- [8.1 导入优化](#8.1 导入优化)
- [8.2 导出优化](#8.2 导出优化)
- [8.3 性能对比](#8.3 性能对比)
- 九、总结
- 参考资料
摘要
本文系统介绍DolphinDB数据导入导出功能。从CSV文件到JSON数据,从Parquet格式到数据库同步,全面讲解各类数据格式的导入导出方法。通过丰富的代码示例,帮助读者掌握高效的数据交换技能。
一、数据导入导出概述
1.1 支持的数据格式
数据格式
文本格式
CSV
JSON
TXT
二进制格式
Parquet
ORC
HDF5
数据库
MySQL
PostgreSQL
SQL Server
1.2 导入导出函数
| 函数 |
说明 |
| loadText |
导入文本文件 |
| saveText |
导出文本文件 |
| loadTextEx |
导入到分布式表 |
| saveTextEx |
从分布式表导出 |
| loadParquet |
导入Parquet |
| saveParquet |
导出Parquet |
| loadJSON |
导入JSON |
| saveJSON |
导出JSON |
二、CSV文件操作
2.1 导入CSV
// 基本导入
t = loadText("/data/sensor_data.csv")
// 指定分隔符
t = loadText("/data/sensor_data.csv", delimiter=',')
// 指定表结构
schema = table(
`device_id`timestamp`temperature`humidity as colNames,
[INT, DATETIME, DOUBLE, DOUBLE] as colTypes
)
t = loadText("/data/sensor_data.csv", schema=schema)
// 跳过标题行
t = loadText("/data/sensor_data.csv", skipRows=1)
// 指定日期格式
t = loadText("/data/sensor_data.csv", dateFormat="yyyy-MM-dd HH:mm:ss")
2.2 导出CSV
// 创建测试数据
t = table(
1..100 as device_id,
2024.01.01 + 0..99 as date,
rand(20.0..30.0, 100) as temperature,
rand(40.0..60.0, 100) as humidity
)
// 导出CSV
saveText(t, "/output/sensor_data.csv")
// 指定分隔符
saveText(t, "/output/sensor_data.csv", delimiter=',')
// 追加模式
saveText(t, "/output/sensor_data.csv", mode='a')
// 不包含列名
saveText(t, "/output/sensor_data.csv", header=false)
2.3 大文件导入
// 分批导入大文件
def importLargeCSV(filePath, batchSize=100000) {
result = table(1:0, `device_id`timestamp`temperature`humidity,
[INT, TIMESTAMP, DOUBLE, DOUBLE])
// 使用ploadText并行加载
data = ploadText(filePath)
result.append!(data)
return result
}
// 导入到分布式表
db = database("dfs://iot_data", VALUE, 2024.01.01..2024.12.31)
loadTextEx(db, "sensor_data", "/data/sensor_data.csv", `timestamp)
2.4 CSV导入实战
// 完整的CSV导入流程
def importSensorData(csvPath, dbPath) {
// 1. 定义表结构
schema = table(
`device_id`timestamp`temperature`humidity`pressure`status as colNames,
[INT, DATETIME, DOUBLE, DOUBLE, DOUBLE, SYMBOL] as colTypes
)
// 2. 导入数据
t = loadText(csvPath, schema=schema, dateFormat="yyyy-MM-dd HH:mm:ss")
// 3. 数据清洗
t = select * from t
where temperature between -40 and 100
and humidity between 0 and 100
// 4. 写入分布式表
db = database(dbPath)
loadTable(db, "sensor_data").append!(t)
return t.rows()
}
// 执行导入
importSensorData("/data/sensors.csv", "dfs://iot_data")
三、JSON文件操作
3.1 导入JSON
// 导入JSON文件
t = loadJSON("/data/sensor_data.json")
// 解析JSON字符串
jsonStr = '{"device_id":1,"temperature":25.5,"humidity":50.0}'
data = parseJson(jsonStr)
// 解析JSON数组
jsonArr = '[{"id":1,"value":10},{"id":2,"value":20}]'
t = parseJson(jsonArr)
3.2 导出JSON
// 创建测试数据
t = table(
1..5 as device_id,
`A`B`C`D`E as name,
10.0 20.0 30.0 40.0 50.0 as value
)
// 导出JSON
saveJSON(t, "/output/sensor_data.json")
// 格式化输出
saveJSON(t, "/output/sensor_data_pretty.json", pretty=true)
3.3 嵌套JSON处理
// 处理嵌套JSON
nestedJson = '{
"device": {
"id": 1,
"name": "sensor_001"
},
"data": {
"temperature": 25.5,
"humidity": 50.0
}
}'
// 解析嵌套结构
data = parseJson(nestedJson)
device_id = data.device.id
temperature = data.data.temperature
四、Parquet文件操作
4.1 导入Parquet
// 导入Parquet文件
t = loadParquet("/data/sensor_data.parquet")
// 指定列
t = loadParquet("/data/sensor_data.parquet",
columns=`device_id`timestamp`temperature)
// 导入到分布式表
db = database("dfs://iot_data", VALUE, 2024.01.01..2024.12.31)
loadParquetEx(db, "sensor_data", "/data/sensor_data.parquet", `timestamp)
4.2 导出Parquet
// 创建测试数据
t = table(
1..10000 as device_id,
take(2024.01.01..2024.01.10, 10000) as date,
rand(20.0..30.0, 10000) as temperature,
rand(40.0..60.0, 10000) as humidity
)
// 导出Parquet
saveParquet(t, "/output/sensor_data.parquet")
// 指定压缩
saveParquet(t, "/output/sensor_data.parquet", compression="snappy")
4.3 Parquet优势
| 特性 |
说明 |
| 列式存储 |
高效压缩、快速查询 |
| 压缩率高 |
比CSV小5-10倍 |
| 读取快 |
只读取需要的列 |
| 跨平台 |
Spark、Hive等支持 |
五、数据库同步
5.1 MySQL同步
// 加载MySQL插件
loadPlugin("/plugins/mysql/libPluginMySQL.so")
// 连接MySQL
conn = mysql::connect("localhost", 3306, "root", "password", "iot_db")
// 导入MySQL表
t = mysql::loadTable(conn, "sensor_data")
// 导入查询结果
t = mysql::query(conn, "SELECT * FROM sensor_data WHERE date >= '2024-01-01'")
// 写入MySQL
mysql::saveTable(conn, t, "sensor_data_backup")
5.2 PostgreSQL同步
// 加载PostgreSQL插件
loadPlugin("/plugins/odbc/libPluginODBC.so")
// 连接PostgreSQL
conn = odbc::connect("Driver={PostgreSQL};Server=localhost;Port=5432;Database=iot_db;",
"postgres", "password")
// 导入数据
t = odbc::query(conn, "SELECT * FROM sensor_data")
// 写入数据
odbc::execute(conn, "INSERT INTO sensor_data VALUES (1, '2024-01-15', 25.5, 50.0)")
六、批量导入导出
6.1 批量导入
// 批量导入目录下所有CSV
def batchImportCSV(dirPath, dbPath, tableName) {
files = dir(dirPath, "*.csv")
db = database(dbPath)
for (file in files) {
print("导入: " + file)
t = loadText(dirPath + "/" + file)
loadTable(db, tableName).append!(t)
}
return size(files)
}
// 执行批量导入
batchImportCSV("/data/sensors/", "dfs://iot_data", "sensor_data")
6.2 定时同步
// 定时同步任务
def syncData() {
// 从源数据库同步
source = mysql::loadTable(mysql_conn, "sensor_data")
// 写入DolphinDB
loadTable("dfs://iot_data", "sensor_data").append!(source)
print("同步完成: " + now())
}
// 每小时同步
scheduleJob("sync_sensor", "传感器数据同步", syncData,
00:00, 2024.01.01, 2030.12.31, 'H')
七、数据格式转换
7.1 格式转换
// CSV转Parquet
def csvToParquet(csvPath, parquetPath) {
t = loadText(csvPath)
saveParquet(t, parquetPath)
}
// Parquet转CSV
def parquetToCSV(parquetPath, csvPath) {
t = loadParquet(parquetPath)
saveText(t, csvPath)
}
// JSON转Parquet
def jsonToParquet(jsonPath, parquetPath) {
t = loadJSON(jsonPath)
saveParquet(t, parquetPath)
}
7.2 数据清洗
// 导入时清洗数据
def importAndClean(filePath) {
// 导入
t = loadText(filePath)
// 清洗
t = select * from t
where temperature is not null
and temperature between -40 and 100
and humidity between 0 and 100
// 转换
t[`timestamp] = temporalParse(t.timestamp, "yyyy-MM-dd HH:mm:ss")
return t
}
八、性能优化
8.1 导入优化
| 优化项 |
说明 |
| 批量导入 |
减少IO次数 |
| 并行导入 |
ploadText并行加载 |
| 预分配 |
设置初始容量 |
| 分区导入 |
loadTextEx直接导入分区 |
8.2 导出优化
| 优化项 |
说明 |
| 列裁剪 |
只导出需要的列 |
| 压缩存储 |
Parquet压缩 |
| 分区导出 |
按分区导出 |
8.3 性能对比
| 格式 |
导入速度 |
导出速度 |
存储空间 |
| CSV |
中 |
快 |
大 |
| JSON |
慢 |
中 |
大 |
| Parquet |
快 |
快 |
小 |
九、总结
本文系统介绍了DolphinDB数据导入导出:
- CSV操作:导入、导出、大文件处理
- JSON操作:导入、导出、嵌套处理
- Parquet操作:导入、导出、优势分析
- 数据库同步:MySQL、PostgreSQL
- 批量处理:批量导入、定时同步
- 格式转换:CSV/JSON/Parquet互转
- 性能优化:导入导出优化
思考题:
- 如何选择合适的数据格式?
- 大文件导入如何优化?
- 如何实现增量数据同步?
参考资料