duckdb数据库操作
和sqlite对比主要的区别就是duckdb是按列存储,并且数据文件有压缩。在数据分析领域比sqlite有优势
//批量插入,速度快
DuckDBConnection cn = new DuckDBConnection(@"Data Source=E:\tmp\duckdb2.db");
//DuckDBConnection connection = new DuckDBConnection("Data Source=:memory:")) //内存数据库
cn.Open();
using (DuckDBAppender appender = cn.CreateAppender("t1")) //数据库表名t1
{
for (int i = 10; i <= 10000; i++)
{
// 开始新行
IDuckDBAppenderRow row = appender.CreateRow(); //.app.AppendRow();
// 添加列值(必须按表定义的顺序)
row.AppendValue(i); // id
row.AppendValue($"中国人:{i}"); // location
// 结束行
row.EndRow();
}
appender.Close();
}
cn.Close();
//查询数据
DuckDBConnection cn = new DuckDBConnection(@"Data Source=E:\tmp\duckdb2.db");
cn.Open();
string msg = "";
DataTable dt = new DataTable();
string querySQL = @" SELECT * FROM t1 ";
using (var command = new DuckDBCommand(querySQL, cn))
using (var reader = command.ExecuteReader())
{
dt.Load(reader); //没有Adapter的fill,可用load写到DataTable
while (reader.Read())
{
int id = reader.GetInt32(0);
string name = reader.GetString(1);
msg += $"{id},{name}/";
}
}
this.textBox1.Text = msg;
this.dataGridView1.DataSource = dt;
cn.Close();
//更新
未实际Adapter的fill,故无法对DataTable做update操作
duckdb真是个宝藏数据库:
1. 100G的mysql备份文件(.sql文本文件)恢复到duckdb后点1个G,恢复到sqlserver中点4.8g,恢复到mysql中要103g(没错,比sql文件还要大点, mysq5.4)。恢复到firebird5中占5G。duck行存储结构压缩率高。
2. 3千万数据按id查秒出,按非索引字段查询也秒出
3. 写入速度快,用IDuckDBAppenderRow 批量插入每秒能写入5万行以上
4. 查询速度快,查询5万行在1s左右。在写入firebird时1万条需20s(改到ssd硬盘后写入1万条2s),duck的批量写入速度和sqlserver的批量写入差不多
5. 更新速度和行插入速度未测试,美中不足是驱动没有实现Adapter类
6. 可以并发读,但不要并发写入和更新。
7. 并发读时在测试时使用同一个connection时偶尔会出错,但不同读操作使用不同的connection时不出错,即不同读的线程分别创建DuckDBConnection (在不同进程分别open连接时测试出错)。经测试创建连接后open和close操作共需耗时给15ms
8. 需要安装VC_redist.x64 (vc2015-2019)库
9. 在写入时频繁Open和Close数据库会多占用大量空间,数据库文件会增大10到100倍以上。
2026年2月9日
浙公网安备 33010602011771号