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;
    }
相关推荐
城管不管4 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
倔强的石头1064 小时前
向量数据库从相似度检索走向融合数据底座
数据库
今天AI了吗5 小时前
Python 基础语法(一):常量、变量、输入输出与运算符
开发语言·数据库·人工智能·python·sql·深度学习·机器学习
lilian2336 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
皮卡丘不断更7 小时前
手机优先的 Personal Ledger:把账目、学习和复盘放到同一个入口
数据库·sqlite·fastapi·开源项目·个人效率
保卫大狮兄8 小时前
设备管理从台账到报废,完整生命周期一次讲清
数据库·设备管理·设备
数据安全技术观察8 小时前
数据动态脱敏:让脱敏策略跟着数据目录走
大数据·网络·数据库
小席是个热心肠9 小时前
Redis的自我学习
数据库·redis·学习
2601_965798479 小时前
Salient Theme Setup Guide for Fast Creative WordPress Sites
数据库·web3·php·wordpress
@Mike@10 小时前
09-数据库学习笔记(数据库索引与过滤器)
数据库·笔记