MySql 数据库分表 简单思路

创建源表
复制代码
CREATE TABLE `api_log` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(20) DEFAULT NULL COMMENT '用户名',
  `ip` varchar(45) DEFAULT NULL COMMENT '登录IP地址',
  `ip_location` varchar(255) DEFAULT NULL COMMENT 'IP所属地',
  `os` varchar(50) DEFAULT NULL COMMENT '操作系统',
  `browser` varchar(50) DEFAULT NULL COMMENT '浏览器',
  `status` smallint(6) DEFAULT '1' COMMENT '登录状态 (1成功 2失败)',
  `message` varchar(50) DEFAULT NULL COMMENT '提示消息',
  `login_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '登录时间',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `created_by` int(11) DEFAULT NULL COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=127 DEFAULT CHARSET=utf8 COMMENT='登录日志表';
新增日志
php 复制代码
//按年月分表 通过redis存储 防止每次插入都需要去扫描数据库
public function apiLog():Response
{
    // 获取当前年月
    $tableName = 'api_log_' . date('Ym');
    //每月第一次创建删除一次
    if(!\support\Redis::get($tableName)){
        $prefix = 'api_log_';
        $expireDate = date('Ym', strtotime('-1 year'));
        //清理一年前的旧表
        \support\think\Db::query("DROP TABLE IF EXISTS ".$prefix . $expireDate);
        //清理一年前及更早的旧表
        // 查询所有分表
        $tables = \support\think\Db::query("SHOW TABLES LIKE '{$prefix}%'");
        foreach ($tables as $t) {
            $table = reset($t); // 获取表名
            // 提取年月后缀
            $suffix = str_replace($prefix, '', $table);
            // 如果年月 <= 过期年月,则删除
            if (ctype_digit($suffix) && $suffix <= $expireDate) {
                \support\think\Db::query("DROP TABLE IF EXISTS {$table}");
            }
        }
        //保存31天自动销毁
        \support\Redis::set($tableName,1, 60 * 60 * 24 * 31);
        // 确保表存在(没有则创建)
        \support\think\Db::query("CREATE TABLE IF NOT EXISTS {$tableName} LIKE api_log");
    }
    // 插入数据
    \support\think\Db::table($tableName)->insert([
        'username'=>'日志插入'
    ]);
    return success();
}
日志查询带分页
php 复制代码
public function apiLogList(\support\Request $request): Response
    {
        $rows = $request->post('rows');
        $page = $request->post('page');
        $starttime = $request->post('starttime');
        $endtime = $request->post('endtime');
        $tables = $this->getTableNames($starttime, $endtime);
        $baseQuery = "SELECT id,username FROM %s WHERE status='004001'";
        $unionQueries = array_map(
            fn($table) => sprintf($baseQuery, $table),
            $tables
        );
        // 构建 UNION ALL 查询
        $unionSql = implode(' UNION ALL ', $unionQueries);
        // 总数查询
        $count = \support\think\Db::query("SELECT COUNT(*) as total_count FROM ({$unionSql}) as combined_tables");
        // 分页查询
        $offset = ($page - 1) * $rows;
        $list = \support\think\Db::query("{$unionSql} ORDER BY cts DESC LIMIT {$offset}, {$rows}");
        return success(data:$list,count: $count);
    }
    /**
     * 根据时间范围生成表名数组
     */
    private function getTableNames($starttime, $endtime){
        $startDate = new DateTime($starttime);
        $endDate = new DateTime($endtime);
        $tableList = \support\think\Db::query('SHOW TABLES');
        $tables = [];
        $current = (clone $startDate)->modify('first day of this month');
        $endMonth = (clone $endDate)->modify('first day of this month');
        while($current <= $endMonth){
            $tableName = 'api_log_' . $current->format('Ym');
            // 检查表是否存在(可选)
            if(in_array($tableName,$tableList)){
                $tables[] = $tableName;
            }
            // 下一个月
            $current->modify('+1 month');
        }
        return $tables;
    }
相关推荐
A.说学逗唱的Coke18 小时前
【大模型专题】向量数据库深度解析:从原理到实战,构建企业级 AI 知识检索底座
数据库·人工智能
果丁智能18 小时前
智能锁赋能网约房民宿数字化管控:身份核验+远程授权,筑牢安全防线、降本增效
网络·数据库·人工智能·安全·智能家居
无敌的牛18 小时前
redis学习过程
数据库·redis·学习
IT北辰19 小时前
神通数据库管理系统V7.0.251210 for Windows(x86 64bit)安装部署
数据库·神通
北顾笙98019 小时前
MySQL-day2
数据库·mysql
Demons_kirit19 小时前
新项目如何连接上自己本地的数据库
数据库
洪晓露20 小时前
将 rke2 集群证书延长至 10 年
运维·服务器·数据库
程序猿乐锅20 小时前
【MySQL | 第八篇】MySQL 视图
数据库·mysql
dog25021 小时前
网络长尾延时的重尾本质
开发语言·网络·php
jieyucx21 小时前
SQL 查询终极高阶通鉴:从零基础拆解到工业级多表联查、窗口函数与索引优化
数据库·sql