laraveladmin / sharding
Declarative logical table sharding for Hyperf models: time or capacity modes, transparent CRUD, pagination, aggregates and online backfill.
Requires
- php: >=8.2
- hyperf/async-queue: ~3.2.0
- hyperf/command: ~3.2.0
- hyperf/database: ~3.2.0
- hyperf/db-connection: ~3.2.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-11-02 07:48:13 UTC
README
Hyperf 模型声明式逻辑分表:内置 time(年 / 月 / 日)与 capacity(固定 ID 段,写满自动切表)两种模式,提供透明 CRUD、分页、聚合、注册表与自动回填。按年分表:$shardUnit='year' + $shardTable='..._{Y}';只写 unit 时默认模板会自动推导年表。
状态:MVP。
capacity模式(logs使用)已实现并通过测试;time模式为可用基础版;groupBy/distinct、自定义 driver、自动 schema 变更属于后续增强。
安装与迁移
composer require laraveladmin/sharding
# 1) 发布配置 + 两份迁移到应用目录
php bin/hyperf.php vendor:publish laraveladmin/sharding
# 2) 执行迁移(本仓库使用 migrate:all;Hyperf 标准 migrate 亦可)
php bin/hyperf.php migrate:all
- 包内迁移源文件:
vendor/laraveladmin/sharding/migrations/(开发副本:packages/sharding/migrations/)。 vendor:publish会把两份迁移复制到database/migrations/2026/;若目标文件已存在会跳过,需覆盖时加--force。若你的应用迁移目录不同,从上述路径手动复制。- 也可跳过迁移,执行
php bin/hyperf.php shard:install幂等建表(等价 DDL 兜底)。 - 开发期可在本仓库
server/composer.json用pathrepository 指向../packages/sharding(当前接入方式)。
开发副本/本仓库已提交迁移到 server/database/migrations/2026/;其他项目从 vendor 或 vendor:publish 获取。
默认 config/sharding.php 的 models 为空/注释,不硬编码任何模型或数据表;优先在模型上用 $shardMode / $shardCapacity / $shardTable 声明。
模型声明
use Hyperf\Database\Model\SoftDeletes;
use LaravelAdmin\Sharding\Concerns\Shardable;
class Log extends Model
{
use Shardable;
use SoftDeletes;
protected string $shardMode = 'capacity';
protected int $shardCapacity = 10_000_000;
protected string $shardTable = 'logs_{seq}';
protected string $shardIdStrategy = 'range';
protected string $shardKey = 'created_at';
}
logs 已接入,默认 SHARDING_ENABLED=false;完成迁移(或 shard:install)→ shard:create → shard:activate 后再打开。
内部模型
注册表 / 回填记录的数据查询统一走 Eloquent 模型,不用 Db::table():
| 表 | 模型 |
|---|---|
shard_registries | LaravelAdmin\Sharding\Model\ShardRegistry(SoftDeletes) |
shard_backfills | LaravelAdmin\Sharding\Model\ShardBackfill |
- 表名 / 连接由
sharding.registry_table、sharding.backfill_table、sharding.registry_connection配置,模型动态取。 - 数据 CRUD 走模型;DDL、
information_schema盘点、动态分表MAX(id)仍使用连接对象(这些不是注册表数据查询)。
命令
shard:install:创建shard_registries/shard_backfillsshard:create {model} --seq=N:预建容量分表(pending)shard:activate {model} [--seq=N]:激活写表 / 封旧表shard:backfill {model} [--auto] [--dry-run]:批量回填(游标续跑)shard:backfill:status {model}:回填进度shard:status {model} [--with-trashed]:分表 / 水位shard:prune {model} --keep=N [--dry-run] [--force]:手动清理旧容量表shard:sync-registry {model}:注册表与物理表漂移报告
行为与限制
- 容量模式按 ID 段计数(含已删除 / 软删除),每表 ≤ capacity;封表前预留安全余量。
- 写切后新数据只写分表,不提供回滚 / 双写 / 反向合并。
created_at不参与容量模式选表;按时间筛选需扫描全部 active + readonly 表。ORDER BY id可逐表取满即停;其它排序字段需归并全部相关表。- 聚合:
sum/count/min/max/avg按分片合并,avg用总量重算;groupBy/distinct尚未实现。 - 回填:每批一次 SELECT + 每个目标表一条多值 INSERT + 一次游标更新;支持断点续跑。
- 旧表(
shard_table = base_table)不进入普通查询,不自动删除 / 归档;回填期间按id > cursor水位并入。 - 自定义 driver 接口已预留,但运行时不接管自定义模式(会显式报错)。
- 激活 / 回填的分布式锁为 P1;MVP 未加锁,多 worker 同时首次写 / 回填需先人工串行。
测试
本仓库:
包测试(在任意已安装本包的 Hyperf 应用中运行;本仓库用 server 容器):
docker compose exec -T server vendor/bin/pest ../packages/sharding/tests
本仓库 Log 接入回归:
docker compose exec -T server vendor/bin/pest --test-directory=test test/Unit/Sharding/ShardingLogIntegrationTest.php