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;
    }
相关推荐
数据知道16 小时前
PostgreSQL 故障排查:万字详解如何找出数据库中的死锁
数据库·postgresql
AI_567817 小时前
阿里云OSS成本优化:生命周期规则+分层存储省70%
运维·数据库·人工智能·ai
choke23317 小时前
软件测试任务测试
服务器·数据库·sqlserver
龙山云仓17 小时前
MES系统超融合架构
大数据·数据库·人工智能·sql·机器学习·架构·全文检索
IT邦德17 小时前
OEL9.7 安装 Oracle 26ai RAC
数据库·oracle
jianghua00117 小时前
Django视图与URLs路由详解
数据库·django·sqlite
那我掉的头发算什么17 小时前
【Mybatis】Mybatis-plus使用介绍
服务器·数据库·后端·spring·mybatis
倔强的石头10617 小时前
关系数据库替换用金仓:数据迁移过程中的完整性与一致性风险
数据库·kingbase
_Johnny_17 小时前
ETCD 配额/空间告警模拟脚本
数据库·chrome·etcd
静听山水17 小时前
StarRocks查询加速
数据库