PHPackages                             skylence/laravel-star-schema - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. skylence/laravel-star-schema

ActiveLibrary[Database &amp; ORM](/categories/database)

skylence/laravel-star-schema
============================

Star schema dimensional modeling for Laravel. Define fact tables, dimension tables, and aggregate data with scheduled jobs.

01.1k↑2676.9%PHPCI failing

Since Mar 19Pushed 1mo agoCompare

[ Source](https://github.com/skylence-be/laravel-star-schema)[ Packagist](https://packagist.org/packages/skylence/laravel-star-schema)[ RSS](/packages/skylence-laravel-star-schema/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Laravel Star Schema
===================

[](#laravel-star-schema)

Star schema dimensional modeling for Laravel. Define fact tables, dimension tables, and query analytics data with a fluent API.

Works with MySQL, PostgreSQL, and SQLite.

Installation
------------

[](#installation)

```
composer require skylence/laravel-star-schema
```

Publish the config file:

```
php artisan vendor:publish --tag="star-schema-config"
```

Run migrations:

```
php artisan migrate
```

Seed the date dimension:

```
php artisan star-schema:seed-dates
```

Quick Start
-----------

[](#quick-start)

### 1. Define a Fact

[](#1-define-a-fact)

A fact represents a measurable business event — an order, a payment, a stock movement.

```
namespace App\StarSchema\Facts;

use App\Models\Order;
use Illuminate\Database\Eloquent\Builder;
use Skylence\StarSchema\Contracts\FactDefinition;

class SalesOrderFact implements FactDefinition
{
    public function name(): string
    {
        return 'sales_orders';
    }

    public function sourceModel(): string
    {
        return Order::class;
    }

    public function query(): Builder
    {
        return Order::query();
    }

    public function measures(): array
    {
        return [
            'total_amount' => 'Total Amount',
            'quantity'     => 'Item Count',
        ];
    }

    public function dimensions(): array
    {
        return [
            'customer_id' => CustomerDimension::class,
            'product_id'  => ProductDimension::class,
        ];
    }

    public function degenerateDimensions(): array
    {
        return [
            'order_number' => 'Order Number',
        ];
    }

    public function dateColumn(): string
    {
        return 'ordered_at';
    }

    public function grain(): string
    {
        return 'One row per order';
    }
}
```

### 2. Register It

[](#2-register-it)

In `config/star-schema.php`:

```
'facts' => [
    App\StarSchema\Facts\SalesOrderFact::class,
],
```

### 3. Query It

[](#3-query-it)

```
use Carbon\CarbonImmutable;
use Skylence\StarSchema\StarQuery;
use Skylence\StarSchema\Enums\Range;

// Revenue per day for the last 30 days
$trend = StarQuery::fact('sales_orders')
    ->between(
        CarbonImmutable::now()->subDays(29),
        CarbonImmutable::now(),
    )
    ->perDay()
    ->sum('total_amount');

// Returns Collection with gap-filled dates
foreach ($trend as $point) {
    echo "{$point->date}: {$point->value}\n";
}

// Using preset ranges
$trend = StarQuery::range('sales_orders', Range::Last30Days)
    ->perWeek()
    ->avg('total_amount');

// Single scalar value
$total = StarQuery::fact('sales_orders')
    ->between($from, $to)
    ->scalar('total_amount');

// Growth rate vs previous period
$growth = StarQuery::fact('sales_orders')
    ->between($from, $to)
    ->growthRate('total_amount');
// => ['current' => 15000, 'previous' => 12000, 'growth' => 25.0]
```

Fluent Query API
----------------

[](#fluent-query-api)

MethodDescription`StarQuery::fact($fact)`Start a query for a registered fact (name or instance)`StarQuery::range($fact, Range::YTD)`Start a query with a preset date range`->between($from, $to)`Set the date range`->perDay()`Group by day`->perWeek()`Group by week`->perMonth()`Group by month`->perQuarter()`Group by quarter`->perYear()`Group by year`->grain(TimeGrain::Monthly)`Set grain with enum`->where('status', 'paid')`Filter by column value`->where('status', ['paid', 'shipped'])`Filter by multiple values (whereIn)`->groupBy('customer_id')`Group by dimension`->withoutGapFilling()`Disable zero-filling for missing periods`->sum('amount')`Aggregate with SUM`->avg('amount')`Aggregate with AVG`->count()`Aggregate with COUNT`->min('amount')`Aggregate with MIN`->max('amount')`Aggregate with MAX`->scalar('amount')`Get a single aggregated value (no time grouping)`->growthRate('amount')`Compare current vs previous periodAll time-series methods return `Collection` where each `TrendValue` has `date` (string) and `value` (float|int) properties.

Date Ranges
-----------

[](#date-ranges)

The `Range` enum provides common presets:

RangePeriod`Range::Today`Start of today to now`Range::Yesterday`Full day yesterday`Range::Last7Days`Last 7 days`Range::Last30Days`Last 30 days`Range::Last90Days`Last 90 days`Range::MonthToDate`Start of current month to now`Range::QuarterToDate`Start of current quarter to now`Range::YearToDate`Start of current year to now`Range::LastMonth`Full previous month`Range::LastQuarter`Full previous quarter`Range::LastYear`Full previous year`Range::All`All time (from 2000-01-01)Artisan Commands
----------------

[](#artisan-commands)

```
# Seed date dimension (2020-2035 by default)
php artisan star-schema:seed-dates
php artisan star-schema:seed-dates --start-year=2015 --end-year=2040
php artisan star-schema:seed-dates --fiscal-start=4  # April fiscal year

# Aggregate facts into snapshot rows
php artisan star-schema:aggregate
php artisan star-schema:aggregate --fact=sales_orders --grain=monthly
php artisan star-schema:aggregate --from=2025-01-01 --to=2025-01-31

# Sync dimension tables from source models
php artisan star-schema:sync-dimensions
php artisan star-schema:sync-dimensions --dimension=customer

# Prune old snapshots based on retention config
php artisan star-schema:prune
```

Configuration
-------------

[](#configuration)

See the full [configuration reference](docs/configuration.md).

Key settings in `config/star-schema.php`:

```
return [
    'table_prefix' => 'star_',        // Table name prefix
    'connection'    => null,           // Dedicated analytics DB connection

    'date_dimension' => [
        'start_year'             => 2020,
        'end_year'               => 2035,
        'fiscal_year_start_month' => 1,   // 1=Jan, 4=Apr, 7=Jul
        'locale'                 => null, // 'nl', 'fr', 'de', etc.
        'holidays'               => [],   // Array or callable
    ],

    'retention' => [
        'daily'     => 90,    // Keep daily snapshots for 90 days
        'weekly'    => 365,   // Keep weekly snapshots for 1 year
        'monthly'   => null,  // Keep forever
        'quarterly' => null,
        'yearly'    => null,
    ],

    'facts'      => [],  // Register FactDefinition classes
    'dimensions' => [],  // Register DimensionDefinition classes
];
```

Advanced Usage
--------------

[](#advanced-usage)

- [Defining Dimensions](docs/dimensions.md) — Dimension definitions, SCD types, hierarchies
- [Snapshot Aggregation](docs/aggregation.md) — Pre-computed snapshots, scheduling, retention
- [Database Adapters](docs/adapters.md) — Multi-database support and custom adapters
- [Configuration Reference](docs/configuration.md) — Full config options

Database Support
----------------

[](#database-support)

DatabaseVersionStatusMySQL8.0+SupportedPostgreSQL14+SupportedSQLite3.xSupportedTesting
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

MIT

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance59

Moderate activity, may be stable

Popularity21

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/8ad0eeb3e0f0183e243d7edf649313243750f8048918eb00c9c041c5dc379149?d=identicon)[skylence](/maintainers/skylence)

---

Top Contributors

[![jonasvanderhaegen](https://avatars.githubusercontent.com/u/7755555?v=4)](https://github.com/jonasvanderhaegen "jonasvanderhaegen (6 commits)")

### Embed Badge

![Health badge](/badges/skylence-laravel-star-schema/health.svg)

```
[![Health](https://phpackages.com/badges/skylence-laravel-star-schema/health.svg)](https://phpackages.com/packages/skylence-laravel-star-schema)
```

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k115.1M102](/packages/jdorn-sql-formatter)[illuminate/database

The Illuminate Database package.

2.8k52.4M9.4k](/packages/illuminate-database)[mongodb/mongodb

MongoDB driver library

1.6k64.0M546](/packages/mongodb-mongodb)[ramsey/uuid-doctrine

Use ramsey/uuid as a Doctrine field type.

90340.3M211](/packages/ramsey-uuid-doctrine)[reliese/laravel

Reliese Components for Laravel Framework code generation.

1.7k3.4M16](/packages/reliese-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
