PHP 클라이언트

PHP 클라이언트 (PHP Client)

DuckDB PHP 클라이언트는 [tertiary client(3차 클라이언트)]({% link docs/current/clients/overview.md %})이며 서드파티가 유지 관리해요.

성능에 초점을 맞춘 PHP용 클라이언트 API예요. DuckDB PHP 클라이언트는 FFI를 통해 공식 C API를 내부적으로 사용해 좋은 벤치마크 결과를 내요. 이 라이브러리는 C API의 단순한 래퍼가 아니라, PHP 친화적인 맞춤 메서드를 도입해 DuckDB를 더 쉽게 다룰 수 있게 해줘요. Linux, Windows, macOS와 호환되며 PHP 8.3 이상이 필요해요.

출처: 문서

본문

전체 문서는 https://duckdb-php.readthedocs.io/에서 볼 수 있어요.

자동 설치 (Automatic Install, 초보자 추천)

composer require satur.io/duckdb-auto

이 설치 방법을 쓰려면 satur.io/duckdb-auto가 코드를 실행하도록 허용해야 해요. 자세한 내용은 installation을 확인해요.

빠른 시작 (Quick Start)

DuckDB::sql("SELECT 'quack' as my_column")->print();    
-------------------
| my_column       |
-------------------
| quack           |
-------------------

여기서 사용한 DuckDB::sql() 함수는 새 인메모리 데이터베이스에서 쿼리를 수행하며, 결과를 가져온 뒤 그 데이터베이스를 파괴해요.

이것은 가장 흔한 사용 사례는 아니에요. 영구 연결을 얻는 방법을 볼게요.

연결 (Connection)

$duckDB = DuckDB::create('duck.db'); // 또는 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);');

$duckDB->query('SELECT * FROM test')->print();

짐작했겠지만, DuckDB::create()는 지정된 데이터베이스에 새 연결을 만들거나, 없으면 새로 만든 뒤 연결을 설정해요.

그다음 query 함수를 사용해 요청을 수행할 수 있어요.

정적 메서드 sql과 비정적 메서드 query의 차이를 주목해요. 전자는 항상 새 인메모리 데이터베이스를 만들고 파괴하는 반면, 후자는 기존에 설정된 연결을 사용하므로 대부분의 경우 선호되어요.

또한 이 라이브러리는 쿼리에 파라미터를 바인딩하기 위한 prepared statements도 제공해요.

Prepared Statements

$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();

Appenders

Appenders는 DuckDB에서 데이터를 로드하는 권장 방법이에요. 자세한 내용은 [Appender 페이지]({% link docs/current/clients/c/appender.md %})를 참고해요.

$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-Powerful

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               |
...

요구 사항 (Requirements)

  • Linux, macOS 또는 Windows.
  • x64 플랫폼.
  • PHP >= 8.3.
  • ext-ffi.
  • ext-bcmath – 큰 정수(> PHP_INT_MAX)에 필요.
  • ext-zend-opcache – 더 나은 성능을 위해.

타입 지원 (Type Support)

버전 1.2.0부터 이 라이브러리는 모든 DuckDB 파일 타입을 지원해요.

DuckDB Type SQL Type PHP Type
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_BIGNUM BIGNUM string
DUCKDB_TYPE_SQLNULL NULL null

더 알아보기 (Learn more)

PHP 클라이언트의 전체 문서는 duckdb-php.readthedocs.io에서 확인해요.