KingbaseES例程_普通表在线转分区表(基于规则)
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例程_普通表在线转分区表(基于规则)的更多相关文章
- Oracle在线重定义(online redefinition)--将普通表改为分区表
使用Oracle的在线重定义技术,可以将Oracle的普通表改为分区表.操作如下: STEP1:测试表是否可以在线重定义,这里以unixdev数据库的LIJIAMAN.BSTEST为例 EXEC DB ...
- Oracle表空间及分区表
(1) 表空间及分区表的概念表空间: 是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间.分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应 ...
- 使用导出导入(datapump)方式将普通表切换为分区表
随着数据库数据量的不断增长,有些表须要由普通的堆表转换为分区表的模式. 有几种不同的方法来对此进行操作,诸如导出表数据,然后创建分区表再导入数据到分区表:使用EXCHANGE PARTITION方式来 ...
- ORACLE普通表转换成分区表
转http://mp.weixin.qq.com/s?__biz=MzAwMjkyMjEwNg==&mid=2247484761&idx=1&sn=ce080581145931 ...
- Oracle大表改为分区表及表空间切换方案
Oracle大表改为分区表及表空间切换方案 一. 背景 由于之前数据库表和索引放在一个表空间导致表空间数据文件增长太快,文件数量即将达到Oracle表空间的限制,需要对表(没有分 ...
- KingbaseES R3 读写分离集群在线扩容案例
案例说明: 1. 通过sys_basebackup创建新备库. 2. 将备库加入到Cluster nodes管理,可以用kingbase_monitor.sh一键启停. 3. 主备复制切换测试. 此次 ...
- SQL Server 2005中的分区表(三):将普通表转换成分区表(转)
在设计数据库时,经常没有考虑到表分区的问题,往往在数据表承重的负担越来越重时,才会考虑到分区方式,这时,就涉及到如何将普通表转换成分区表的问题了. 那么,如何将一个普通表转换成一个分区表 呢?说到底, ...
- Docker入门实战_正版电子书在线阅读_百度阅读
Docker入门实战_正版电子书在线阅读_百度阅读 Docker入门实战
- SQL Server 2005中的分区表(三):将普通表转换成分区表
在设计数据库时,经常没有考虑到表分区的问题,往往在数据表承重的负担越来越重时,才会考虑到分区方式,这时,就涉及到如何将普通表转换成分区表的问题了. 那么,如何将一个普通表转换成一个分区表 呢?说到底, ...
- 关于我们_ | 腕表时代watchtimes.com.cn
关于我们_ | 腕表时代watchtimes.com.cn 关于我们 腕表时代是北京兰会时光科技有限公司旗下运营的手表网站.腕表时代于2013年5月17日正式上线.秉承专业.生动.实用 ...
随机推荐
- html+css:小米顶部菜单+二级菜单
1.源码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- win32 - WriteConsoleA 的使用
#include <Windows.h> #include <stdio.h> #pragma warning(disable:4996) void PasswordCheck ...
- Taro兼容h5的一些小问题
背景:先做了小程序,现在需要兼容h5 问题一:Image组件mode属性设置为aspectFill在h5上没效果 解决方法:给img加样式 object-fit: cover (例子如下) // js ...
- 微服务程序运行步骤及nameko入门案例
首先一个微服务应用程序需要有服务的生产者和服务的消费者,另外还需要一个注册中心来管理和调度服务 1.服务提供方,即生产者启动服务,并将服务提交到注册中心注册服务 2.服务需求方,即消费者连接到注册中心 ...
- 我的第一个项目(十三) :组件间传值的一些方案(vuex,eventbus,localStorage)
好家伙, 先说一下我的需求,我要组件间传值 1.eventBus 前端兄弟组件传值eventbus无法使用 不报错也不触发,就很奇怪 //eventBus.js import Vue from & ...
- 【Azure 应用服务】App Service For Linux 环境中,如何修改 Nginx 配置中 server_name的默认值 example.com
问题描述 在App Service for Linux环境中,部署PHP应用,使用Nginx服务器.因为PHP应用中所有静态资源的URL使用的默认域名为 https://example.com:808 ...
- require和import的区别以及相互使用的方式
Node.js 里可分为 CommonJS 模块和 ECMAScript 模块(ESM)两种不同的模块系统. CommonJS 模块是 Node.js 最初支持的模块系统,它使用 require() ...
- spark读取和处理zip、gzip、excel、等各种文件最全的技巧总结
一.当后缀名为zip.gzip,spark可以自动处理和读取 1.spark非常智能,如果一批压缩的zip和gzip文件,并且里面为一堆text文件时,可以用如下方式读取或者获取读取后的schema ...
- 探索Terraform实践:优化基础设施管理
Terraform 是管理基础设施及代码(IaC)最常用的工具之一,它能使我们安全且可预测地对基础设施应用更改. Terraform作为一个强大的基础设施即代码工具,为开发人员和运维团队提供了一种简单 ...
- spring 注入参数时为list map写法用例
导包基础:这了让服务器支持json 需要导入下面包 <dependency> <groupId>com.alibaba</groupId> <artifact ...