KingbaseES例程_普通表在线转分区表

概述

普通表转分区表,使用视图的替换式规则,以路由方式,实现在线转移数据。

数据准备

/*普通大表*/
create table tab_single
as
select id, (random() * 100)::int + 1 c1, md5(id::text) name
from generate_series(1, 10000000) id; alter table tab_single add primary key (id); /*表结构一样的分区表*/
create table tab_part
( like tab_single )
partition by list (c1)
;
select format($$ create table tab_part_%s partition of tab_part for values in ( %s ) $$, id, id)
from generate_series(1, 100) id \gexec /*分区表可以创建查询所需的索引*/
create index idx_tab_part_id on tab_part(id); /*创建合并视图,作为操作入口*/
create or replace view tab_view as
select *
from tab_single
union all
select *
from tab_part; /*视图不可更新*/
update tab_view
set name = 'a'
where id = 1;
[55000] ERROR: cannot update view "tab_view" 详细:Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable. 建议:To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.

通过规则实现视图更新

INSERT 规则

/*NEW数据,插入到分区表*/
CREATE or replace RULE rul_ins_tab_view
AS ON INSERT TO tab_view
DO INSTEAD insert into tab_part
select new.*; insert into tab_view
select id + 10000000, (random() * 100)::int + 1 c1, 'a' name
from generate_series(1, 10) id; /*新数据插入到分区表*/
select count(*) from tab_part;
count
-------
10
(1 row)

DELETE 规则


CREATE or replace RULE rul_del_tab_view
AS ON DELETE TO tab_view
DO INSTEAD (
delete
from tab_single
where row (tab_single.*) = row (old.*) ;
delete
from tab_part
where row (tab_part.*) = row (old.*);
); delete
from tab_view
where id = 10; /*旧数据从普通表删除*/
select *
from tab_single
where id = 10;
id | c1 | name
----+----+------
(0 rows)

UPDATE 规则

/*
* 1. 更新分区表的数据
* 2. 如果分区表没有旧数据,则分区表插入新新数据
* 3. 删除普通表的旧数据
*/ CREATE or replace RULE rul_upd_tab_view
AS ON UPDATE TO tab_view
DO INSTEAD (
insert into tab_part
select new.*
where (select count(*) cnt
from tab_part
where row (tab_part.*) = row (new.*)) = 0; delete
from tab_single
where row (tab_single.*) = row (old.*); delete
from tab_part
where row (tab_part.*) = row (old.*)
and row (tab_part.*) != row (new.*)
and old <> new;
); /*更新在普通表数据,可以更新主键值*/
update tab_view
set name='abcde'
where id = 200; /*数据从普通表删除*/
select id, c1, name
from tab_single
where id = 200; id | c1 | name
----+----+------
(0 rows) /*数据在分区表中插入或更新*/
select id, c1, name
from tab_part
where id = 200;
id | c1 | name
-----+----+-------
200 | 89 | abcde
(1 row) /*更新在分区表数据,可以更新主键值*/
update tab_view
set id=20000000+200 ,
name='xxxxxxxx'
where id = 200; /*在分区表的数据*/
select id, c1, name
from tab_part
where id = 200;
id | c1 | name
----------+----+----------
20000200 | 52 | xxxxxxxx
(1 row)

分步转移数据


do
$$
declare
stprow int;
chgrow int;
movrow int; timstm timestamp;
begin
stprow := 10000; /*每步迁移10000行数据*/
chgrow := 0; /*实际影响的行*/
movrow := 0; /*累计迁移的行*/ loop
timstm := clock_timestamp();
with del as (delete from tab_single
where ctid = any (array(select ctid from tab_single limit stprow))
returning *)
insert into tab_part
select * from del;
commit;
get diagnostics chgrow = row_count;
exit when chgrow = 0;
movrow := movrow + chgrow;
raise info 'moved rows : % / % , % ms',chgrow, movrow, (date_part('sec',clock_timestamp()-timstm)*1000)::numeric(10,3);
end loop; end;
$$
;

SHELL脚本高并发迁移数据

time seq 0 1000 | xargs -i -n1 -P10 psql -c "update tab_view set id = id where id between 10000*{}+0 and 10000*({}+1)-1"

real    0m49.630s
user 0m0.740s
sys 0m1.315s

抛弃普通表,保留分区表

/*分区表代替视图*/
do
$$
begin
drop view tab_view;
alter table tab_part
rename to tab_view;
commit;
end;
$$
;

或者

/*保留数据入口视图,删除视图的规则,修改视图定义*/
do
$$
begin
drop RULE rul_ins_tab_view TO tab_view;
drop RULE rul_del_tab_view TO tab_view;
drop RULE rul_upd_tab_view TO tab_view; create or replace view tab_view as
select *
from tab_part; commit;
end;
$$
;

注意

DML操作,主键值可能会出现重复,但可以通过校验语句避免。

