+ - 0:00:00
Notes for current slide
Notes for next slide

DuckDB 学习笔记

吴诗涛

2024-05-28

1 / 14

DuckDB 介绍

2 / 14

什么是 DuckDB

DuckDB 是一种高性能、内嵌的 SQL OLAP 数据库管理系统,旨在处理分析查询。它具有以下特点:1

  1. 简单易用:无需外部依赖,支持在应用内运行或作为单一二进制文件运行。
  2. 跨平台:支持 Linux、macOS 和 Windows 等主流操作系统。
  3. 功能丰富:支持读取和写入 CSV、Parquet、JSON 等文件格式,支持本地文件系统和远程端点(如 S3)。
  4. 高性能:通过列式存储引擎实现快速查询,支持并行执行和超内存工作负载。
  5. 可扩展:支持第三方扩展,如新的数据类型、函数和文件格式。
3 / 14

使用方法一:DuckDB + SQL

这种方法相对简单,把数据存入 DuckDB 数据库后,用 SQL 查询即可。

4 / 14

创建 DuckDB 数据库

# install.packages("duckdb")
library(duckdb)
# 创建 DuckDB 连接,同时会在本地创建 local.duckdb 文件
con = dbConnect(duckdb(), dbdir = "local.duckdb")
5 / 14

向 DuckDB 数据库写入表

可以将 R 中的数据框写入到 DuckDB 数据库中:

# 写入 R 中的数据框
dbWriteTable(con, "table_iris", iris)
dbWriteTable(con, "table_mtcars", mtcars)
dbListTables(con)
#> [1] "table_iris" "table_mtcars"
6 / 14

向 DuckDB 数据库写入表

可以将 R 中的数据框写入到 DuckDB 数据库中:

# 写入 R 中的数据框
dbWriteTable(con, "table_iris", iris)
dbWriteTable(con, "table_mtcars", mtcars)
dbListTables(con)
#> [1] "table_iris" "table_mtcars"

也可以将本地的文件直接导入到 DuckDB 数据库中,这个方法可以突破内存大小的限制:

# 创建本地 CSV 文件
data.frame(
Species = c("setosa", "versicolor", "virginica"),
code = LETTERS[1:3]
) |> write.csv("species_code.csv", row.names = FALSE)
# 将本地 CSV 文件直接导入 DuckDB
duckdb_read_csv(con, "table_code", "species_code.csv")
dbListTables(con)
#> [1] "table_code" "table_iris" "table_mtcars"
6 / 14

从 DuckDB 数据库删除表

dbRemoveTable(con, "table_mtcars")
dbListTables(con)
#> [1] "table_code" "table_iris"
7 / 14

从 DuckDB 数据库删除表

dbRemoveTable(con, "table_mtcars")
dbListTables(con)
#> [1] "table_code" "table_iris"

使用 SQL 查询 DuckDB 数据库

dbGetQuery(con, "SELECT * FROM table_iris LIMIT 3;")
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 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
7 / 14

使用 SQL 查询 DuckDB 数据库

dbGetQuery(con, "SELECT Species, COUNT(*) AS n
FROM table_iris
GROUP BY Species
ORDER BY n;")
#> Species n
#> 1 setosa 50
#> 2 versicolor 50
#> 3 virginica 50
# 表连接
dbGetQuery(con, "SELECT a.Species, code, n FROM
(
SELECT Species, COUNT(*) AS n
FROM table_iris
GROUP BY Species
) a
LEFT JOIN table_code b
ON a.Species = b.Species;")
#> Species code n
#> 1 setosa A 50
#> 2 versicolor B 50
#> 3 virginica C 50
8 / 14

断开 DuckDB 连接

# 断开数据库连接
dbDisconnect(con)
9 / 14

使用方法二:duckplyr

10 / 14

加载 duckplyr 和 dplyr

# install.packages("duckplyr")
library(duckplyr)
library(dplyr)
con = dbConnect(duckdb(), dbdir = "local.duckdb")

从 DuckDB 创建数据源

使用 tbl() 连接 DuckDB 数据库中的表,可以看到表的行数是 ??,因为 duckplyr 采用惰性计算,只是生成了查询计划,并没有实际执行。

table_iris = tbl(con, "table_iris")
table_iris
#> # Source: table<table_iris> [?? x 5]
#> # Database: DuckDB v0.10.2 [unknown@Linux 5.15.0-107-generic:R 4.4.0//home/shitao/git/shitao-blog/static/slides/duckdb/local.duckdb]
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <dbl> <dbl> <dbl> <dbl> <fct>
#> 1 5.1 3.5 1.4 0.2 setosa
#> 2 4.9 3 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 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 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
#> # ℹ more rows
11 / 14

使用管道操作数据

现在就可以和平常的数据一样进行分析了,要得到最终执行结果,需在管道最后接上 collect()

table_iris |>
count(Species) |>
collect()
#> # A tibble: 3 × 2
#> Species n
#> <fct> <dbl>
#> 1 setosa 50
#> 2 versicolor 50
#> 3 virginica 50
table_code = tbl(con, "table_code")
table_iris |>
count(Species) |>
left_join(table_code, join_by(Species)) |>
select(Species, code, n) |>
collect()
#> # A tibble: 3 × 3
#> Species code n
#> <fct> <chr> <dbl>
#> 1 setosa A 50
#> 2 versicolor B 50
#> 3 virginica C 50
12 / 14

断开 DuckDB 连接

数据库用完,记得断开连接哦!

# 断开数据库连接
dbDisconnect(con)
13 / 14

🚀🚀🚀

14 / 14

DuckDB 介绍

2 / 14
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow