Installation:
composer require one23/laravel-clickhouse
Publish the config file:
php artisan vendor:publish --provider="One23\LaravelClickhouse\ClickhouseServiceProvider"
Configure .env:
CLICKHOUSE_HOST=127.0.0.1
CLICKHOUSE_PORT=9000
CLICKHOUSE_DATABASE=your_db
CLICKHOUSE_USERNAME=user
CLICKHOUSE_PASSWORD=pass
First Use Case: Extend your Eloquent model to use ClickHouse:
use One23\LaravelClickhouse\Eloquent\Model;
class User extends Model
{
protected $connection = 'clickhouse';
}
Define the connection in config/database.php:
'clickhouse' => [
'driver' => 'clickhouse',
'host' => env('CLICKHOUSE_HOST'),
'port' => env('CLICKHOUSE_PORT'),
'database' => env('CLICKHOUSE_DATABASE'),
'username' => env('CLICKHOUSE_USERNAME'),
'password' => env('CLICKHOUSE_PASSWORD'),
],
Run Migrations:
Ensure your migrations are compatible with ClickHouse syntax (e.g., DateTime instead of timestamp).
One23\LaravelClickhouse\Eloquent\Model for all ClickHouse models.DB::connection('clickhouse')->table() for raw queries.Data Ingestion:
// Bulk insert
User::insert([
['name' => 'John', 'email' => 'john@example.com'],
['name' => 'Jane', 'email' => 'jane@example.com'],
]);
Use ClickHouse’s INSERT INTO ... VALUES syntax for efficiency.
Time-Series Data:
Leverage ClickHouse’s strengths with DateTime fields and Array types:
schema()->create('metrics', function (Blueprint $table) {
$table->dateTime('recorded_at');
$table->array('values')->nullable();
});
Aggregations:
$results = User::selectRaw('
toDate(recorded_at) as day,
avg(value) as avg_value
')
->groupBy('day')
->get();
Materialized Views: Create materialized views via migrations or raw SQL for performance-critical queries.
Schema Mismatches:
ALTER TABLE for columns. Use MODIFY COLUMN or recreate tables.unsignedBigInteger for auto-increments; use UUID or DateTime + sortingKey instead.Data Types:
String has a max length of 2^32 - 1 (vs. MySQL’s 255). Use String for large texts.DateTime is preferred over timestamp for time-series data.Transactions:
Eloquent Quirks:
deleted_at column, but ClickHouse’s DELETE is not atomic. Use a is_deleted boolean instead.increment()/decrement() may not work as expected; use raw SQL or update()..env:
CLICKHOUSE_LOG_QUERIES=true
users.xml for user permissions.EXPLAIN in raw SQL to analyze query plans.Custom Query Builder:
Extend the query builder to add ClickHouse-specific functions (e.g., arrayJoin, groupArray):
DB::connection('clickhouse')->select('arrayJoin(values) as value from metrics');
Event Listeners:
Listen for eloquent.saved to trigger ClickHouse-specific post-save logic (e.g., updating materialized views).
Testing: Use Docker for local ClickHouse instances in tests:
# docker-compose.yml
services:
clickhouse:
image: clickhouse/clickhouse-server
ports:
- "9000:9000"
Seeding:
Seed large datasets efficiently with ClickHouse’s INSERT INTO ... SELECT or clickhouse-client CLI tool.
How can I help you explore Laravel packages today?