我的 Postgres 13 数据库中有一个包含用户订阅的表。我添加了一个 GiST 索引来禁止同一用户的重叠时间范围:
CREATE INDEX user_sub_exclusion_index ON public.user_sub USING gist (user_id, tstzrange(sub_start, sub_end))
但是今天我发现它不起作用。
这是表 DDL:
-- DROP TABLE public.user_sub;
CREATE TABLE public.user_sub (
id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
app_id varchar NOT NULL,
product_id int4 NOT NULL,
iap_product_id int8 NOT NULL,
created_time int8 NOT NULL,
updated_time int8 NOT NULL,
user_id int8 NOT NULL,
sub_start_time int8 NOT NULL DEFAULT 0,
sub_end_time int8 NOT NULL DEFAULT 0,
enabled int2 NOT NULL DEFAULT 1,
order_id varchar NOT NULL,
sub_start timestamptz NOT NULL,
sub_end timestamptz NOT NULL,
CONSTRAINT user_sub_new_pk PRIMARY KEY (id),
CONSTRAINT user_sub_new_un UNIQUE (order_id)
);
CREATE INDEX user_sub_exclusion_index ON public.user_sub USING gist (user_id, tstzrange(sub_start, sub_end));
CREATE INDEX user_sub_tstzrange_user_id_product_id_excl ON public.user_sub USING gist (tstzrange(sub_start, sub_end, '[]'::text), user_id, product_id);
现在是表数据的示例:它包含同一用户的重叠时间范围:
INSERT INTO public.user_sub (app_id, product_id, iap_product_id, created_time, updated_time, user_id, sub_start_time, sub_end_time, enabled, order_id, sub_start, sub_end)
VALUES
('vOghoo10L9', 9, 6, 1680251663942, 1680251663942, 77, 1680501039421, 1680587439421, 1, '627599858277646336', '2023-04-03 13:50:39.421', '2023-04-04 13:50:39.421')
, ('vOghoo10L9', 9, 6, 1680263287925, 1680263287925, 77, 1680587439422, 1680673839422, 1, '627697298195189760', '2023-04-04 13:50:39.422', '2023-04-05 13:50:39.422')
, ('vOghoo10L9', 9, 6, 1680263497256, 1680263497256, 77, 1680673839423, 1680760239423, 1, '627679779371601920', '2023-04-05 13:50:39.423', '2023-04-06 13:50:39.423')
, ('vOghoo10L9', 9, 6, 1680263539890, 1680263539890, 77, 1680760239424, 1680846639424, 1, '627680143827259392', '2023-04-06 13:50:39.424', '2023-04-07 13:50:39.424')
, ('vOghoo10L9', 9, 6, 1680273609032, 1680273609032, 77, 1680846639425, 1680933039425, 1, '627601223242579968', '2023-04-07 13:50:39.425', '2023-04-08 13:50:39.425')
, ('vOghoo10L9', 9, 6, 1680275903068, 1680275903068, 77, 1680933039426, 1681019439426, 1, '627610724383956992', '2023-04-08 13:50:39.426', '2023-04-09 13:50:39.426')
, ('vOghoo10L9', 9, 6, 1680276434561, 1680276434561, 77, 1681019439427, 1681105839427, 1, '627612898614681600', '2023-04-09 13:50:39.427', '2023-04-10 13:50:39.427')
, ('vOghoo10L9', 9, 6, 1680277832740, 1680277832740, 77, 1681105839428, 1681192239428, 1, '627618880539664384', '2023-04-10 13:50:39.428', '2023-04-11 13:50:39.428')
, ('vOghoo10L9', 9, 6, 1680282545888, 1680282545888, 77, 1681192239429, 1681278639429, 1, '627411682153152512', '2023-04-11 13:50:39.429', '2023-04-12 13:50:39.429')
, ('vOghoo10L9', 9, 6, 1680327772145, 1680327772145, 77, 1681278639430, 1681365039430, 1, '627601513341616128', '2023-04-12 13:50:39.430', '2023-04-13 13:50:39.430')
, ('vOghoo10L9', 9, 5, 1680761228691, 1680761228691, 79, 1680761228687, 1680847628687, 1, '629789245600776192', '2023-04-06 14:07:08.687', '2023-04-07 14:07:08.687')
, ('vOghoo10L9', 9, 5, 1680763488691, 1680763488691, 77, 1680763488689, 1680849888689, 1, '629798689575354368', '2023-04-06 14:44:48.689', '2023-04-07 14:44:48.689')
, ('vOghoo10L9', 9, 5, 1680763634694, 1680763634694, 77, 1680849888690, 1688712288690, 1, '629799331018653696', '2023-04-07 14:44:48.690', '2023-07-07 14:44:48.690')
, ('vOghoo10L9', 9, 6, 1680850885924, 1680850885924, 80, 1680850881709, 1680937281709, 1, '630165239553671168', '2023-04-07 15:01:21.709', '2023-04-08 15:01:21.709')
, ('vOghoo10L9', 9, 6, 1681461059268, 1681461059268, 81, 1681461059263, 1681547459263, 1, '632723434021126144', '2023-04-14 16:30:59.263', '2023-04-15 16:30:59.263')
, ('vOghoo10L9', 9, 6, 1681483885008, 1681483885008, 82, 1681483885006, 1681570285006, 1, '632820205569245184', '2023-04-14 22:51:25.006', '2023-04-15 22:51:25.006')
, ('iYDFo0PQQX', 11, 14, 1682762462986, 1682762462986, 86, 1682762462971, 1682848862971, 1, '638182956129267712', '2023-04-29 18:01:02.971', '2023-04-30 18:01:02.971')
, ('iYDFo0PQQX', 11, 14, 1682764832099, 1682764832099, 86, 1682764832090, 1682851232090, 1, '638192942803423232', '2023-04-29 18:40:32.090', '2023-04-30 18:40:32.090')
, ('iYDFo0PQQX', 11, 14, 1682765939081, 1682765939081, 86, 1682765939052, 1682852339052, 1, '638197106476421120', '2023-04-29 18:58:59.052', '2023-04-30 18:58:59.052')
, ('iYDFo0PQQX', 11, 14, 1682766222551, 1682766222551, 86, 1682766193447, 1682852593447, 1, '638198676681232384', '2023-04-29 19:03:13.447', '2023-04-30 19:03:13.447')
;
我错过了什么吗?如何使这个约束起作用?即,防止同一用户订阅重叠的时间范围。
要使约束起作用,您需要创建约束。仅仅创建一个索引是不够的(创建一个约束无论如何都会创建它的支持索引)。
(如果我的排除标准正确的话。)
小提琴