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;
    }
相关推荐
随风M记忆s16 分钟前
Redis支持事务吗?了解Redis的持久化机制吗?
数据库·redis·bootstrap
花青泽2 小时前
5-数据库-SQL注入-联合查询-关键字绕过-day13
数据库·sql
天桥下的卖艺者8 小时前
使用scitable包,两步生成逆概率删失权重(IPCW)
数据库·r语言
隔窗听雨眠8 小时前
AI原生数据库浪潮:国产数据库的架构重构与路径之争
数据库
数据库小学妹9 小时前
数据库选型实战:从数据类型到TCO成本,五维决策框架+九款产品横评
数据库·信创·国产数据库·数据库选型·oracle迁移
神龙天舞200110 小时前
MySQL 备库为什么会延迟好几个小时
android·数据库·mysql
姜太小白10 小时前
【Linux】df -h 卡住问题的通用排查与解决方案总结
linux·运维·php
丙氨酸長鏈11 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
独行侠影a11 小时前
APScheduler+Redis 分布式定时任务:解决多实例任务重复执行
数据库·redis·分布式
传说故事12 小时前
数据库中一些常用英文单词含义
数据库·oracle