问题
注意:我指的是数学序列,而不是PostgreSQL的序列机制。
我有一张表,代表整数序列。定义是:
CREATE TABLE sequences
(
id serial NOT NULL,
title character varying(255) NOT NULL,
date date NOT NULL,
sequence integer[] NOT NULL,
CONSTRAINT "PRIM_KEY_SEQUENCES" PRIMARY KEY (id)
);
我的目标是使用给定的子序列查找行。也就是说,其中sequence
字段是包含给定子序列的序列的行(在我的情况下,该序列是有序的)。
例
假设该表包含以下数据:
+----+-------+------------+-------------------------------+
| id | title | date | sequence |
+----+-------+------------+-------------------------------+
| 1 | BG703 | 2004-12-24 | {1,3,17,25,377,424,242,1234} |
| 2 | BG256 | 2005-05-11 | {5,7,12,742,225,547,2142,223} |
| 3 | BD404 | 2004-10-13 | {3,4,12,5698,526} |
| 4 | BK956 | 2004-08-17 | {12,4,3,17,25,377,456,25} |
+----+-------+------------+-------------------------------+
因此,如果给定的子序列是{12, 742, 225, 547}
,我想找到第二行。
同样,如果给定的子序列是{3, 17, 25, 377}
,我想找到第1行和第4行。
最后,如果给定的子序列为{12, 4, 3, 25, 377}
,则不会返回任何行。
调查
首先,我不能完全确定用数组数据类型表示序列是明智的。尽管这似乎适合这种情况;我担心这会使处理更加复杂。也许最好使用与另一个表的关系模型来不同地表示序列。
同样,我考虑使用unnest
数组函数扩展序列,然后添加搜索条件。但是,序列中的术语数是可变的,我看不出该怎么做。
我知道也可以使用intarray模块的subarray
功能在子序列中剪切序列,但是我看不出它对我的搜索有何好处。
约束条件
即使目前仍在开发我的模型,该表也打算由许多序列组成,这些序列介于50,000至300,000行之间。所以我有很强的性能约束。
在我的示例中,我使用了相对较小的整数。实际上,这些整数有可能变得更大,直到溢出为止bigint
。在这种情况下,我认为最好的方法是将数字存储为字符串(因为没有必要执行这些数学运算序列)。但是,选择此解决方案将导致无法使用上述intarray模块。
numeric
而不是字符串(text
例如)?我不需要对序列执行数学运算。
text
,并且阻止了您存储虚假的非数字数据。取决于,如果您仅执行I / O,则可能希望文本减少I / O处理。
SELECT ARRAY[12, 4, 3, 17, 25, 377, 456, 25] @> ARRAY[12, 4, 3, 25, 377];
将返回true,因为此运算符未考虑订单。
bigint
,则应将其numeric
用作存储它们的类型。它慢很多,但占用更多空间。