KingbaseES例程_普通表在线转分区表(基于规则)的更多相关文章

  1. Oracle在线重定义(online redefinition)--将普通表改为分区表

    使用Oracle的在线重定义技术,可以将Oracle的普通表改为分区表.操作如下: STEP1:测试表是否可以在线重定义,这里以unixdev数据库的LIJIAMAN.BSTEST为例 EXEC DB ...

  2. Oracle表空间及分区表

    (1) 表空间及分区表的概念表空间: 是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间.分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应 ...

  3. 使用导出导入(datapump)方式将普通表切换为分区表

    随着数据库数据量的不断增长,有些表须要由普通的堆表转换为分区表的模式. 有几种不同的方法来对此进行操作,诸如导出表数据,然后创建分区表再导入数据到分区表:使用EXCHANGE PARTITION方式来 ...

  4. ORACLE普通表转换成分区表

    转http://mp.weixin.qq.com/s?__biz=MzAwMjkyMjEwNg==&mid=2247484761&idx=1&sn=ce080581145931 ...

  5. Oracle大表改为分区表及表空间切换方案

    Oracle大表改为分区表及表空间切换方案 一.            背景 由于之前数据库表和索引放在一个表空间导致表空间数据文件增长太快,文件数量即将达到Oracle表空间的限制,需要对表(没有分 ...

  6. KingbaseES R3 读写分离集群在线扩容案例

    案例说明: 1. 通过sys_basebackup创建新备库. 2. 将备库加入到Cluster nodes管理,可以用kingbase_monitor.sh一键启停. 3. 主备复制切换测试. 此次 ...

  7. SQL Server 2005中的分区表(三):将普通表转换成分区表(转)

    在设计数据库时,经常没有考虑到表分区的问题,往往在数据表承重的负担越来越重时,才会考虑到分区方式,这时,就涉及到如何将普通表转换成分区表的问题了. 那么,如何将一个普通表转换成一个分区表 呢?说到底, ...

  8. Docker入门实战_正版电子书在线阅读_百度阅读

    Docker入门实战_正版电子书在线阅读_百度阅读 Docker入门实战

  9. SQL Server 2005中的分区表(三):将普通表转换成分区表

    在设计数据库时,经常没有考虑到表分区的问题,往往在数据表承重的负担越来越重时,才会考虑到分区方式,这时,就涉及到如何将普通表转换成分区表的问题了. 那么,如何将一个普通表转换成一个分区表 呢?说到底, ...

  10. 关于我们_ | 腕表时代watchtimes.com.cn

    关于我们_ | 腕表时代watchtimes.com.cn 关于我们         腕表时代是北京兰会时光科技有限公司旗下运营的手表网站.腕表时代于2013年5月17日正式上线.秉承专业.生动.实用 ...

随机推荐

  1. SpringBoot+Shiro+LayUI权限管理系统项目-7.实现用户管理

    1.说明 只讲解关键部分,详细看源码,文章下方捐赠或QQ联系捐赠获取. 2.功能展示 包括用户增删改查和分配角色. 3.业务模型 @Data @EqualsAndHashCode(callSuper ...

  2. Oracle 表压缩(Table Compression)技术介绍

    Oracle 表压缩(Table Compression)介绍 1.官方文档说法: As your database grows in size, consider using table compr ...

  3. win32 - 创建带有标准阴影的无边框窗口

    这个框框好像删不掉,就先放这边吧...   #define WIN32_LEAN_AND_MEAN #include <unknwn.h> #include <windows.h&g ...

  4. Dubbo使用APISIX作为网关

    为什么使用网关 Dubbo服务本身没有暴露HTTP接口,客户端(如:Web,APP)无法直接调用其提供的方法. 而APISIX可以通过dubbo-proxy插件为Dubbo服务提供外部访问的HTTP接 ...

  5. defaultdict高级用法

    说明 defaultdict数据结构允许调用者提供一个函数,用来在键名缺失的情况下,创建与这个 键对应的值.只要字典发现调用者想要访问的键不存在,就会触发这个函数,以返回应该 与键相关联的默认值 下面 ...

  6. java图书管理系统(桌面版本)

    运行效果: 注册登陆界面 注册存在的账户时 ​ 登陆之后主界面如下 点击图书管理-图书更新界面如下 图书列表 项目说明: 由于平时工作比较忙,也没时间写,可是我在公众号后台看见好多小伙伴讨论,我就抽时 ...

  7. 【Azure Function】Function本地调试时遇见跨域问题(blocked by CORS policy)

    问题描述 在本地调试Azure Function时,遇见了跨域问题: Access to XMLHttpRequest at 'http://localhost:7071/api/HttpTrigge ...

  8. 手机使用termux部署alist(一起体验alist挂载云盘)

    termux安装alist 安装termux 软件Termux:https://f-droid.org/packages/com.termux/ pkg install vim pkg install ...

  9. 借助 Terraform 功能协调部署 CI/CD 流水线-Part 1

    在当今快节奏的开发环境中,实现无缝.稳健的 CI/CD 流水线对于交付高质量软件至关重要.在本文中,我们将向您介绍使用 Bitbucket Pipeline.ArgoCD GitOps 和 AWS E ...

  10. Zabbix6.0使用教程 (一)—zabbix新增功能介绍2

    上一篇我们已经介绍了部分zabbix6.0的新增功能,这期我们将继续为家详细介绍下余下的zabbix6.0新增功能,大家可以往下看. 六.监控项 6.1 自动类型选择 监控项配置表单会自动建议匹配的信 ...