duckdb

R语言
sql
python
作者

不止BI

发布于

2024年3月1日

DuckDB 是一款开源的列式关系数据库管理系统 (RDBMS),由荷兰 Centrum Wiskunde & Informatica (CWI) 的 Mark Raasveldt 和 Hannes Mühleisen 开发,于 2019 年首次发布。

DuckDB 的设计目标是快速、可靠、可移植且易于使用。它提供了一套丰富的 SQL 方言,支持远超基本 SQL 的功能。

DuckDB 的特点

  • 高性能: DuckDB 采用列式存储引擎,并支持并行执行,因此能够以极快的速度处理分析查询,即使是处理超过内存大小的数据集也能够游刃有余。

  • 易于使用: DuckDB 提供了标准的 SQL 语法,使其易于学习和使用。即使是 SQL 初学者也能快速上手。

  • 可移植: DuckDB 没有任何外部依赖项,只需要 C++11 编译器即可构建,因此具有很强的可移植性。它可以在各种操作系统和平台上运行,包括 Linux、macOS、Windows、Android 和 iOS。

  • 可靠: DuckDB 经过严格的测试,并得到社区的广泛支持,因此非常可靠。

在R中使用

写入数据表

代码
library(duckdb)
library(dplyr)
con_duck <- DBI::dbConnect(duckdb(), path = ":memory:")

# # 将数据存在数据库文件(只读,共享不进程)
# con <- dbConnect(duckdb(), dbdir = "my-db.duckdb", read_only = FALSE)
# # 进程共享
# con <- dbConnect(duckdb(), dbdir = "my-db.duckdb", read_only = TRUE)



dbiris <- copy_to(con_duck, iris, overwrite = TRUE)
代码
select * from iris
Displaying records 1 - 10
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
4.6 3.4 1.4 0.3 setosa
5.0 3.4 1.5 0.2 setosa
4.4 2.9 1.4 0.2 setosa
4.9 3.1 1.5 0.1 setosa

数据操作

在R中,duckdb同时支持sql语法查询与dplyr语法查询

数据查询

代码
select t.Species,max(t."Sepal.Length") SepalLengthMax
from iris t
group by t.Species
3 records
Species SepalLengthMax
setosa 5.8
versicolor 7.0
virginica 7.9
代码
dbiris %>%
  group_by(Species) %>%
  summarise(Sepal.Length.MAX = max(Sepal.Length)) %>%
  as_tibble()
# A tibble: 3 × 2
  Species    Sepal.Length.MAX
  <fct>                 <dbl>
1 setosa                  5.8
2 versicolor              7  
3 virginica               7.9

直接查询文件

代码
write.csv(iris,'./t.csv')
dbGetQuery(con_duck,statement = "select * from t.csv limit 10")
   column0 Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1        1          5.1         3.5          1.4         0.2  setosa
2        2          4.9         3.0          1.4         0.2  setosa
3        3          4.7         3.2          1.3         0.2  setosa
4        4          4.6         3.1          1.5         0.2  setosa
5        5          5.0         3.6          1.4         0.2  setosa
6        6          5.4         3.9          1.7         0.4  setosa
7        7          4.6         3.4          1.4         0.3  setosa
8        8          5.0         3.4          1.5         0.2  setosa
9        9          4.4         2.9          1.4         0.2  setosa
10      10          4.9         3.1          1.5         0.1  setosa

清空数据

代码
truncate iris 

在python中使用

创建数据库

代码
import duckdb
con = duckdb.connect("pyduck.db")

写入数据

代码
con.sql("drop table if exists test ")
con.sql("CREATE TABLE test (i INTEGER)")
con.sql("INSERT INTO test VALUES (42)")
con.table("test").show()
┌───────┐
│   i   │
│ int32 │
├───────┤
│    42 │
└───────┘
代码
con.close()

数据操作

通过sql语句可以直接查询目录下的文件

代码
duckdb.sql("SELECT * from t.csv where Species  = 'setosa'")
┌─────────┬──────────────┬─────────────┬──────────────┬─────────────┬─────────┐
│ column0 │ Sepal.Length │ Sepal.Width │ Petal.Length │ Petal.Width │ Species │
│  int64  │    double    │   double    │    double    │   double    │ varchar │
├─────────┼──────────────┼─────────────┼──────────────┼─────────────┼─────────┤
│       1 │          5.1 │         3.5 │          1.4 │         0.2 │ setosa  │
│       2 │          4.9 │         3.0 │          1.4 │         0.2 │ setosa  │
│       3 │          4.7 │         3.2 │          1.3 │         0.2 │ setosa  │
│       4 │          4.6 │         3.1 │          1.5 │         0.2 │ setosa  │
│       5 │          5.0 │         3.6 │          1.4 │         0.2 │ setosa  │
│       6 │          5.4 │         3.9 │          1.7 │         0.4 │ setosa  │
│       7 │          4.6 │         3.4 │          1.4 │         0.3 │ setosa  │
│       8 │          5.0 │         3.4 │          1.5 │         0.2 │ setosa  │
│       9 │          4.4 │         2.9 │          1.4 │         0.2 │ setosa  │
│      10 │          4.9 │         3.1 │          1.5 │         0.1 │ setosa  │
│       · │           ·  │          ·  │           ·  │          ·  │   ·     │
│       · │           ·  │          ·  │           ·  │          ·  │   ·     │
│       · │           ·  │          ·  │           ·  │          ·  │   ·     │
│      41 │          5.0 │         3.5 │          1.3 │         0.3 │ setosa  │
│      42 │          4.5 │         2.3 │          1.3 │         0.3 │ setosa  │
│      43 │          4.4 │         3.2 │          1.3 │         0.2 │ setosa  │
│      44 │          5.0 │         3.5 │          1.6 │         0.6 │ setosa  │
│      45 │          5.1 │         3.8 │          1.9 │         0.4 │ setosa  │
│      46 │          4.8 │         3.0 │          1.4 │         0.3 │ setosa  │
│      47 │          5.1 │         3.8 │          1.6 │         0.2 │ setosa  │
│      48 │          4.6 │         3.2 │          1.4 │         0.2 │ setosa  │
│      49 │          5.3 │         3.7 │          1.5 │         0.2 │ setosa  │
│      50 │          5.0 │         3.3 │          1.4 │         0.2 │ setosa  │
├─────────┴──────────────┴─────────────┴──────────────┴─────────────┴─────────┤
│ 50 rows (20 shown)                                                6 columns │
└─────────────────────────────────────────────────────────────────────────────┘

通过read_*方法查询文件目录下的问及那,支持read_parquetread_csvread_json

代码
t = duckdb.read_csv("t.csv")            

通过sql直接查询数据框数据,支持pandasPolarsArrowspark等,通过对应的方法可以将查询的结果直接转为对应的数据结构

代码
import pandas as pd
test_df = pd.DataFrame.from_dict({"i": [1, 2, 3, 4], "j": ["one", "two", "three", "four"]})
t = duckdb.sql("SELECT * FROM test_df").df()
t
   i      j
0  1    one
1  2    two
2  3  three
3  4   four
代码
duckdb.sql("SELECT * FROM test_df").arrow()
pyarrow.Table
i: int64
j: string
----
i: [[1,2,3,4]]
j: [["one","two","three","four"]]
代码
duckdb.sql("SELECT * FROM test_df").pl()
shape: (4, 2)
i j
i64 str
1 "one"
2 "two"
3 "three"
4 "four"
回到顶部