Problem
Uwaga: mam na myśli sekwencje matematyczne , a nie mechanizm sekwencji w PostgreSQL .
Mam tabelę reprezentującą sekwencje liczb całkowitych. Definicja to:
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)
);
Moim celem jest znalezienie wierszy przy użyciu podanego podsekwencji. To znaczy, wiersze, w których sequence
pole jest sekwencją zawierającą podaną podsekwencję (w moim przypadku sekwencja jest uporządkowana).
Przykład
Załóżmy, że tabela zawiera następujące dane:
+----+-------+------------+-------------------------------+
| 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} |
+----+-------+------------+-------------------------------+
Więc jeśli podanym podsekwencją jest {12, 742, 225, 547}
, chcę znaleźć wiersz 2.
Podobnie, jeśli podanym podsekwencją jest {3, 17, 25, 377}
, chcę znaleźć wiersz 1 i wiersz 4.
Wreszcie, jeśli podanym podsekwencją jest {12, 4, 3, 25, 377}
, to nie są zwracane wiersze.
Dochodzenia
Po pierwsze, nie jestem całkowicie pewien, czy sekwencje z tablicowym typem danych są mądre. Chociaż wydaje się to odpowiednie do sytuacji; Obawiam się, że utrudnia to obsługę. Być może lepiej jest inaczej reprezentować sekwencje, używając modelu relacji z inną tabelą.
W ten sam sposób myślę o rozszerzeniu sekwencji za pomocą unnest
funkcji tablicowej, a następnie dodaniu moich kryteriów wyszukiwania. Niemniej liczba zmiennych w sekwencji jest zmienna. Nie widzę, jak to zrobić.
Wiem, że można również przycinać sekwencję w podsekwencjach za pomocą subarray
funkcji modułu intarray , ale nie widzę korzyści, jakie przyniosło mi to wyszukiwanie.
Ograniczenia
Nawet jeśli obecnie mój model jest wciąż rozwijany, tabela ma składać się z wielu sekwencji, od 50 000 do 300 000 wierszy. Mam więc silne ograniczenie wydajności.
W moim przykładzie użyłem stosunkowo małych liczb całkowitych. W praktyce możliwe jest, że te liczby całkowite staną się znacznie większe, aż do przepełnienia bigint
. W takiej sytuacji najlepiej jest przechowywać liczby jako ciągi znaków (ponieważ nie jest konieczne wykonywanie tych sekwencji operacji matematycznych). Jednak wybranie tego rozwiązania uniemożliwia użycie wspomnianego wyżej modułu intarray .
numeric
a nie ciąg znaków ( text
na przykład)? Nie muszę wykonywać operacji matematycznych na moich sekwencjach.
text
, i uniemożliwia przechowywanie fałszywych danych nienumerycznych. Zależy, jeśli wykonujesz tylko operacje we / wy, możesz chcieć, aby tekst ograniczył przetwarzanie operacji we / wy.
SELECT ARRAY[12, 4, 3, 17, 25, 377, 456, 25] @> ARRAY[12, 4, 3, 25, 377];
zwróci true, ponieważ zamówienie nie jest uwzględniane przez tego operatora.
bigint
, należy użyć ichnumeric
jako typu do ich przechowywania. Jest o wiele wolniejszy i zajmuje znacznie więcej miejsca.