duckdb: 一個超火的數據庫,背後公司只有 18 人?
簡介
DuckDB 是一個嵌入式、內存中、SQL OLAP 數據庫管理系統。它提供了一種高效的方式來查詢和分析數據, 可以被集成到各種應用程序或編程語言中。
最近非常的 🔥,一個月下載超過 200 萬次。實際上,這家位於荷蘭阿姆斯特丹的小型公司只有 18 人,下面這篇公衆號介紹了它的背景:震驚:開發一款世界矚目的數據庫僅需 18 人。這讓我想起了 clickhous。duckdb 的簡單易用、提供了便利的方法、功能強大讓它朝着成功邁進。
它的名字來自於創始人的寵物鴨子。
DuckDB 的主要特點包括:
-
嵌入式: DuckDB 可以作爲一個庫集成到應用程序中, 而不需要單獨的服務器進程。這使得它特別適合於嵌入式系統、物聯網設備和 Edge 計算場景。
-
內存中: DuckDB 將數據加載到內存中進行查詢, 這使得它在查詢速度和並行性能方面表現出色。對於中小型數據集, DuckDB 可以提供接近原生查詢速度。
-
SQL 兼容性: DuckDB 支持標準的 SQL 語言, 包括大部分 SQL 語句和函數。它旨在提供高度的 SQL 兼容性, 使遷移和集成變得更加容易。
-
矢量化執行: DuckDB 採用了矢量化執行模型, 可以有效利用現代 CPU 的 SIMD 指令集, 從而提高查詢性能。
-
數據格式支持: 除了內置的行 Store 和列 Store,DuckDB 還支持直接查詢常見的文件格式, 如 CSV、Parquet、JSONL 等。
-
查詢優化器: DuckDB 內置了成本模型驅動的查詢優化器, 能夠生成高效的執行計劃。
-
可擴展性: DuckDB 支持通過插件擴展自定義函數和數據格式, 使其能夠更好地適應特定的應用場景。
-
多平臺支持: DuckDB 可以在多種操作系統和硬件架構上運行, 包括 Linux、Windows、macOS、ARM 等。
DuckDB 可以應用於許多場景, 如數據分析、ETL、機器學習特徵工程等。它可以作爲獨立的數據庫系統使用, 也可以集成到各種應用程序中, 爲高性能的數據處理和分析提供支持。
安裝
官方提供了多種環境的部署方式,不管是獨立程序還是作爲編程語言的庫。Mac/Linux/Windows 那是必須的,常見語言也有相應額度庫。
比如 Go 語言:
go get github.com/marcboeker/go-duckdb
package main
import (
"database/sql"
"fmt"
_ "github.com/marcboeker/go-duckdb"
)
func main() {
// 一個內存庫
db, _ := sql.Open("duckdb", "")
// 創建表
db.Exec(`CREATE TABLE person (id INTEGER, name VARCHAR)`)
// 插入測試數據
db.Exec(`INSERT INTO person VALUES (42, 'John')`)
// 查詢數據
var (
id int
name string
)
row := db.QueryRow(`SELECT id, name FROM person`)
_ = row.Scan(&id, &name)
fmt.Println("id:", id, "name:", name)
}
也可以部署獨立程序,比如在 Mac 上:
brew install duckdb
啓動duckdb
:
duckdb
官方文檔 [1] 提供了容易閱讀,全面的資料, 我在這裏就不進行翻譯。官方的文檔還是很詳細的,而且文檔組織的也是超一流的,方便查找和閱讀。
擴展
duckdb 還提供了很多的擴展,比如從 Mysql、Postgres、SQLite 中讀取數據,又比如下面這個 inet 提供了 Ip 地址數據類型:
INSTALL inet;
LOAD inet;
SELECT '127.0.0.1'::INET AS ipv4, '2001:db8:3c4d::/48'::INET AS ipv6;
CREATE TABLE tbl (id INTEGER, ip INET);
INSERT INTO tbl VALUES
(1, '192.168.0.0/16'),
(2, '127.0.0.1'),
(3, '8.8.8.8'),
(4, 'fe80::/10'),
(5, '2001:db8:3c4d:15::1a2f:1a2b');
SELECT * FROM tbl;
接下來,我們以一個 IP 地理信息庫爲例,看看怎麼從 IP 地址查詢國家信息和城市信息。
實戰:IP 地理信息庫
IP 地理信息庫文件
IP 地理位置數據庫 世界城鎮擴展版 2021-11-08 | eMule Fans 電騾愛好者 [2] 網站提供了免費的 IP 地址世界城鎮庫以及 IP 地址中國城鎮庫。我們以世界城鎮庫爲例。
wget -o ip-to-country_csv.city.zip https://github.com/emulefanscom/ip2c/releases/download/2021-11-08/ip-to-country_csv.city.zip
unzip ip-to-country_csv.city.zip
解壓開的文件大小爲 231 MB, CSV 格式的文件:
# ls
total 557344
-rw-r--r--@ 1 smallnest staff 231M 11 10 2021 ip-to-country.csv
-rw-r--r--@ 1 smallnest staff 34M 12 7 2021 ip-to-country_csv.city.zip
從 CSV 文件中進行加載
我們下載的 IP 庫文件中的數據格式如下,第一列是起始IP
, 第二列是結束IP
, 第三列是國家代碼(2碼)
,第四列是國家名稱(3碼)
,第五列是城市名稱-省名稱-國家名稱
, 沒有 header。
"16777216","16777471","AU","AUS","South Brisbane - Queensland - Australia"
"16777472","16778239","CN","CHN","Qingzhou - Fujian - China"
"16778240","16779263","AU","AUS","Narre Warren - Victoria - Australia"
"16779264","16781311","CN","CHN","Guangzhou Shi - Guangdong - China"
"16781312","16785407","JP","JPN","Shinjuku - Tokyo - Japan"
"16785408","16793599","CN","CHN","Guangzhou Shi - Guangdong - China"
"16793600","16793855","JP","JPN","Hiroshima - Hiroshima - Japan"
"16793856","16794111","JP","JPN","Hiroshima - Hiroshima - Japan"
"16794112","16794367","JP","JPN","Hiroshima - Hiroshima - Japan"
"16794368","16794623","JP","JPN","Hiroshima - Hiroshima - Japan"
使用 duckdb 的read_csv
函數從 CSV 文件中加載數據到表中 (read_csv_auto
可以自動解析 csv,猜測數據類型和 header, 不過函數已經棄用了,可以使用功能更強大的read_csv
)。注意因爲數據文件沒有 header,所以 1 這裏需要指定列名,否則會自動生成列名,而且我們指定了列的數據類型。
create table ip2country AS SELECT * FROM read_csv('ip-to-country.csv',
header = false,
columns = {
ip_start: 'INT64',
ip_end: 'INT64',
country_tld: 'VARCHAR',
country_code: 'VARCHAR',
country_name: 'VARCHAR'
}
);
從文件中加載還是飛快的,幾乎在 1 秒之內就加載完了。不知道是真的加載到內存中了還是僞加載。
接下來我們就可以使用這個數據庫進行分析了,比如我們查詢 8.8.8.8
這個 IP:
select * from ip2country where (
SELECT (
CAST(SPLIT_PART(ipv4, '.', 1) AS INT64) * 16777216 +
CAST(SPLIT_PART(ipv4, '.', 2) AS INT64) * 65536 +
CAST(SPLIT_PART(ipv4, '.', 3) AS INT64) * 256 +
CAST(SPLIT_PART(ipv4, '.', 4) AS INT64)
) AS int_ip
FROM (
SELECT '8.8.8.8' AS ipv4
)
)
between ip_start and ip_end;
因爲 duckdb 沒有函數把 ip 轉換成整數的函數,前面提到的 inet 插件也不行,所以我們通過 sql 語句來轉換。查詢出來的這個 IP 顯示它位於美國加州山景城,也就是谷歌的所在地:
接下來查詢一個我廠的 dns 服務器的 ip 地址看看:
select * from ip2country where (
SELECT (
CAST(SPLIT_PART(ipv4, '.', 1) AS INT64) * 16777216 +
CAST(SPLIT_PART(ipv4, '.', 2) AS INT64) * 65536 +
CAST(SPLIT_PART(ipv4, '.', 3) AS INT64) * 256 +
CAST(SPLIT_PART(ipv4, '.', 4) AS INT64)
) AS int_ip
FROM (
SELECT '180.76.76.76' AS ipv4
)
)
between ip_start and ip_end;
可以看到顯示這個 Ip 地址位於北京市:
參考資料
[1]
官方文檔: https://duckdb.org/docs/installation/index
[2]
Emulefans: https://www.emulefans.com/ip-to-country-city-20211108/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/aAgDibroCEk0UQAI2NtZxg