分表发+分区

news/2025/3/19 11:28:29/文章来源:https://www.cnblogs.com/sanqiyi/p/18780702

1. 表结构设计

一、基本概念

  1. 分表:将一个大表拆分为多个小表(如 user_checkin_0user_checkin_1),按 user_id 取模决定数据存到哪张表。
  2. 分区:将一个表中的数据按时间(如每月)分成多个物理存储块,但逻辑上仍是一张表,分区是数据库层的功能。

二、表结构设计

-- 用户签到记录表(按用户ID分表)
CREATE TABLE user_checkin_%s (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID',checkin_date DATE NOT NULL COMMENT '签到日期(格式:YYYY-MM-DD)',created_at INT  NOT NULL DEFAULT 0 COMMENT '创建时间',PRIMARY KEY (id, checkin_date),        -- 主键包含 checkin_dateUNIQUE KEY udx_user_date (user_id, checkin_date),KEY idx_date (checkin_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
PARTITION BY RANGE (TO_DAYS(checkin_date)) (PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')),...
);

 

2、hyperf框架设置

一、数据库配置 config/autoload/databases.php

return ['default' => ['driver' => Hyperf\DB\DB::class,'sharding' => ['enable' => true,'rules' => ['user_checkin' => [         // 逻辑表名'shard_key' => 'user_id', 'algorithm' => 'mod',    // 取模算法'num' => 3,              // 分3张表(示例)'format' => 'user_checkin_%s', // 物理表名格式
                ],],],],
];

 

二、 模型类 app/Model/UserCheckin.php

namespace App\Model;use Hyperf\DbConnection\Model\Model;class UserCheckin extends Model
{// 逻辑表名(对应配置中的 user_checkin)protected $table = 'user_checkin';// 动态选择分表public function getTable(){$userId = $this->user_id ?? 0;$suffix = $userId % 3;  // 分3张表,实际用1024return "user_checkin_{$suffix}";}
}  

 

3、手动或定时任务创建分区

每个月一号的时候定时任务去操作 自动分区

一、代码定时任务创建分区

 编辑命令 app/Command/PartitionCommand.php

namespace App\Command;use Hyperf\Command\Command as HyperfCommand;
use Hyperf\DbConnection\Db;
use Psr\Container\ContainerInterface;class PartitionCommand extends HyperfCommand
{protected $name = 'partition:maintain';public function handle(){// 下个月1号的日期(如 2023-04-01)$nextMonth = date('Y-m-01', strtotime('+1 month'));$partitionName = 'p' . date('Ym', strtotime($nextMonth));// 为每个分表添加分区for ($i = 0; $i < 3; $i++) {  // 示例3张分表,实际用1024$table = "user_checkin_{$i}";$sql = "ALTER TABLE {$table} ADD PARTITION (PARTITION {$partitionName} VALUES LESS THAN (TO_DAYS('{$nextMonth}')))";
            Db::statement($sql);$this->info("为表 {$table} 添加分区 {$partitionName}");}}
}

注册命令 config/autoload/commands.php

 

return [App\Command\PartitionCommand::class,
];

设置定时任务(每月1号执行)

# 编辑 Crontab
crontab -e# 添加任务(每月1号 00:05 执行)
5 0 1 * * cd /path/to/project && php bin/hyperf.php partition:maintain

4、查询sql

一、纯 SQL 查询语句

-- 假设用户ID为 12345,分表为 user_checkin_313(12345 % 1024 = 313)
-- 查询 2023-10 月的签到记录
SELECT *
FROM user_checkin_313
WHERE user_id = 12345AND checkin_date BETWEEN '2023-10-01' AND '2023-10-31';

二、Hyperf 框架动态查询实现

namespace App\Model;use Hyperf\DbConnection\Model\Model;class UserCheckin extends Model
{protected $table = 'user_checkin'; // 逻辑表名// 动态设置分表名public function getTable(){$userId = $this->user_id ?? 0;$suffix = $userId % 1024; // 分表数量 1024return "user_checkin_{$suffix}";}
}
查询最近一个月签到记录
// 获取当前月份的第一天和最后一天
$startDate = date('Y-m-01'); // 本月第一天(如 2023-10-01)
$endDate = date('Y-m-t');     // 本月最后一天(如 2023-10-31)// 执行查询(假设用户ID为 12345)
$userId = 12345;
$records = UserCheckin::query()->where('user_id', $userId)->whereBetween('checkin_date', [$startDate, $endDate])->get();// 输出结果
foreach ($records as $record) {echo $record->checkin_date . ' : ' . $record->points . PHP_EOL;
}

三、执行流程解析

  1. 分表路由
    Hyperf 根据 user_id 计算分表后缀(如 user_checkin_313),自动拼接物理表名。

  2. 分区剪裁
    MySQL 根据 checkin_date BETWEEN '2023-10-01' AND '2023-10-31' 自动定位到 p202310 分区,跳过其他分区。

  3. 查询优化

    • 索引建议:在 user_id 和 checkin_date 上创建复合索引,加速查询:

       
      ALTER TABLE user_checkin_313 
      ADD INDEX idx_user_date (user_id, checkin_date);

四、验证查询效率

1. 查看执行计划
// 在 Hyperf 中获取 SQL 执行计划
$explain = UserCheckin::query()->where('user_id', 12345)->whereBetween('checkin_date', [$startDate, $endDate])->explain()->get();// 输出结果
dd($explain);

