使用存储过程水平分表


​ 我们经常会遇到一些数据表,数据量过大,比如日志表,每天产生几十万条数据,这样积累下来非常不利于数据库查询和维护,有时候甚至连select count(*) from table a 都查不出来,为避免这种情况产生,通常会按照数据创建时间,来按年按月或者按季度进行分表,原表只保留几个月的数据。如下所示,用存储过程来进行处理。

​ 逻辑 就是 先创建分表,结构和原表相同,然后再插入数据,再删除原表插入历史表的数据。

分表存储过程

CREATE DEFINER=`XXX`@`%` PROCEDURE `up_clear_table_a`()
BEGIN
    -- 自动前30天前的数据到历史表中
    DECLARE v_stat_date DATE;
    DECLARE v_table_name VARCHAR(50);
    DECLARE v_str VARCHAR(2000);
    SET v_stat_date=DATE_SUB(CURRENT_DATE(),INTERVAL 30 DAY);
    SET v_table_name=CONCAT('table_a_',DATE_FORMAT(v_stat_date,'%Y'));
       
    SET v_str=CONCAT('create table if not exists ',v_table_name,'(
         id varchar(40) NOT NULL DEFAULT '''' COMMENT ''id'',
         type tinyint(4) DEFAULT ''0'' COMMENT ''类型'',
         remark varchar(255) DEFAULT '''',
         state tinyint(4) DEFAULT ''0'' COMMENT ''状态'',
         created_at datetime DEFAULT CURRENT_TIMESTAMP COMMENT ''创建时间'',
         created_operator_id varchar(40) DEFAULT '''' COMMENT ''创建人'',
         created_operator_name varchar(40) DEFAULT '''' COMMENT ''创建人名称'',
         PRIMARY KEY (id),
       ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=''表''');       
    SET @sql=v_str;
    PREPARE stmt FROM @sql; 
    EXECUTE stmt;  
    DEALLOCATE PREPARE stmt;  
      
    SET v_str=CONCAT('insert into ',v_table_name,'
          select * from table_a where created_at>=''',v_stat_date,''' and created_at=v_stat_date AND created_at

解析

建表

  • 也可以使用 create TABLE if not exists table_b like table_a;来进行复制表,只复制表结构不复制数据;
  • if not exists 是必须要写的,不然报错的话就执行不下去了;
  • 单引号 两边都需要加个单引号

PREPARE 预处理语句

PREPARE stmt FROM @sql; 
EXECUTE stmt;  
DEALLOCATE PREPARE stmt; 

上面这三句是固定式语句,第一句式 预定义好动态sql语句 stmt,第二句毫无疑问是执行语句,第三局是删除预定义语句stmt。

DEALLOCATE 英文翻译就是 释放; 解除分配; 释放游标; 删除一个准备好的查询; 归还;


文章作者: 洛神葵
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 洛神葵 !
评论