Greenplum 生成加分区语句
在使用greenplum中会使用分区表,但同时分区表需要维护分区;比如加分区,这个过程比较痛苦,查询相关资料以后有了相应的解决办法,但是该办法也不是万能的,有诸多限制,关于限制有兴趣的同学可以查看我文章最后提到的参考资料。
创建2个表(range分区表和list分区表)
CREATE TABLE tb1_partition_list_yyyymmdd (
id numeric,
yyyymmdd character varying(128)
)
WITH (appendonly=true, compresslevel=5) DISTRIBUTED BY (id) PARTITION BY LIST(yyyymmdd)
(
PARTITION p20120811 VALUES('') WITH (tablename='tb1_partition_list_yyyymmdd_1_prt_p20120811', orientation=row , appendonly=true, compresslevel=5 ),
PARTITION p20120812 VALUES('') WITH (tablename='tb1_partition_list_yyyymmdd_1_prt_p20120812', orientation=row , appendonly=true, compresslevel=5 )
);
CREATE TABLE tb1_partition_range_yyyymmdd (
id numeric,
yyyymmdd date
)
WITH (appendonly=true, compresslevel=5) DISTRIBUTED BY (id) PARTITION BY RANGE(yyyymmdd)
(
PARTITION p20120811 START ('2012-08-11'::date) END ('2012-08-12'::date) WITH (tablename='tb1_partition_range_yyyymmdd_1_prt_p20120811', orientation=row , appendonly=true, compresslevel=5 ),
PARTITION p20120812 START ('2012-08-12'::date) END ('2012-08-13'::date) WITH (tablename='tb1_partition_range_yyyymmdd_1_prt_p20120812', orientation=row , appendonly=true, compresslevel=5 )
);
上面分别创建了list分区表和range分区表。
下面创建一个辅助视图:
CREATE VIEW v_pg_add_partitions AS
SELECT pp.parrelid AS tableoid, prl.parchildrelid, prl.parname AS partitionname, CASE WHEN (pp.parkind = 'h'::"char") THEN 'hash'::text WHEN (pp.parkind = 'r'::"char") THEN 'range'::text WHEN (pp.parkind = '
l'::"char") THEN 'list'::text ELSE NULL::text END AS partitiontype, translate(pg_get_expr(prl.parlistvalues, prl.parchildrelid), '-'':date character varying bpchar numeric double precision timestamp without time
zone'::text, ''::text) AS partitionlistvalue, "substring"(translate(pg_get_expr(prl.parrangestart, prl.parchildrelid), '-'':date character varying bpchar numeric double precision timestamp without time zone'::t
ext, ''::text), 1, 8) AS partitionrangestart, "substring"(translate(pg_get_expr(prl.parrangeend, prl.parchildrelid), '-'':date character varying bpchar numeric double precision timestamp without time zone'::text
, ''::text), 1, 8) AS partitionrangeend, prl.parruleord AS partitionposition, (("substring"(prl.parlistvalues, 'consttype ([0-9]+)'::text))::integer)::regtype AS listtype, (("substring"(prl.parrangeend, 'constty
pe ([0-9]+)'::text))::integer)::regtype AS rangetype FROM pg_partition pp, pg_partition_rule prl WHERE ((pp.paristemplate = false) AND (prl.paroid = pp.oid));
接下来创建生成添加分区表的命令的函数:
create or replace function add_partition_info(tableoid oid,days_from_now integer)
returns setof text
as $$
import datetime
def now():
d=datetime.datetime.now()
format='%Y%m%d'
return datetime.datetime.strftime(d,format) def add_day(d,n):
format='%Y%m%d'
d2=datetime.datetime.strptime(d,format)
d3=d2+datetime.timedelta(days=n)
return datetime.datetime.strftime(d3,format) def add_month(d,n):
format='%Y%m%d'
formatymd='%Y%m01'
if d.__len__() == 6:
format='%Y%m'
formatymd='%Y%m'
d2=datetime.datetime.strptime(d,format)
d3=d2+datetime.timedelta(days=31*n)
return datetime.datetime.strftime(d3,formatymd) relist=[]
sql=""" select * from (select *,tableoid::regclass tablename,lead(case when partitionrangeend <> '' then partitionrangeend else partitionlistvalue end) over (partition by tableoid order by partitionposition desc) as pre_value,row_number() over (partition by tableoid order by partitionposition desc) rn from v_pg_add_partitions where substr(partitionname,1,3)='p20' and tableoid=%s) t where rn=1;""" % (tableoid);
rv=plpy.execute(sql);
sql_relation="select array_to_string(reloptions,',') reloptions from pg_class where oid=%s" % (tableoid)
rv_relation=plpy.execute(sql_relation) if rv.nrows()!=1:
return None
else:
reloptions = rv_relation[]['reloptions']
tablename=rv[]['tablename']
partitiontype=rv[]['partitiontype']
partitionname=rv[]['partitionname']
pre_value=rv[]['pre_value']
now_add_7days=add_day(now(),days_from_now) if partitiontype=='range':
rangetype=rv[]['rangetype']
partitionrangestart=rv[]['partitionrangestart']
partitionrangeend=rv[]['partitionrangeend']
interval = int(partitionrangeend) - int(pre_value) if partitionname.__len__()==7:
func_add=add_month
interval=int(partitionrangeend[0:6]) - int(pre_value[0:6]) elif partitionname.__len__()==9:
func_add=add_day else:
return None
while partitionrangestart < now_add_7days:
partitionrangestart = func_add(partitionrangestart,interval)
partitionrangeend = func_add(partitionrangeend,interval)
partitionname="p"+func_add(partitionname[1:],interval)
add_sql = "alter table %s add partition %s start ('%s'::%s) end ('%s'::%s) " % (tablename,partitionname,partitionrangestart,rangetype,partitionrangeend,rangetype)
if reloptions != None and reloptions != '':
add_sql+='with (%s);' % (reloptions)
else:
add_sql+=";"
relist.append(add_sql) if partitiontype=='list':
listtype=rv[]['listtype']
partitionlistvalue=rv[]['partitionlistvalue']
interval=int(partitionlistvalue) - int(pre_value) if partitionname.__len__()==7:
func_add = add_month elif partitionname.__len__()==9:
func_add=add_day else:
return None
while partitionlistvalue < now_add_7days:
partitionlistvalue=func_add(partitionlistvalue,interval)
partitionname="p"+func_add(partitionname[1:],interval)
add_sql="alter table %s add partition %s values ('%s'::%s)" % (tablename,partitionname,partitionlistvalue,listtype)
if reloptions != None and reloptions != '':
add_sql +='with (%s);' % (reloptions)
else:
add_sql+=";"
relist.append(add_sql)
return relist
$$ LANGUAGE plpythonu;
最后我们进行测试(增加当前时间3天内的分区)
test_db=# SELECT add_partition_info('tb1_partition_range_yyyymmdd'::regclass,3);
                                                                    add_partition_info
----------------------------------------------------------------------------------------------------------------------------------------------------------
 alter table tb1_partition_range_yyyymmdd add partition p20120813 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120814 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120815 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120816 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120817 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120818 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120819 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120820 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120821 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120822 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120823 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120824 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120825 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120826 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120827 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120828 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120829 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120830 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120831 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120901 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120902 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120903 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120904 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120905 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120906 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120907 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120908 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
 alter table tb1_partition_range_yyyymmdd add partition p20120909 start (''::date) end (''::date) with (appendonly=true,compresslevel=5);
再创建一个range分区且是按月分区的表
CREATE TABLE tb1(
id numeric,
yyyymmdd date
)DISTRIBUTED BY (id) PARTITION BY RANGE(yyyymmdd)
(
PARTITION p201208 START ('2012-08-01'::date) END ('2012-09-01'::date) ,
PARTITION p201209 START ('2012-09-01'::date) END ('2012-10-01'::date)
);
test_db=# SELECT add_partition_info('tb1'::regclass,1);
                                   add_partition_info
-----------------------------------------------------------------------------------------
 alter table tb1 add partition p201210 start (''::date) end (''::date) ;
 alter table tb1 add partition p201211 start (''::date) end (''::date) ;
 alter table tb1 add partition p201212 start (''::date) end (''::date) ;
 alter table tb1 add partition p201301 start (''::date) end (''::date) ;
 alter table tb1 add partition p201302 start (''::date) end (''::date) ;
 alter table tb1 add partition p201303 start (''::date) end (''::date) ;
 alter table tb1 add partition p201304 start (''::date) end (''::date) ;
 alter table tb1 add partition p201305 start (''::date) end (''::date) ;
 alter table tb1 add partition p201306 start (''::date) end (''::date) ;
 alter table tb1 add partition p201307 start (''::date) end (''::date) ;
 alter table tb1 add partition p201308 start (''::date) end (''::date) ;
 alter table tb1 add partition p201309 start (''::date) end (''::date) ;
 alter table tb1 add partition p201310 start (''::date) end (''::date) ;
 alter table tb1 add partition p201311 start (''::date) end (''::date) ;
 alter table tb1 add partition p201312 start (''::date) end (''::date) ;
 alter table tb1 add partition p201401 start (''::date) end (''::date) ;
 alter table tb1 add partition p201402 start (''::date) end (''::date) ;
 alter table tb1 add partition p201403 start (''::date) end (''::date) ;
 alter table tb1 add partition p201404 start (''::date) end (''::date) ;
 alter table tb1 add partition p201405 start (''::date) end (''::date) ;
 alter table tb1 add partition p201406 start (''::date) end (''::date) ;
 alter table tb1 add partition p201407 start (''::date) end (''::date) ;
 alter table tb1 add partition p201408 start (''::date) end (''::date) ;
 alter table tb1 add partition p201409 start (''::date) end (''::date) ;
 alter table tb1 add partition p201410 start (''::date) end (''::date) ;
 alter table tb1 add partition p201411 start (''::date) end (''::date) ;
 alter table tb1 add partition p201412 start (''::date) end (''::date) ;
可以看见也是没有问题的。
参考资料:
《greenplum企业应用实战》
Greenplum 生成加分区语句的更多相关文章
- sqlserver 表中记录生成insert,可以加条件,可以生成建表语句
		sqlserver 表中记录生成insert,可以加条件,可以生成建表语句 create PROCEDURE [sp_getinsert] ( ) , --如果非默认架构,可以加上架构名 例如:sch ... 
- GreenPlum数据加载
		1. copy命令 对于数据加载,GreenPlum数据库提供copy工具,copy工具源于PostgreSQL数据库,copy命令支持文件与表之间的数据加载和表对文件的数据卸载.使用copy命令进行 ... 
- phalcon  Model 'partitions' could not be loaded(模型不支持分区语句)
		注意: 很明确提示用phalcon自带的模型层是不能用partition这个关键字的 解决方法: 自己写个PDO类 然后用pdo中的query方法执行语句成功: mysql分区目的 是减少数据库的负担 ... 
- h5 录音  自动生成proto Js语句  UglifyJS-- 对你的js做了什么  【原码笔记】-- protobuf.js 与 Long.js  【微信开发】-- 发送模板消息  能编程与会编程  vue2入坑随记(二) -- 自定义动态组件  微信上传图片
		得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ... 
- 快速将一个表的数据生成SQL插入语句
		将一个表中的数据生成SQL插入语句,方便系统快速初始化,在数据库中执行创建以下过程就可以了. ) Drop Procedure GenerateData go CREATE PROCEDURE Gen ... 
- 这种代码怎么改写?以致于在下次增加CustomsType时,不需要再加 if 语句。
		最近看到项目里一段代码如下: excelObject excel = new excelObject(); if (loadbill.CustomsType == 1) excel.IDownload ... 
- 使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句
		开始 EF6.1也出来不少日子了,6.1相比6.0有个很大的特点就是新增了System.Data.Entity.Infrastructure.Interception 命名空间,此命名空间下的对象可以 ... 
- 用LinqPad查看Nhibernate生成的sql语句
		使用Nhibernate开发一般都要对Nhibernate生成的sql语句进行查看及分析,查看Nhibernate生成的sql语句,可以使用NHProfiler和log4net.但NHProfiler ... 
- 【转】Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
		原文链接:http://www.cnblogs.com/quanyongan/p/3152290.html 最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 ... 
随机推荐
- SQL多表查询案例
			表结构: emp表: dept表: salgrade表: (1)查出至少有一个员工的部门.显示部门编号.部门名称.部门位置.部门人数. SELECT z.*,d.dname,d.loc FROM de ... 
- WebSocket协议开发
			一直以来,网络在很大程度上都是围绕着HTTP的请求/响应模式而构建的.客户端加载一个网页,然后直到用户点击下一页之前,什么都不会发生.在2005年左右,Ajax开始让网络变得更加动态了.但所有的HTT ... 
- BZOJ 3932 [CQOI2015]任务查询系统 ——可持久化线段树
			[题目分析] 主席树,维护区间大小以及权值之和. 但是细节确实要琢磨很久,WA了几次. [代码] #include <cstdio> #include <cstring> #i ... 
- 我的c++学习(7)引用和复制构造函数
			一.引用 什么是引用? 引用又称别名(alias),是一种非常特殊的数据类型.它不是定义一个新的变量,而是给一个已经定义的变量重新起一个别名,也就是 C++系统不为引用类型变量分配内存空间.引用主要用 ... 
- java获取日期
			/* * 获取昨天日期 方法一,这个方法好像有点慢 */Date dt = new Date(); Calendar cal = Calendar.getInstance();cal.add(Cale ... 
- ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 I. Illegal or Not?
			I. Illegal or Not? time limit per test 1 second memory limit per test 512 megabytes input standard i ... 
- BZOJ4378 : [POI2015]Logistyka
			对于每个询问,设不小于$s$的个数为$cnt$,小于$s$的和为$sum$. 那么如果可以进行$s$轮,当且仅当$sum\geq (c-cnt)\times s$. 权值线段树维护,时间复杂度$O(m ... 
- Hive内部表外部表转化分析(装)
			link:http://anyoneking.com/archives/127hive表分为内部表和外部表.外部表在删除的时候并不会删除到hdfs中的文件,比较安全,所以对于重要的需要进行分析的日志建 ... 
- foxmail配置office365邮箱
			公司用的是office365套装,由于一直不习惯outlook点x就退出程序的设置,导致经常出现没能及时响应邮件的情况.一怒之下,把客户端改成foxmail. 邮箱客户端切换的主要问题出现在foxma ... 
- Haskell 笔记 ①
			①一切都是函数,包括常量.表达式,格式:名字 参数1 参数2.. =函数内容 ②if语句(else绝对不可以省略) F=if (..) then x else y ③没有数组,只有列表[1,2,3,4 ... 
