DuckDB PHP 客户端是第三方客户端,由第三方维护。
PHP 客户端 API。
该库专注于性能,内部通过FFI使用官方 C API,实现了良好的基准测试结果。它不仅仅是 C API 的封装,还引入了自定义的、对 PHP 友好的方法来简化 DuckDB 的使用。它兼容 Linux、Windows 和 macOS 操作系统,需要 PHP 8.3 或更高版本。
安装
composer require satur.io/duckdb
文档
完整文档可在https://duckdb-php.readthedocs.io/查阅。
快速开始
DuckDB::sql("SELECT 'quack' as my_column")->print();
-------------------
| my_column |
-------------------
| quack |
-------------------
我们在这里使用的函数DuckDB::sql()
在一个新的内存数据库中执行查询,该数据库在检索结果后销毁。
这并非最常见的用例,让我们看看如何获取持久连接。
连接
$duckDB = DuckDB::create('duck.db'); // or DuckDB::create() for in-memory database
$duckDB->query('CREATE TABLE test (i INTEGER, b BOOL, f FLOAT);');
$duckDB->query('INSERT INTO test VALUES (3, true, 1.1), (5, true, 1.2), (3, false, 1.1), (3, null, 1.2);');
$duckDB->query('SELECT * FROM test')->print();
正如您可能猜到的,DuckDB::create()
会创建到指定数据库的新连接;如果数据库尚不存在,则会先创建再建立连接。
之后,我们可以使用query
函数来执行请求。
请注意静态方法
sql
和非静态方法query
之间的区别。前者总是创建并销毁一个新的内存数据库,而后者则使用之前建立的连接,在大多数情况下应是首选。
此外,该库还提供预处理语句,用于将参数绑定到我们的查询中。
预处理语句
$duckDB = DuckDB::create();
$duckDB->query('CREATE TABLE test (i INTEGER, b BOOL, f FLOAT);');
$duckDB->query('INSERT INTO test VALUES (3, true, 1.1), (5, true, 1.2), (3, false, 1.1), (3, null, 1.2);');
$boolPreparedStatement = $duckDB->preparedStatement('SELECT * FROM test WHERE b = $1');
$boolPreparedStatement->bindParam(1, true);
$result = $boolPreparedStatement->execute();
$result->print();
$intPreparedStatement = $duckDB->preparedStatement('SELECT * FROM test WHERE i = ?');
$intPreparedStatement->bindParam(1, 3);
$result = $intPreparedStatement->execute();
$result->print();
追加器
追加器是 DuckDB 中加载数据的首选方法。有关更多信息,请参阅追加器页面。
$duckDB = DuckDB::create();
$result = $duckDB->query('CREATE TABLE people (id INTEGER, name VARCHAR);');
$appender = $duckDB->appender('people');
for ($i = 0; $i < 100; ++$i) {
$appender->append(rand(1, 100000));
$appender->append('string-'.rand(1, 100));
$appender->endRow();
}
$appender->flush();
DuckDB 的强大功能
DuckDB 提供了一些惊人的功能。例如,您可以直接查询远程文件。
让我们使用聚合函数计算 parquet 远程文件中某一列的平均值
DuckDB::sql(
'SELECT "Reporting Year", avg("Gas Produced, MCF") as "AVG Gas Produced"
FROM "https://github.com/plotly/datasets/raw/refs/heads/master/oil-and-gas.parquet"
WHERE "Reporting Year" BETWEEN 1985 AND 1990
GROUP BY "Reporting Year";'
)->print();
--------------------------------------
| Reporting Year | AVG Gas Produce |
--------------------------------------
| 1985 | 2461.4047344111 |
| 1986 | 6060.8575605681 |
| 1987 | 5047.5813074014 |
| 1988 | 4763.4090541633 |
| 1989 | 4175.2989758837 |
| 1990 | 3706.9404742437 |
--------------------------------------
或者汇总一个远程 CSV 文件
DuckDB::sql('SUMMARIZE TABLE "https://blobs.duckdb.org/data/Star_Trek-Season_1.csv";')->print();
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| column_name | column_type | min | max | approx_unique | avg | std | q25 | q50 | q75 | count | null_percentage |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| season_num | BIGINT | 1 | 1 | 1 | 1.0 | 0.0 | 1 | 1 | 1 | 30 | 0 |
| episode_num | BIGINT | 0 | 29 | 29 | 14.5 | 8.8034084308295 | 7 | 14 | 22 | 30 | 0 |
| aired_date | DATE | 1965-02-28 | 1967-04-13 | 35 | | | 1966-10-20 | 1966-12-22 | 1967-02-16 | 30 | 0 |
| cnt_kirk_hookup | BIGINT | 0 | 2 | 3 | 0.3333333333333 | 0.6064784348631 | 0 | 0 | 1 | 30 | 0 |
...
要求
- Linux、macOS 或 Windows
- x64 平台
- PHP >= 8.3
- ext-ffi
推荐
- ext-bcmath - 大整数(大于 PHP_INT_MAX)所需
- ext-zend-opcache - 提高性能
类型支持
从 1.2.0 版本开始,该库支持所有 DuckDB 文件类型。
DuckDB 类型 | SQL 类型 | PHP 类型 |
---|---|---|
DUCKDB_TYPE_BOOLEAN | BOOLEAN | bool |
DUCKDB_TYPE_TINYINT | TINYINT | int |
DUCKDB_TYPE_SMALLINT | SMALLINT | int |
DUCKDB_TYPE_INTEGER | INTEGER | int |
DUCKDB_TYPE_BIGINT | BIGINT | int |
DUCKDB_TYPE_UTINYINT | UTINYINT | int |
DUCKDB_TYPE_USMALLINT | USMALLINT | int |
DUCKDB_TYPE_UINTEGER | UINTEGER | int |
DUCKDB_TYPE_UBIGINT | UBIGINT | Saturio\DuckDB\Type\Math\LongInteger |
DUCKDB_TYPE_FLOAT | FLOAT | float |
DUCKDB_TYPE_DOUBLE | DOUBLE | float |
DUCKDB_TYPE_TIMESTAMP | TIMESTAMP | Saturio\DuckDB\Type\Timestamp |
DUCKDB_TYPE_DATE | DATE | Saturio\DuckDB\Type\Date |
DUCKDB_TYPE_TIME | TIME | Saturio\DuckDB\Type\Time |
DUCKDB_TYPE_INTERVAL | INTERVAL | Saturio\DuckDB\Type\Interval |
DUCKDB_TYPE_HUGEINT | HUGEINT | Saturio\DuckDB\Type\Math\LongInteger |
DUCKDB_TYPE_UHUGEINT | UHUGEINT | Saturio\DuckDB\Type\Math\LongInteger |
DUCKDB_TYPE_VARCHAR | VARCHAR | string |
DUCKDB_TYPE_BLOB | BLOB | Saturio\DuckDB\Type\Blob |
DUCKDB_TYPE_TIMESTAMP_S | TIMESTAMP_S | Saturio\DuckDB\Type\Timestamp |
DUCKDB_TYPE_TIMESTAMP_MS | TIMESTAMP_MS | Saturio\DuckDB\Type\Timestamp |
DUCKDB_TYPE_TIMESTAMP_NS | TIMESTAMP_NS | Saturio\DuckDB\Type\Timestamp |
DUCKDB_TYPE_UUID | UUID | Saturio\DuckDB\Type\UUID |
DUCKDB_TYPE_TIME_TZ | TIMETZ | Saturio\DuckDB\Type\Time |
DUCKDB_TYPE_TIMESTAMP_TZ | TIMESTAMPTZ | Saturio\DuckDB\Type\Timestamp |
DUCKDB_TYPE_DECIMAL | DECIMAL | float |
DUCKDB_TYPE_ENUM | ENUM | string |
DUCKDB_TYPE_LIST | LIST | array |
DUCKDB_TYPE_STRUCT | STRUCT | array |
DUCKDB_TYPE_ARRAY | ARRAY | array |
DUCKDB_TYPE_MAP | MAP | array |
DUCKDB_TYPE_UNION | UNION | mixed |
DUCKDB_TYPE_BIT | BIT | string |
DUCKDB_TYPE_VARINT | VARINT | string |
DUCKDB_TYPE_SQLNULL | NULL | null |