DuckDB to system zarządzania bazą danych SQL typu OLAP działający w trybie wewnątrzprocesowym. Posiada silne wsparcie dla SQL. DuckDB opiera się na implementacji powłoki SQLite. Każda baza danych jest pojedynczym plikiem na dysku. Można go porównać do “SQLite dla obciążeń analitycznych (OLAP)” (bezpośrednie porównanie w artykule Porównanie SQLite i DuckDB tutaj), podczas gdy SQLite jest przeznaczony dla obciążeń OLTP. Jednak DuckDB może obsługiwać ogromne ilości danych lokalnie. Jest to mniejsza, lżejsza wersja Apache Druid i innych technologii OLAP.

Jest zaprojektowany do pracy jako biblioteka osadzona, eliminując opóźnienia sieciowe, które zazwyczaj występują podczas komunikacji z bazą danych.

Zastąp pracę z podatnymi na błędy plikami Excela lub CSV

Dzięki DuckDB nie musimy już korzystać bezpośrednio z plików zwykłych (CSV, Excel, Parquet). DuckDB obsługuje schemat, typy i interfejs SQL, jest także bardzo szybki.

Zastosowania

  • Bardzo szybki przypadek użycia analitycznego lokalnie. Na przykład przykład z taksówką obejmuje przykład danych o taksówkach z ostatnich 10 lat, zawierający 1,5 miliarda wierszy, który nadal działa na laptopie. Patrz poniżej dla wyników testów wydajnościowych.
  • Można go używać jako osłonę SQL z zerowymi kopiowaniami (na wierzchu plików Parquet w S3).
  • Przynoszenie danych do użytkowników zamiast przeprowadzania dużych cykli komunikacji i opóźnień za pomocą wywołań REST. Zamiast tego dane można umieścić wewnątrz klienta. Można osiągnąć 60 klatek na sekundę, ponieważ dane znajdują się tam, gdzie jest zapytanie.
  • DuckDB na platformie Kubernetes jako warstwa zerowego kopiowania do odczytywania danych z S3 w Jeziorze Danych! Inspirowane tym wpisem na Twitterze. Najtańsza i najszybsza opcja rozpoczęcia pracy.

Sprawdź Rill Data, narzędzie BI, które zapewnia interaktywność w czasie poniżej sekundy, ponieważ jest oparte na DuckDB (a także Druid dla usług chmurowych na poziomie przedsiębiorstwa).

MotherDuck to usługa zarządzana wokół DuckDB, która pozwala na skalowanie od lokalnej bazy danych do bazy danych w chmurze i hybrydowej — stworzona przez jednego z twórców Google BigQuery, takich jak Jordan Tigani. Zapoznaj się z jego dyskusją w Podcaście Inżynierii Analitycznej na temat Osobistej Hurtowni Danych. Ożywiająca

rozmowa na temat powiązanych technologii WebAssembly, np. jest to aplikacja skompilowana do kodu C, który jest bardzo szybki. Na przykład Figma korzysta z tego, co w przeciwnym razie nigdy nie działałoby w przeglądarce.

Testy wydajnościowe

Projekty przykładowe

Technologia i Publikacje

DuckDB jest dostarczany jako budowa amalgamation - pojedynczy ogromny plik C++ (SQLite to pojedynczy ogromny plik C). Oprócz tego opiera się na solidnych podstawach naukowych. Został stworzony przez badaczy akademickich odpowiedzialnych za MonetDB i zawiera implementacje kilku interesujących publikacji:

Z artykułu Dlaczego DuckDB:

DuckDB zawiera kolumnowy silnik wykonywania zapytań, w którym zapytania są wciąż interpretowane, ale duży pakiet wartości („wektor”) jest przetwarzany za jednym razem. To dramatycznie zmniejsza narzut w tradycyjnych systemach takich jak PostgreSQL, MySQL czy SQLite, które przetwarzają każdy wiersz sekwencyjnie. Wykonywanie zapytań wektorowych prowadzi do znacznie lepszej wydajności w zapytaniach OLAP.

Interfejs Pythona i Obsługa Danych

Z dokumentacji DuckDB - Python API:

Pobieranie danych za pomocą SQL

# pobierz jako ramka danych pandas
df = con.execute("SELECT * FROM items").fetchdf()
print(df)
#        item   value  count
# 0     jeans    20.0      1
# 1    hammer    42.2      2
# 2    laptop  2000.0      1
# 3  chainsaw   500.0     10
# 4    iphone   300.0      2
 
# pobierz jako słownik tablic numpy
arr = con.execute("SELECT * FROM items").fetchnumpy()
print(arr)
# {'item': masked_array(data=['jeans', 'hammer', 'laptop', 'chainsaw', 'iphone'],
#              mask=[False, False, False, False, False],
#        fill_value='?',
#             dtype=object), 'value': masked_array(data=[20.0, 42.2, 2000.0, 500.0, 300.0],
#              mask=[False, False, False, False, False],
#        fill_value=1e+20), 'count': masked_array(data=[1, 2, 1, 10, 2],
#              mask=[False, False, False, False, False],
#        fill_value=999999,
#             dtype=int32)}

Tworzenie tabeli

# utwórz tabelę
con.execute("CREATE TABLE items(item VARCHAR, value DECIMAL(10,2), count INTEGER)")
# wstaw dwa elementy do tabeli
con.execute("INSERT INTO items VALUES ('jeans', 20.0, 1), ('hammer', 42.2, 2)")
 
# pobierz elementy ponownie
con.execute("SELECT * FROM items")
print(con.fetchall())
# [('jeans', 20.0, 1), ('hammer', 42.2, 2)]

Wstawianie danych

# wstaw wiersz za pomocą instrukcji przy
 
gotowanej
con.execute("INSERT INTO items VALUES (?, ?, ?)", ['laptop', 2000, 1])
 
# wstaw wiele wierszy za pomocą instrukcji przygotowanej
con.executemany("INSERT INTO items VALUES (?, ?, ?)", [['chainsaw', 500, 10], ['iphone', 300, 2]] )
 
# zapytaj bazę danych za pomocą instrukcji przygotowanej
con.execute("SELECT item FROM items WHERE value > ?", [400])
print(con.fetchall())
# [('laptop',), ('chainsaw',)]