Day.26 实务应用 - 实作表自动分区管理( event / procedure / partition )_1

procedure简单来说就跟写程序一样,只是procedure是运用资料库的程序语言,透过不同语言逻辑的语法来达到相同目的。
预告: 这边实作逻辑拆分上大致上会分个3天,带各位一步一步实作整个流程~

每个新环境的开始就是要 Hello World

ps.复制时附注内容记得要删掉才能执行喔/images/emoticon/emoticon33.gif

Example. 新增一个简单的procedure名为 hello_proc()

DELIMITER ||    -- 重新定义SQL结束符号(必要&自定义符号可变)
DROP PROCEDURE IF EXISTS hello_proc || --存在时先删除(加了就不用每次修改逻辑内容都得先删除在新增)
CREATE PROCEDURE hello_proc()  --建立procedure 

-- (BEGIN 开始/ END 结尾) 之间的部分为写逻辑的区块
BEGIN

--变数宣告赋值 
SET @val = 'hello world';
--输出
SELECT @val; 

END || 

-- 恢复原本的结束符号
DELIMITER ;

Q: 有了上面的procedure如何呼叫它!?

A: 使用CALL指令执行procedure


mysql> CALL hello_proc();
+-------------+
| @val        |
+-------------+
| hello world |
+-------------+
1 row in set (0.00 sec)

如果要带参数怎麽办? 来看以下简单IF-ELSE逻辑范例判断输入值大小。


DELIMITER || 
DROP PROCEDURE IF EXISTS t1_proc ||  
CREATE PROCEDURE t1_proc(v1 INT(10))
BEGIN
        --定义变数型态
        DECLARE val INT(10);
        --变数赋值
        SET val = v1;

        IF val < 10 THEN
			SET @CHECK = "TRUE";
        ELSE
			SET @CHECK = "FALSE";
        END IF;

		SELECT @CHECK;
END||
DELIMITER ;

mysql> call t1_proc(7);
+--------+
| @CHECK |
+--------+
| TRUE   |
+--------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

简单的认识如何使用後,在来进入正题罗~

  • 情境模拟

有一个尚未切分区的资料表act,且本身已经有资料在内了,想用该表栏位created_at(建立时间)当做partition key切表,除了切分区还要能达到自动新增分区与删除旧资料分区的动作,方便资料上的维护。

