【问题标题】:postgres partitioned table foreign key on bigint bug关于 bigint 错误的 postgres 分区表外键
【发布时间】:2015-04-16 09:27:55
【问题描述】:

我有一个按日期划分的表,带有一个 bigint 主键,还有另一个表引用了这个主键,但是当我尝试插入一个我知道在分区表中的值时,约束会报错:

ERROR: insert or update on table "partition_test_2" violates foreign key constraint "partition_test_2_record_id_fkey"
SQL state: 23503
Detail: Key (record_id)=(2315648946516) is not present in table "partition_test".

这里是复制问题的脚本:

--DROP TRIGGER insert_partition_test_trigger ON temp.partition_test;
DROP TABLE IF EXISTS temp.partition_test_y2015m1;
DROP TABLE IF EXISTS temp.partition_test_y2015m2;
DROP TABLE IF EXISTS temp.partition_test_y2015m3;
DROP TABLE IF EXISTS temp.partition_test_y2015m4;
DROP TABLE IF EXISTS temp.partition_test_2;
DROP TABLE IF EXISTS temp.partition_test;

CREATE TABLE temp.partition_test
(
    record_id bigint PRIMARY KEY,
    date date,
    units integer
);

CREATE TABLE temp.partition_test_y2015m1 (CHECK(date >= '2015-01-01' AND date < '2015-02-01')) INHERITS (temp.partition_test);
CREATE TABLE temp.partition_test_y2015m2 (CHECK(date >= '2015-02-01' AND date < '2015-03-01')) INHERITS (temp.partition_test);
CREATE TABLE temp.partition_test_y2015m3 (CHECK(date >= '2015-03-01' AND date < '2015-04-01')) INHERITS (temp.partition_test);
CREATE TABLE temp.partition_test_y2015m4 (CHECK(date >= '2015-04-01' AND date < '2015-05-01')) INHERITS (temp.partition_test);

CREATE INDEX partition_test_y2015m1_date ON temp.partition_test_y2015m1(date);
CREATE INDEX partition_test_y2015m2_date ON temp.partition_test_y2015m2(date);
CREATE INDEX partition_test_y2015m3_date ON temp.partition_test_y2015m3(date);
CREATE INDEX partition_test_y2015m4_date ON temp.partition_test_y2015m4(date);

CREATE OR REPLACE FUNCTION partition_test_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF new.date >= '2015-01-01' AND new.date < '2015-02-01' THEN
        INSERT INTO temp.partition_test_y2015m1 VALUES (NEW.*);
    ELSIF new.date >= '2015-02-01' AND new.date < '2015-03-01' THEN
        INSERT INTO temp.partition_test_y2015m2 VALUES (NEW.*);
    ELSIF new.date >= '2015-03-01' AND new.date < '2015-04-01' THEN
        INSERT INTO temp.partition_test_y2015m3 VALUES (NEW.*);
    ELSIF new.date >= '2015-04-01' AND new.date < '2015-05-01' THEN
        INSERT INTO temp.partition_test_y2015m4 VALUES (NEW.*);
    ELSE
        RAISE EXCEPTION 'Date out of range. Fix the partition_test_insert_trigger() function!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER insert_partition_test_trigger
    BEFORE INSERT ON temp.partition_test
    FOR EACH ROW EXECUTE PROCEDURE partition_test_insert_trigger();

INSERT INTO temp.partition_test (record_id, date, units) VALUES
(2315648946516,'2015-01-15', 12),
(5684621651651,'2015-02-04',54),
(5665655115778,'2015-03-19',2),
(6532322558877,'2015-04-25',68);

CREATE TABLE temp.partition_test_2
(
    record_id bigint REFERENCES temp.partition_test(record_id),
    price_type_id smallint,
    price numeric,
    PRIMARY KEY (record_id, price_type_id)
);
INSERT INTO temp.partition_test_2(record_id, price_type_id, price) VALUES 
(2315648946516, 1, 100.25),
(2315648946516, 2, 100.25),
(5684621651651, 1, 100.25),
(5684621651651, 2, 100.25),
(5665655115778, 1, 100.25),
(5665655115778, 2, 100.25),
(6532322558877, 1, 100.25),
(6532322558877, 2, 100.25);

-- SELECT * FROM temp.partition_test WHERE record_id = 2315648946516;

这是 Postgres 中的错误,不可能吗?还是我做错了什么?

【问题讨论】:

  • Quote from the manual "继承特性的一个严重限制是索引(包括唯一约束)和外键约束只适用于单个表,而不适用于它们的继承子表"

标签: postgresql foreign-keys partitioning


【解决方案1】:

正如上面的评论所说:

“继承特性的一个严重限制是索引(包括唯一约束)和外键约束只适用于单个表,而不适用于它们的继承子表”

非常感谢,感觉这应该是以后版本实现的功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多