mysql的分区表

打印 上一主题 下一主题

主题 816|帖子 816|积分 2448

1.SQL表创建
下面以时间范围进行创建(每月一个分区,表中创建了四个月的分区)
  1. 创建:
  2. CREATE TABLE test_table (  
  3.     id INT NOT NULL AUTO_INCREMENT,  
  4.     content VARCHAR(255),  
  5.     create_time DATETIME NOT NULL,
  6.    PRIMARY KEY (id, create_time)
  7. ) PARTITION BY RANGE (TO_DAYS(create_time)) (  
  8.     PARTITION p20240601 VALUES LESS THAN (TO_DAYS('2024-06-01')),  
  9.     PARTITION p20240701 VALUES LESS THAN (TO_DAYS('2024-07-01')),  
  10.     PARTITION p20241801 VALUES LESS THAN (TO_DAYS('2024-08-01')),  
  11.     PARTITION p20240901 VALUES LESS THAN (TO_DAYS('2024-09-01'))
  12. );  
  13. 查询分区详情:
  14. SELECT *
  15. FROM
  16.     INFORMATION_SCHEMA.PARTITIONS
  17. WHERE
  18.     TABLE_NAME = 'test_table';
复制代码
2、mapper文件
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="*.infrastructure.mapper.TestTableMapper">
  6.     <resultMap id="TestTable" type="*.domain.entity.TestTable">
  7.         <id column="id" property="id" typeHandler="org.apache.ibatis.type.LongTypeHandler"/>
  8.         <result property="content" column="content" jdbcType="VARCHAR"/>
  9.         <result property="createTime" column="create_time" jdbcType="TIMESTAMP"
  10.                 typeHandler="org.apache.ibatis.type.LocalDateTimeTypeHandler"/>
  11.     </resultMap>
  12.     <!-- 创建新分区 -->
  13.     <update id="createNewPartition">
  14.         ALTER TABLE TEST_TABLE
  15.             ADD PARTITION (  
  16.                 PARTITION ${partitionName} VALUES LESS THAN (TO_DAYS(#{lessThanValue}))
  17.             )
  18.     </update>
  19.     <!-- 删除旧分区 -->
  20.     <update id="dropPartition">
  21.         ALTER TABLE TEST_TABLE
  22.         DROP
  23.         PARTITION
  24.         ${partitionName}
  25.     </update>
  26.     <!--查询是否存在分区-->
  27.     <select id="exitsPartition" resultType="boolean">
  28.         SELECT COUNT(1) > 0
  29.         FROM INFORMATION_SCHEMA.PARTITIONS
  30.         WHERE TABLE_NAME = 'TEST_TABLE'
  31.           AND PARTITION_NAME = #{partitionName}
  32.     </select>
  33. </mapper>
复制代码
3、service
  1. package *.domain.service;
  2. import *.domain.entity.TestTable;
  3. import *.infrastructure.repo.TestTableRepository;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.dao.DataAccessException;
  6. import org.springframework.stereotype.Service;
  7. import java.time.LocalDate;
  8. import java.time.LocalDateTime;
  9. import java.time.YearMonth;
  10. import java.time.format.DateTimeFormatter;
  11. import java.util.Random;
  12. @Service
  13. public class TestTableService {
  14.     @Autowired
  15.     TestTableRepository repository;
  16.         // 插入数据,如果分区不存在,就创建分区,重新插入
  17.     public void insert() {
  18.         TestTable testTable = new TestTable();
  19.         testTable.setContent("test");
  20.         Random random = new Random();
  21.         int i = Math.abs(random.nextInt()) % 365;
  22.         LocalDateTime dateTime = LocalDateTime.now().minusDays(i);
  23.         testTable.setCreateTime(dateTime);
  24.         try {
  25.             repository.getBaseMapper().insert(testTable);
  26.         } catch (DataAccessException e) {
  27.             LocalDate nextMonthFirstDay = YearMonth.from(dateTime).plusMonths(1).atDay(1);
  28.             String lessThanValue = nextMonthFirstDay.format(DateTimeFormatter.ISO_DATE);
  29.             String partitionName = "p" + lessThanValue.replaceAll("-", "");
  30.             // 创建分区时加锁,如果是多节点,需要分布式锁
  31.             synchronized (this) {
  32.                 if (!repository.getBaseMapper().exitsPartition(partitionName)) {
  33.                     repository.getBaseMapper().createNewPartition(partitionName, lessThanValue);
  34.                 }
  35.             }
  36.             repository.getBaseMapper().insert(testTable);
  37.         }
  38.     }
  39.         // 创建分区
  40.     public void createNewPartition(String partitionName, String lessThanValue) {
  41.         repository.getBaseMapper().createNewPartition(partitionName, lessThanValue);
  42.     }
  43.         // 删除分区
  44.     public void dropPartition(String partitionName) {
  45.         repository.getBaseMapper().dropPartition(partitionName);
  46.     }
  47. }
复制代码
----------------分割线-------------------------------
上述方法用代码来判定分区,新增分区,大概会引入一些奇奇怪怪的题目,因此,优化如下:

【针对mysql,使用mysql的定时事件】
1、首先确认mysql的时间调理器是否已经开启:
  1. -- 查询事件调度器是否开启
  2. SHOW VARIABLES LIKE 'event_scheduler';
  3. -- 确保事件调度器已经开启  
  4. SET GLOBAL event_scheduler = ON;  
复制代码
2、写存储过程,用于创建新的分区, 这里是按天创建新的分区
  1. DELIMITER //  
  2.   
  3. CREATE PROCEDURE `AddDailyPartition`()  
  4. BEGIN  
  5.     DECLARE tomorrow DATE;  
  6.     DECLARE partition_name VARCHAR(20);  
  7.   
  8.     -- 计算明天的日期  
  9.     SET tomorrow = DATE_FORMAT(CURDATE() + INTERVAL 1 DAY, '%Y-%m-%d');  
  10.     SET partition_name = CONCAT('p', DATE_FORMAT(tomorrow, '%Y%m%d'));  
  11.   
  12.     -- 构建ALTER TABLE语句来添加分区  
  13.     SET @sql = CONCAT('ALTER TABLE TEST_TABLE ',  
  14.                       'ADD PARTITION (PARTITION ', partition_name,   
  15.                       ' VALUES LESS THAN (TO_DAYS(\'', tomorrow, '\')))');  
  16.   
  17.     -- 执行ALTER TABLE语句  
  18.     PREPARE stmt FROM @sql;  
  19.     EXECUTE stmt;  
  20.     DEALLOCATE PREPARE stmt;  
  21. END //  
  22.   
  23. DELIMITER ;  
复制代码
3、创建定时事件,调用存储过程
  1. -- 创建定时事件  
  2. CREATE EVENT `CreateDailyPartition`  
  3.     ON SCHEDULE EVERY 1 DAY STARTS TIMESTAMP(CURDATE())  
  4.     DO CALL AddDailyPartition();  
复制代码
4、查察已经创建的定时事件
  1. SELECT * FROM information_schema.EVENTS;
  2. 在查看事件时,重要的列包括:
  3. EVENT_NAME: 事件的名称。
  4. EVENT_SCHEMA: 事件所属的数据库。
  5. STATUS: 事件的状态,比如是否为ENABLED或DISABLED。
  6. STARTS: 事件开始的时间。
  7. ENDS: 事件结束的时间(如果有设置的话)。
  8. LAST_EXECUTED: 事件上一次执行的时间。
  9. EVENT_DEFINITION: 事件定义,即事件中要执行的SQL语句。
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张国伟

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表