预期结果

  • partitions 列显示 p202310(仅扫描目标分区)。

  • type 列为 range,表示高效的范围查询。

2. 日志验证

检查 Hyperf 的 SQL 日志,确认实际查询的表名和条件:

[DEBUG] SELECT * FROM `user_checkin_313` 
WHERE `user_id` = 12345 
AND `checkin_date` BETWEEN '2023-10-01' AND '2023-10-31'

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/901435.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何让GameObject销毁时无论是否Active过,都调用OnDestroy

1)如何让GameObject销毁时无论是否Active过,都调用OnDestroy2)升级到URP画面会提升吗3)如何用Dynamic Mesh做出在墙上打洞的效果4)UE可以把烘焙好的光照贴图导出吗这是第424篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力…

测序芯片-不同键合工艺对比-flowcell-代加工-外协加工-委外加工-激光代加工-河南郑州-芯晨微纳(河南)

基因测序(包括DNA测序和RNA测序)是研究生命信息的重要方法之一。DNA测序(DNA sequencing,或译DNA定序)是指分析特定DNA片段的碱基序列, 也就是腺嘌呤(A)、胸腺嘧啶(T)、胞嘧啶(C)与鸟嘌呤(G)的排列方式。同理,RNA测序是指分析特定RNA片段的碱基序列,也就是腺嘌呤(A)、鸟嘌呤…

Go语言内存管理机制解析

引言 Go语言以高并发性能和简洁的内存管理著称,其独特的内存分配机制在保证开发效率的同时,实现了接近C/C++的性能。本文将深入剖析Go的内存管理设计,结合内存逃逸、多级缓存池、无锁化分配等核心机制,揭示其高效运作的秘密。 参考文档 https://www.bilibili.com/video/BV1…

HTTP响应拆分漏洞——CRLF注入漏洞

CRLF漏洞 CRLF注入漏洞:web应用没有对用户输入做严格过滤,导致攻击者可以输入一些恶意字符,攻击者向请求行或首部中的字段注入恶意的CRLF,就能注入一些首部字段或报文主题,并在响应中输出。 HTTP报文中,HTTP header之间是由一个CRLF字符序列分隔开的,HTTP Header 与Body…

图案化CCD视觉精密点胶技术-flowcell-代加工-外协加工-委外加工-激光代加工-河南郑州-芯晨微纳(河南)

图案化视觉点胶技术(Patterned Vision Dispensing Technology)是一种结合高精度点胶工艺与机器视觉系统的先进制造技术,能够根据预设的图案或路径精确分配胶水、导电浆料、封装材料等流体,广泛应用于电子封装、微纳制造、生物芯片等领域。技术原理视觉定位:通过高分辨率摄…

充电桩消防火焰检测系统

充电桩消防火焰检测系统的核心在于其强大的识别能力,充电桩消防火焰检测系统一旦检测到火焰或烟雾,系统会立即启动一系列自动响应机制。首先,自动灭火系统会被触发,根据充电桩的具体环境和安全规范,选择合适的灭火方式,如气体灭火或水喷淋系统。这种即时干预能够在火势初…

助你玩转——4G模组Air780EPM的GPIO设计~

本文将结合Air780EPM的硬件架构与软件框架,从管脚分配、电气特性、复用机制、代码开发四个维度,深入解析GPIO设计的全流程要点,为开发者提供从理论到实践的完整技术指南。 一、概述 开发方式:Air780EPM 仅支持 LuatOS 软件开发方式,不支持 AT 指令开发方式。若使用 AT 指令…

【Java】XxlJob入门

xxl-job概念 xxlJob是轻量级的可视化分布式任务调度平台,适用于中小型企业。主要特性如下:简单、动态、轻量级、支持弹性扩容缩容、事件全异步执行、跨语言。 调度中心和执行任务解耦 调度任务支持多种不同场景的路由策略、容错策略、触发策略 运维更便捷环境准备和部署 Gith…

快速掌握!4G模组:Air780EPM 天线设计说明

天线设计,也是4G模组应用中最容易踩坑的地方。今天主要分享讨论Air700ECQ/EAQ/EMQ系列模组,天线管脚到4G天线之间的电路设计和走线规则。 Air700ECQ/EAQ/EMQ模组属于Cat.1 bis R13架构,天线架构精简为单天线架构,去掉了分集接收天线,因此只需要一根天线。 知识点: Cat.1 …

24级数应二班课堂作业2

2024010068 刘晓津 几年几月多少天year = int(input("请输入年份: ")) month = int(input("请输入月份: "))if month in [1, 3, 5, 7, 8, 10, 12]:days = 31 elif month in [4, 6, 9, 11]:days = 30 elif month == 2:if (year % 4 == 0 and year % 100 != …

简谈如何用纳米压印技术制备测序芯片-测序芯片-flowcell-代加工-外协加工-委外加工-激光代加工-河南郑州-芯晨微纳(河南)

利用纳米压印技术(Nanoimprint Lithography, NIL)制备测序芯片(如DNA测序芯片或生物传感器芯片)的核心在于通过高精度模板在基材上高效复制纳米级结构,从而构建用于捕获、固定或检测生物分子的功能表面。以下是具体步骤和关键技术要点:测序芯片的功能需求 测序芯片通常需…