欢迎投稿

今日深度:

PostgreSql Partition + Hibernate Insert,postgresqlinsert

PostgreSql Partition + Hibernate Insert,postgresqlinsert


与Oracle不同,PostgreSQL需要手动控制分区规则触发器。

步骤一:创建分区

CREATE TABLE table_partition_1( CHECK partition_column criteria) INHENRITS (table)

步骤二:为分区表创建PK跟index,这里使用btree
ALTER TABLE ONLY table_partition_1
 ADD CONSTRAINT table_partition_1_pkey PRIMARY KEY (key_column);

CREATE INDEX index_table_partition_1 ON table_partition_1  USING btree(column);

步骤三:手动创建触发器
CREATE OR REPLACE FUNCTION before_insert_table()
  RETURNS trigger AS
$BODY$
 DECLARE  
BEGIN
if criteria  then
	EXECUTE 'insert into appropriate table ...'  SELECT  ($1).* '  USING NEW;
end if;
return null;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION before_insert_table()
  OWNER TO db;

rule在批量操作时更合适,但是对于单独操作会占用较大的开销。
CREATE RULE table_partition_1 _insert AS
(criteria ...)
DO INSTEAD 
    INSERT INTO table_partition_1 VALUES (NEW.*)

步骤四:触发器方式hibernate向分区插入数据时,获得的result count为0,会导致判断失败而回滚。 解决方法是使用rule,或者声明分区插入时不进行result检查。
@SQLInsert(sql = "INSERT INTO "
		+ "table(column,...)"
		+ " VALUES(?,...)", check = ResultCheckStyle.NONE)

在Java项目中,考虑到分区创建会采用job方式自动创建,可以通过function完成创建。
CREATE OR REPLACE FUNCTION "public"."function"()
  RETURNS void AS $BODY$ 
 DECLARE  
 	 _tablename text ;
   quarter integer;
	record1 record;  
BEGIN
	select function(now()) as quarter  into record1;
  quarter := record1.quarter;
	_tablename := 'partition_name';
PERFORM 1
FROM   pg_catalog.pg_class c
WHERE  c.relname = _tablename;
	IF FOUND <> TRUE THEN
			EXECUTE 'CREATE TABLE ' || _tablename  || ' (
        CHECK ( criteria) 
     ) INHERITS (table)';
		EXECUTE 'ALTER TABLE ' || _tablename  || ' OWNER TO db ';
		EXECUTE  ' alter table ' ||   _tablename || ' add CONSTRAINT  ' || _tablename||'_pkey  PRIMARY key (column) ' ;
		EXECUTE  ' CREATE INDEX ' || _tablename|| '_index
		ON '||  _tablename ||'
		USING btree
		(column)'; 
  END IF;
END
$BODY$
  LANGUAGE 'plpgsql' VOLATILE COST 100;
ALTER FUNCTION "public"."function"() OWNER TO "db";



参考资料: entity-hibspec-customsql.html
postgresql-table-partitioning-hibernate.html



hibernate 连接postgresql数据库存储对象出错

increment
用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。

identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。

sequence
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。

hilo
使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。

seqhilo
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。

uuid
用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。

guid
在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。

native
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。

assigned
让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。
 

hibernate 连接 postgresql postgresql 的语句有特殊的要 HQL 会自动转换成 postgresql 要的语句

会的,只要你写的是标准的HQL语句。
如果你在做数据库类型迁移,例如从sqlserver 换成postgreSQL,有些本地代码它是不会转换的,例如sqlserver中的dateadd函数。。

对于java数据库开发,建议你去了解一下JDiy,它是一个超轻量级的数据库框架。支持PostgreSql,操作数据库非常简单。
 

www.htsjk.Com true http://www.htsjk.com/shujukunews/2010.html NewsArticle PostgreSql Partition + Hibernate Insert,postgresqlinsert 与Oracle不同,PostgreSQL需要手动控制分区规则触发器。 步骤一:创建分区 CREATE TABLE table_partition_1( CHECK partition_column criteria) INHENRITS (table) 步骤...
评论暂时关闭