【发布时间】: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