Sorun
Not: PostgreSQL'in dizi mekanizmasına değil, matematiksel dizilere atıfta bulunuyorum .
Tamsayı dizilerini temsil eden bir tablo var. Tanım:
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)
);
Amacım belirli bir alt diziyi kullanarak satırları bulmak. Yani, sequence
alanın verilen alt diziyi içeren bir dizi olduğu satırlar (benim durumumda, dizi sıralanır).
Misal
Tablonun aşağıdaki verileri içerdiğini varsayalım:
+----+-------+------------+-------------------------------+
| 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} |
+----+-------+------------+-------------------------------+
Yani verilen {12, 742, 225, 547}
alt çizgi ise 2. satırı bulmak istiyorum.
Benzer şekilde, verilen {3, 17, 25, 377}
alt çizgi ise , 1. satırı ve 4. satırı bulmak istiyorum.
Son olarak, verilen alt dizge ise {12, 4, 3, 25, 377}
, döndürülen satır yoktur.
Araştırmalar
İlk olarak, bir dizi veri türü ile dizileri temsil tamamen akıllıca emin değilim. Bu duruma uygun görünse de; Korkarım daha karmaşık bir kullanım sağlar. Belki de dizileri başka bir tabloyla ilişki modeli kullanarak farklı şekilde temsil etmek daha iyidir.
Aynı şekilde, unnest
dizi işlevini kullanarak dizileri genişletmek ve sonra arama ölçütlerimi eklemek düşünüyorum . Bununla birlikte, dizideki değişken olan terimlerin sayısı, bunun nasıl yapılacağını görmüyorum.
İntarray modülünün subarray
işlevini kullanarak sırayla dizimi kesmenin mümkün olduğunu biliyorum, ancak arama için bana nasıl fayda sağladığını göremiyorum.
Kısıtlamalar
Şu anda modelim hala geliştirilse bile, tablonun 50.000 ila 300.000 sıra arasında birçok diziden oluşması amaçlanmıştır. Bu yüzden güçlü bir performans kısıtlamam var.
Örneğimde nispeten küçük tamsayılar kullandım. Pratikte, bu tamsayıların taşmasına kadar çok daha büyük olması mümkündür bigint
. Böyle bir durumda, en iyisinin sayıları dizeler olarak saklamak olduğunu düşünüyorum (çünkü bu matematiksel işlem dizilerini gerçekleştirmek gerekli değildir). Bununla birlikte, bu çözümü seçerek , yukarıda belirtilen intarray modülünün kullanılmasını imkansız hale getirir .
numeric
bir dize kullanmıyoruz ( text
örneğin)? Dizilerim üzerinde matematiksel işlemler yapmam gerekmiyor.
text
ve sahte sayısal olmayan verileri depolamanızı engelliyor. Bağımlıdır, yalnızca G / Ç yapıyorsanız metnin G / Ç işlemlerini azaltmasını isteyebilirsiniz.
SELECT ARRAY[12, 4, 3, 17, 25, 377, 456, 25] @> ARRAY[12, 4, 3, 25, 377];
sipariş bu operatör tarafından dikkate alınmadığından true değerini döndürür.
bigint
kullanmalısınıznumeric
. Çok daha yavaş ve daha fazla yer kaplıyor.