Problema
Nota: Refiro-me às seqüências matemáticas , não ao mecanismo de sequências do PostgreSQL .
Eu tenho uma tabela representando sequências de números inteiros. A definição é:
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)
);
Meu objetivo é encontrar linhas usando uma determinada subsequência. Ou seja, as linhas em que o sequence
campo é uma sequência que contém a subsequência especificada (no meu caso, a sequência é ordenada).
Exemplo
Suponha que a tabela contenha os seguintes dados:
+----+-------+------------+-------------------------------+
| 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} |
+----+-------+------------+-------------------------------+
Portanto, se a subsequência especificada for {12, 742, 225, 547}
, desejo encontrar a linha 2.
Da mesma forma, se a subsequência especificada for {3, 17, 25, 377}
, desejo encontrar a linha 1 e a linha 4.
Por fim, se a subsequência especificada for {12, 4, 3, 25, 377}
, não haverá linhas retornadas.
Investigações
Primeiro, não tenho certeza absoluta de que as seqüências com um tipo de dados de matriz sejam sábias. Embora isso pareça apropriado para a situação; Temo que isso torne o manuseio mais complicado. Talvez seja melhor representar as seqüências de maneira diferente, usando um modelo de relações com outra tabela.
Da mesma forma, penso em expandir as seqüências usando a unnest
função array e, em seguida, adicionar meus critérios de pesquisa. No entanto, o número de termos na sequência sendo variável, não vejo como fazer isso.
Eu sei que também é possível cortar minha sequência em subsequência usando a subarray
função do módulo intarray , mas não vejo como isso me beneficia em minha pesquisa.
Restrições
Mesmo que, no momento, meu modelo ainda esteja sendo desenvolvido, a tabela deve ser composta de várias seqüências, entre 50.000 e 300.000 linhas. Então, eu tenho uma forte restrição de desempenho.
No meu exemplo, usei números inteiros relativamente pequenos. Na prática, é possível que esses números inteiros se tornem muito maiores, até transbordar bigint
. Em tal situação, acho que o melhor é armazenar números como seqüências de caracteres (já que não é necessário executar essas seqüências de operações matemáticas). No entanto, ao optar por esta solução, isso torna impossível o uso do módulo intarray , mencionado acima.
numeric
e não uma string ( text
por exemplo)? Não preciso executar operações matemáticas nas minhas seqüências.
text
impede de armazenar dados não numéricos falsos. Depende, se você estiver executando apenas E / S, poderá desejar que o texto reduza o processamento de E / S.
SELECT ARRAY[12, 4, 3, 17, 25, 377, 456, 25] @> ARRAY[12, 4, 3, 25, 377];
retornará true, porque o pedido não é considerado por este operador.
bigint
você deve usarnumeric
como o tipo para armazená-los. É muito mais lento e ocupa muito mais espaço.