mysql存储过程按月创建表分区 方式一

mysql存储过程创建表分区(一)
关于分区表,表分区 请看:http://www.cnblogs.com/freeton/p/4265228.html
关于定时任务 请看:http://www.cnblogs.com/dreamhome/archive/2012/10/25/2739037.html
关于分区索引 请看 http://google3030.blog.163.com/blog/static/16172446520103591023745/
不啰嗦,直接贴代码了。

--设置mysql自动允许定时任务
set global event_scheduler =1;

--建日志表(依据此表的createtime字段进行分区,注建表是不能含有主键,或者主键必须是createtime,原因解释清空上面的连接‘[关于分区索引](http://google3030.blog.163.com/blog/static/16172446520103591023745/)’)
CREATE TABLE `sys_log_storage` (
  `id` bigint(32) NOT NULL COMMENT 'ID',
  `ip` varchar(16) DEFAULT NULL COMMENT '服务器IP',
  `lvl` varchar(16) DEFAULT NULL COMMENT '日志级别',
  `title` varchar(64) DEFAULT NULL COMMENT '标题',
  `content` varchar(1024) DEFAULT NULL,
  `createtime` datetime NOT NULL COMMENT '创建时间',
  `classname` varchar(128) DEFAULT NULL,
  `method` varchar(64) DEFAULT NULL
) ENGINE=InnoDB CHARSET=utf8 COMMENT='日志存储';


--按**月**创建分区的存储过程
--(注:上面创建的sys_log_storage表必须没有数据,或者数据createtime字段值小于当前系统时间的下个月第一天的时间值。因为在创建第一个表分区的时候,会以下个月第一天的时间值做为分区分界线,如果有值大于此时间,则会报错误:Table has no partition for value from column_list。)

create PROCEDURE pro_sys_logByMonth(IN tableName VARCHAR(20),IN timeColName VARCHAR(20) )
COMMENT '每月按时添加表分区的存储过程,由定时任务调用'
BEGIN
    DECLARE p_id int;
    DECLARE p_des date;
    DECLARE lasttime VARCHAR(20);
    DECLARE nexttime varchar(20);
    --获取表中的现有的分区数量数量
    SELECT COUNT(partition_name) into p_id FROM INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME=tableName;
    if p_id=0 then
        --获取下个月第一天的时间值,根据此值设置时间分区
        SELECT DATE_FORMAT(DATE_ADD(CURDATE()-DAY(CURDATE())+1,INTERVAL 1 MONTH),'%Y-%m-%d') INTO p_des from DUAL;
        --创建第一个表分区的动态sql
        set @v_add=CONCAT('ALTER table ',tableName,' PARTITION by range COLUMNS(',timeColName,')
         (partition ',CONCAT('par',p_id),' values less than (\'',p_des,'\'))');
    ELSE
        --获取表中现有的最大的分区日期
        SELECT max(partition_description) des into lasttime from INFORMATION_SCHEMA.partitions 
        WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME=tableName;
        --lasttime的值是'2015-12-01' 因是含引号格式的字符串,直接用str_to_date函数和 date_format函数处理不成功。必须通过动态sql把它转换成没有引号的时间字符串
into @nexttime from dual ');
        PREPARE stm from @v_add_a;
        EXECUTE stm;
        DEALLOCATE PREPARE stm;
        --将编译执行的stm结果存储到nexttime中
        set nexttime=@nexttime; 
        --添加表分区的sql
        set @v_add=CONCAT('alter table ',tableName,' add partition (partition ',CONCAT('par',p_id),' values less than (\'',nexttime,'\'))');
    END IF;
    PREPARE stmt from @v_add;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END ;
--每月创建一个分区的定时任务
create event event_sysLogTwo on SCHEDULE EVERY 1 MONTH STARTS CURRENT_TIMESTAMP
on COMPLETION PRESERVE
ENABLE
do call pro_sys_log('sys_log_storage','createtime');


--添加联合索引
alter table sys_log_storage add PRIMARY KEY(id,createtime);
alter table sys_log_storage change id id bigint(32) not null auto_increment;
alter table sys_log_storage auto_increment=1;
--添加索引
alter TABLE sys_log_storage add index inx_syslog_ip(ip);

--查看sql执行时,查询了那些分区,及使用的索引
EXPLAIN PARTITIONs select * from sys_log_storage  where ip='192.168.0.5' and  createtime <'2016-01-20';
**当数据量大时,需要调整分区规则,比如按周或者天,代码如下:**
-- 按日期格式自动添加分区存储过程
create PROCEDURE pro_sys_logByWeekDay (IN tableName VARCHAR(20),IN timeColName VARCHAR(20),IN DateFormat VARCHAR(10) )
COMMENT '按日期格式(年YEAR,月month,周week,日day)添加表分区的存储过程,由定时任务调用'
BEGIN
    DECLARE p_id int;
    DECLARE lasttime VARCHAR(20);
    DECLARE nexttime varchar(20);
    -- 获取表中现有的最大的分区日期
    SELECT COUNT(partition_name),max(partition_description) des into p_id,lasttime 
    from INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME=tableName;
    -- lasttime的值是'2015-12-01' 含引号格式的字符串  必须转换成没有引号的字符串
    set @v_add_a=CONCAT('select adddate(str_to_date(',lasttime,',\'%Y-%c-%d\'),Interval 1 ',DateFormat,') into @nexttime from dual ');
    PREPARE stm from @v_add_a;
    EXECUTE stm;
    DEALLOCATE PREPARE stm;
    -- 将编译执行的stm结果存储到lasttimeadd中
    set nexttime=@nexttime; 
    set @v_add=CONCAT('alter table ',tableName,' add partition (partition ',CONCAT('par',p_id),' values less than (\'',nexttime,'\'))');
    PREPARE stmt from @v_add;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END

-- 创建每周生成一次表分区的定时任务
create EVENT event_sysLogWeek on SCHEDULE EVERY 1 MONTH STARTS CURRENT_TIMESTAMP
on COMPLETION PRESERVE
ENABLE
DO call  pro_sys_logByWeekDay('sys_log_storage','createtime','Week');

-- 创建每天生成一次表分区的定时任务
create EVENT event_sysLogDay on SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP
on COMPLETION PRESERVE
ENABLE
DO call  pro_sys_logByWeekDay('sys_log_storage','createtime','day');

一个刚升级为奶爸的码农的个人整理。

引用\[1\]: MySQL支持多种分区类型,包括RANGE分区、LIST分区、HASH分区和KEY分区。RANGE分区是基于一个给定连续区间的列值,将多行分配给分区。LIST分区类似于RANGE分区,但是是基于列值匹配一个离散值集合中的某个值来进行选择。HASH分区是基于用户定义的达式的返回值来进行选择的分区,该达式使用将要插入到中的这些行的列值进行计算。KEY分区类似于HASH分区,但是只支持计算一列或多列,并且MySQL服务器提供其自身的哈希函数。\[1\] 引用\[2\]: 分区是将物理上截断成多个小块,但在逻辑上仍然是一个整体。分区的好处包括提高数据操作的效率和便于存储管理。当的数据量过大时,分区可以减少对全的操作,提高查询和更新的速度。此外,如果的数据量超过了磁盘的存储容量,可以将数据分配到不同的磁盘上,解决存储空间不足的问题。\[2\] 引用\[3\]: 创建分区存储过程可以通过以下步骤实现: 1. 创建一个存储过程,使用CREATE PROCEDURE语句。 2. 在存储过程中使用CREATE TABLE语句创建分区,并指定分区类型和分区键。 3. 在存储过程中使用ALTER TABLE语句添加分区。 4. 在存储过程中使用INSERT INTO语句向分区中插入数据。 5. 调用存储过程来执行创建分区的操作。 需要注意的是,创建分区存储过程需要根据具体的需求和分区类型进行相应的设置和操作。\[3\] #### 引用[.reference_title] - *1* *2* *3* [mysql创建表分区详细介绍及示例](https://blog.csdn.net/weixin_44462773/article/details/128013794)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值