procedure简单来说就跟写程序一样,只是procedure是运用资料库的程序语言,透过不同语言逻辑的语法来达到相同目的。
预告: 这边实作逻辑拆分上大致上会分个3天,带各位一步一步实作整个流程~
每个新环境的开始就是要 Hello World
ps.复制时附注内容记得要删掉才能执行喔
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
)
(需求拆分)
概念: 捞资料表最旧的那笔记录时间当作第一个分区。
假设最旧日期为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分区重组的方式。
贴心提醒: 一样注解要拿掉才能跑嘿
* 建立一个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)
今天的内容先到这边~明天继续後续的流程
index=mft_log sourcetype="mft:xferlog" ...
Mac 剪片趣 身边很多图像与影音工作者,如插画师, 影片剪辑师, 摄影师 都是使用 mac 电脑来...
Hello,各位好! 虽然已经完成比赛了,但还是想追加一篇来聊聊我的参赛感想,也作为初次参与铁人赛的...
本系列文之後也会置於个人网站 帐号(User) 基本讯息 接着来看看与帐号有关的设定。 在之前,已...
前言 这两天花了满多心力在介绍 FP 的观念跟方法,但其实大部分都停留在理论,或者教科书上的那种 a...