我根据http://www.postgresql.org/docs/8.1/interactive/ddl-partitioning.html
的文档设置了一组分区表格CREATE TABLE t (year, a);
CREATE TABLE t_1980 ( CHECK (year = 1980) ) INHERITS (t);
CREATE TABLE t_1981 ( CHECK (year = 1981) ) INHERITS (t);
CREATE RULE t_ins_1980 AS ON INSERT TO t WHERE (year = 1980)
DO INSTEAD INSERT INTO t_1980 VALUES (NEW.year, NEW.a);
CREATE RULE t_ins_1981 AS ON INSERT TO t WHERE (year = 1981)
DO INSTEAD INSERT INTO t_1981 VALUES (NEW.year, NEW.a);
根据我的理解,如果我插入t(年,a)VALUES(1980,5),它将进入t_1980,如果我插入t(年,a)VALUES(1981,3),它将去t_1981。但是,我的理解似乎是不正确的。首先,我无法理解文档中的以下内容
“目前没有简单的方法来指定不能将行插入主表。主表上的CHECK(false)约束将由所有子表继承,因此不能用于此目的。一种可能性是在主表上设置一个始终引发错误的ON INSERT触发器。(或者,这样的触发器可用于将数据重定向到正确的子表,而不是使用上面建议的一组规则。 )“
上述意味着尽管设置了CHECK约束和RULEs,我还必须在主表上创建TRIGGER,以便INSERT转到正确的表吗?如果是这种情况,db支持分区的重点是什么?我可以自己设置单独的表格吗?我在主表中插入了一堆值,这些行仍然在主表中,而不是在继承的表中。
第二个问题。检索行时,是从主表中选择,还是必须根据需要从各个表中进行选择?以下如何工作?
SELECT year, a FROM t WHERE year IN (1980, 1981);
更新:好像我找到了自己问题的答案
“请注意,COPY命令会忽略规则。如果使用COPY插入数据,则必须将数据复制到正确的子表而不是父表中.COPY会触发触发器,因此您可以正常使用它您可以使用触发器方法创建分区表。“
我确实使用COPY FROM来加载数据,所以RULEs被忽略了。将尝试使用TRIGGER。
答案 0 :(得分:3)
绝对尝试触发器。
如果您认为要实施规则,请不要(想到的唯一例外是可更新视图)。有关此处的更多说明,请参阅此great article by depesz。
实际上,Postgres只支持阅读方面的分区。您将自己设置插入分区的方法 - 在大多数情况下TRIGGERing。根据需求和应用程序,教您的应用程序直接插入分区有时会更快。
从分区表中进行选择时,只要正确设置了CHECK约束(它们在您的示例中)并且subject_exclusion参数设置为corectly,您就可以在主表上选择SELECT ... WHERE ....
对于8.4:
SET constraint_exclusion = partition;
对于< 8.4:
SET constraint_exclusion = on;
所有这一切,我实际上非常喜欢Postgres的方式,并经常自己使用它。
答案 1 :(得分:1)
以上是否意味着尽管如此 设置CHECK约束和 RULEs,我也必须创造 主表上的TRIGGER这样 INSERT会转到正确的表吗?
如果是这样的话,会是什么 数据库支持的重点 分区?我可以设置 我自己分开桌子?
基本上:必须明确地完成子表中的INSERTS(创建TRIGGERS,或者通过在查询中指定正确的子表)。但是分区 SELECTS是透明的,并且(鉴于此模式的存储和索引优势)就是重点。 (另外,因为分区表是继承的, 模式继承自父级,因此一致性 是强制执行的。)
答案 2 :(得分:1)
触发器比规则更好。 今天我玩物化视图表的分区,并遇到触发器解决方案的问题。 为什么? 我正在使用RETURNING,当前的解决方案返回NULL :) 但这里的解决方案对我有用 - 如果我错了,请纠正我。 1.我有3个表插入了一些数据,有一个视图(我们称之为viewfoo)包含 需要实现的数据。 2.插入到最后一个表中的触发器插入物化视图表 通过INSERT INTO matviewtable SELECT * FROM viewfoo WHERE recno = NEW.recno; 这工作正常,我正在使用RETURNING recno; (recno是SERIAL类型 - 序列)。
物化视图(表格)需要进行分区,因为它很大,而且 根据我的测试,在这种情况下,SELECT至少快了x10。 分区问题: *当前触发解决方案RETURN NULL - 所以我不能使用RETURNING recno。 (当前触发解决方案=在depesz页面解释触发器。)
解决方案: 我已经更改了我的第3个表的触发器,而不是插入物化视图表(该表是分区表的父表),但创建了新的触发器,它插入 分区表直接从第3个表中触发RETURN NEW。 物化视图表自动更新,RETURNING recno工作正常。 如果这对任何人都有帮助,我会很高兴。