分表聚合助手类

发布于:2025-07-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

下面是一个分表聚合助手类的推荐实现方式,你可以将其放在 app/model/TaskRecord.php 或单独新建一个 app/model/ShardingHelper.php 文件,适用于所有类似分表模型(如 TaskRecord、StarRecord)。


分表聚合助手(通用版)

namespace app\model;

use support\Db;
use Illuminate\Support\Collection;

class ShardingHelper
{
    /**
     * 获取所有分表表名
     * @param string $baseTableName 例如 'ss_task_records'
     * @param int $shardCount
     * @return array
     */
    public static function getAllShardTables($baseTableName, $shardCount = 16)
    {
        $tables = [];
        for ($i = 0; $i < $shardCount; $i++) {
            $tables[] = "{$baseTableName}_{$i}";
        }
        return $tables;
    }

    /**
     * 跨所有分表聚合查询
     * @param string $baseTableName
     * @param callable $queryCallback function($queryBuilder, $tableName)
     * @param int $shardCount
     * @return Collection
     */
    public static function unionAll($baseTableName, callable $queryCallback, $shardCount = 16)
    {
        $all = collect();
        foreach (self::getAllShardTables($baseTableName, $shardCount) as $table) {
            $query = Db::table($table);
            $result = $queryCallback($query, $table);
            if ($result instanceof \Illuminate\Support\Collection) {
                $all = $all->merge($result);
            } elseif (is_array($result)) {
                $all = $all->merge($result);
            }
        }
        return $all;
    }
}

使用示例

1. 查询所有分表中 user_id in [1,2,3] 的任务

use app\model\ShardingHelper;

$userIds = [1,2,3];
$allRecords = ShardingHelper::unionAll('ss_task_records', function($query) use ($userIds) {
    return $query->whereIn('user_id', $userIds)->get();
});

2. 查询所有分表的任务总数

$total = ShardingHelper::unionAll('ss_task_records', function($query) {
    return $query->count();
})->sum();

3. StarRecord 跨分表查询

$allStars = ShardingHelper::unionAll('ss_star_records', function($query) {
    return $query->where('type', 'earn')->get();
});

说明

  • 你可以把 ShardingHelper 放在 app/model/ 目录,所有分表模型都能用。
  • 只需传入基础表名(如 ‘ss_task_records’),即可跨所有分表聚合。
  • 回调里用 $query 写任何你想要的查询,返回 Collection 或数组即可。

网站公告

今日签到

点亮在社区的每一天
去签到