postgres创建表分区

分区
       PostgreSQL支持基本的表分区功能。
概述
     分区的意思是把逻辑上的一个大表分割成物理上的几块。分区可以提供若干好处:

  • 某些类型的查询性能可以得到极大提升。特别是表中访问率较高的行位于一个单独分区或少数几个分区上的情况下。分区可以减少索引体积从而可以将高使用率部分的索引存放在内存中。如果索引不能全部放在内存中,那么在索引上的读和写都会产生更多的磁盘访问。
  • 当查询或更新一个分区的大部分记录时,连续扫描那个分区而不是使用索引离散的访问整个表可以获得巨大的性能提升。
  • 如果需要大量加载或者删除的记录位于单独的分区上,那么可以通过直接读取或删除那个分区以获得巨大的性能提升,因为ALTER TABLE比操作大量的数据要快的多。它同时还可以避免由于大量DELETE导致的VACUUM超载。
  • 很少用的数据可以移动到便宜一些的慢速存储介质上。

       这种好处通常只有在表可能会变得非常大的情况下才有价值。到底多大的表会从分区中收益取决于具体的应用, 不过有个基本的拇指规则就是表的大小超过了数据库服务器的物理内存大小。
       目前,PostgreSQL支持通过表继承进行分区。每个分区必须做为单独一个父表的子表进行创建。父表自身通常是空的,它的存在只是为了代表整个数据集。你在试图实现分区之前,应该先熟悉继承

PostgreSQL可以实现下面形式的分区:

  • 范围分区

        表被一个或者多个关键字段分区成"范围",这些范围在不同的分区里没有重叠。比如,我们可以为特定的商业对象根据数据范围分区,或者根据标识符范围分区。

  • 列表分区

       表通过明确地列出每个分区里应该出现那些关键字值实现。
实现分区
       要设置一个分区的表,做下面的步骤:

  • 创建"主表",所有分区都从它继承。
  • 这个表中没有数据,不要在这个表上定义任何检查约束,除非你希望约束同样也适用于所有分区。同样,在其上定义任何索引或者唯一约束也没有意义。
  • 创建几个"子表",每个都从主表上继承。通常,这些表不会增加任何字段。
  • 我们将把子表称作分区,尽管它们就是普通的PostgreSQL表。
  • 给分区表增加约束,定义每个分区允许的健值。
--创建序列
create sequence id_seq increment by 1 minvalue 1 no maxvalue start with 1;
--查询序列的值
select nextval('id_seq') ;
select currval('id_seq') ;
--创建日志表
CREATE TABLE ss_log
(
  id character varying(255) NOT NULL,
  createtime timestamp without time zone,
  data character varying(4000),
  model character varying(200),
  type character varying(100),
  url character varying(2000),
  userid character varying(100),
  CONSTRAINT ss_log_pkey PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ss_log
  OWNER TO postgres;


--查询日志表数据
select * from ss_log ;

truncate table ss_log ;

--插入日志信息
insert into ss_log(id,createtime,data,model,type,url,userid) values('adfadfaa3c0147044a42c70000',now() ,'data','model','1','http://','11adfda') ;

--为ss_log创建触发器,分配需要插入到日志表中的数据
CREATE TRIGGER insert_ss_log_trigger
    BEFORE INSERT ON ss_log
    FOR EACH ROW EXECUTE PROCEDURE ss_log_insert_trigger();

CREATE OR REPLACE FUNCTION ss_log_insert_trigger() RETURNS TRIGGER AS $$
declare
	table_name varchar := null ;
	log_createtime varchar := null ;
BEGIN
	log_createtime := to_char(NEW.createtime,'yyyyMMdd') ;
	select relname into table_name from pg_class where relname = 'ss_log_'||log_createtime  ;
	if table_name is null then 
		table_name := 'ss_log_'||log_createtime ;
		execute 'CREATE TABLE '||table_name||' (
			CHECK ( createtime >= '''||log_createtime||'''::timestamp  AND createtime < ('''||log_createtime||'''::timestamp + interval ''1d'') )
		)INHERITS (ss_log)';
	end if ;
	--将数据插入相应的表
	execute 'INSERT INTO '|| table_name||'(id,createtime,data,model,type,url,userid) VALUES ('''
					   ||NEW.id||''','''||NEW.createtime||''','''||NEW.data||''','''||NEW.model||''','''||NEW.type||''','''||NEW.url||''','''||NEW.userid||''')' ;
	--不向主表中查数据
	RETURN NULL;
END;
$$
LANGUAGE plpgsql;

 

猜你喜欢

转载自lpyyn.iteye.com/blog/2088473
今日推荐