子分区表中的常量列

时间:2014-02-14 07:32:49

标签: postgresql postgresql-9.2

我们在应用程序中使用基于继承的分区。分区位于列上,使得每个分区对此列具有不同的值。像这样:

CREATE TABLE base(
    tblock INT NOT NULL,
    -- other fields --
);

-- Create a partition
CREATE TABLE partition_1(
    CHECK(tblock=1),
    INHERITS base
);

有很多这样的分区,每个分区都有大量的记录(以百万计)。整体数据库大小为TB级。

在上面的模式中,分区必须有一个列tblock,即使每个分区在所有行中都具有该列的常量值。这显然是浪费磁盘上的空间。

有没有办法声明分区,以便它实际上不会将tblock的值存储在磁盘上?

我们目前使用的是Postgresql 9.2.6。

1 个答案:

答案 0 :(得分:0)

当然你可以编写触发器来跳过某些列,但是如果这样做,你将失去分区(constraint exclusions)

的好处。

如果继承了表,则无法删除此列

这是一些例子

create table base(i integer, j integer);
CREATE TABLE
create table inh_1() inherits (base);
CREATE TABLE
create table inh_2() inherits (base);
CREATE TABLE

CREATE OR REPLACE FUNCTION part_trigger()
RETURNS TRIGGER AS $$
BEGIN
if NEW.j = 1 THEN INSERT INTO inh_1 (i) VALUES (NEW.i);
    ELSIF NEW.j = 2 THEN INSERT INTO inh_2 (i) VALUES (NEW.i);
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;
CREATE FUNCTION

CREATE TRIGGER insert_base
    BEFORE INSERT ON base
    FOR EACH ROW EXECUTE PROCEDURE part_trigger();
CREATE TRIGGER


insert into base values (100,1);
INSERT 0 0
insert into base values (140,2);
INSERT 0 0
sebpa=# select * from base;
  i  | j
-----+---
 100 |
 140 |
(2 rows)

sebpa=# select * from inh_1;
  i  | j
-----+---
 100 |
(1 row)

sebpa=# select * from inh_2;
  i  | j
-----+---
 140 |
(1 row)