CREATE TABLE `act` (
  `actives_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `status` bigint(20) NOT NULL,
  `start_time` int(11) unsigned NOT NULL,
  `end_time` int(11) unsigned NOT NULL,
  `platform_id` bigint(20) DEFAULT NULL,
  `updated_at` int(11) unsigned NOT NULL,
  `created_at` int(11) unsigned NOT NULL,
  PRIMARY KEY (`actives_id`)
);

  • 需求准备

(前置)

既然要当作partition key 须先将该栏位与原PK结合成复合主键。(actives_id,created_at)

(需求拆分)

  1. 能判断原资料表有无做分区,没有的话捞资料表纪录最旧的那笔记录时间当作第一个分区,建立基础分区资讯。

概念: 捞资料表最旧的那笔记录时间当作第一个分区。

假设最旧日期为1632499200(2021-09-25 00:00:00) GMT +8 

将表中现有资料先新增以下基础分区 (第一天的分区 & pmax)。 
ALTER TABLE `active`.`act` PARTITION BY RANGE (`created_at`) (
    PARTITION p20210924 VALUES LESS THAN (1632528000),
    PARTITION pmax VALUES LESS THAN MAXVALUE 
);

之後的日期分区新增使用pmax分区重组的方式。
  • 实作流程

贴心提醒: 一样注解要拿掉才能跑嘿/images/emoticon/emoticon14.gif

  * 建立一个procedure检查分区: check_part()
   
  * 可带入参数: 1.资料库名称 2.资料表名称
   
  * 流程上会针对partition key型态&表去写,使用时要记得修改小部分内容。
     1. partition key不同型态转换分区的逻辑
     2. 查询直接写死表名称的地方
DELIMITER ||  
DROP PROCEDURE IF EXISTS check_part ||  
CREATE PROCEDURE check_part(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64))
BEGIN   

DECLARE isexist_partition varchar(255) default ''; --判断表是否存在分区
DECLARE old_date VARCHAR(255);  --资料中最早纪录的日期
DECLARE new_p_description VARCHAR(255); --切分区用的分区描述
DECLARE new_p_name VARCHAR(255); --切分区用的分区名称
--判断是否存在分区
select partition_name into isexist_partition from information_schema.partitions where table_schema = IN_SCHEMANAME  and table_name = IN_TABLENAME limit 1;

--资料表没有分区就做新增分区动作
IF isexist_partition <=> NULL THEN 
	SET @p_check = "The table has no partition。 STEP: Add table partition";
    SELECT @p_check;
    
    --捞最早的一笔日期
    select date(from_unixtime(`created_at`)) into old_date  from `act` order by `created_at` asc limit 1 ;
	SET old_date = REPLACE(old_date, '-', ''); 

	SET new_p_name = DATE_FORMAT(old_date, 'p%Y%m%d');
	SET new_p_description = unix_timestamp(old_date + INTERVAL 1 DAY);
	SET @SQL = CONCAT('ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`', ' PARTITION BY RANGE (`created_at`) (PARTITION ', new_p_name, ' VALUES LESS THAN (', new_p_description, '),PARTITION pmax VALUES LESS THAN MAXVALUE );');	
	SELECT @SQL;
    PREPARE stmt FROM @SQL;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

END IF;

SET @STEP = "STEP: check partition [ PASS ]";
SELECT @STEP; 
  
END || 
DELIMITER ;

  • 成果浏览

    • 假设资料表已存在分区
mysql> call check_part('active','act');
+--------------------------------+
| @STEP                          |
+--------------------------------+
| STEP: check partition [ PASS ] |
+--------------------------------+
1 row in set (0.01 sec)
  • 清除表分区定义再试一次
 ALTER TABLE act REMOVE PARTITIONING;
  • 资料表尚未存在分区的执行显示
mysql> call check_part('active','act');
+------------------------------------------------------+
| @p_check                                             |
+------------------------------------------------------+
| The table has no partition STEP: Add table partition |
+------------------------------------------------------+
1 row in set (0.01 sec)

+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
| @SQL                                                                                                                                                        |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ALTER TABLE `active`.`act` PARTITION BY RANGE (`created_at`) (PARTITION p20210924 VALUES LESS THAN (1632528000),PARTITION pmax VALUES LESS THAN MAXVALUE ); |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

+--------------------------------+
| @STEP                          |
+--------------------------------+
| STEP: check partition [ PASS ] |
+--------------------------------+
1 row in set (0.10 sec)

Query OK, 0 rows affected (0.10 sec)

今天的内容先到这边~明天继续後续的流程/images/emoticon/emoticon34.gif


<<:  资料库 组别

>>:  使用Vertex汇出的模型 | ML#Day26

Splunk-SPL

index=mft_log sourcetype="mft:xferlog" ...

day9_MacOs ARM 的剪辑工作之旅

Mac 剪片趣 身边很多图像与影音工作者,如插画师, 影片剪辑师, 摄影师 都是使用 mac 电脑来...

完赛感言

Hello,各位好! 虽然已经完成比赛了,但还是想追加一篇来聊聊我的参赛感想,也作为初次参与铁人赛的...

Day26 - 【概念篇】Keycloak使用基本概念 - 第二部分: User & Group

本系列文之後也会置於个人网站 帐号(User) 基本讯息 接着来看看与帐号有关的设定。 在之前,已...

Day 10 - Functional Programming 初探 (3) - 实战购物车流程

前言 这两天花了满多心力在介绍 FP 的观念跟方法,但其实大部分都停留在理论,或者教科书上的那种 a...