F.18. intarray
ÐодÑÐ»Ñ intarray пÑедоÑÑавлÑÐµÑ ÑÑд полезнÑÑ
ÑÑнкÑий и опеÑаÑоÑов Ð´Ð»Ñ ÑабоÑÑ Ñ Ð¼Ð°ÑÑивами ÑелÑÑ
ÑиÑел без NULL. Также он поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð¾Ð¸Ñк по индекÑÑ Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑÑÑ
из ÑÑиÑ
опеÑаÑоÑов.
ÐÑе ÑÑи опеÑаÑии вÑдаÑÑ Ð¾ÑибкÑ, еÑли в пеÑедаваемом маÑÑиве оказÑваÑÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ NULL.
Ðногие из ÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑий имеÑÑ ÑмÑÑл ÑолÑко Ñ Ð¾Ð´Ð½Ð¾Ð¼ÐµÑнÑми маÑÑивами. ХоÑÑ Ð¸Ð¼ можно пеÑедаÑÑ Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ маÑÑив и болÑÑей ÑазмеÑноÑÑи, знаÑÐµÐ½Ð¸Ñ Ð±ÑдÑÑ ÑÑиÑÑваÑÑÑÑ Ð¸Ð· него как из линейного маÑÑива в поÑÑдке Ñ ÑанениÑ.
F.18.1. ФÑнкÑии и опеÑаÑоÑÑ intarray
РеализованнÑе в модÑле intarray ÑÑнкÑии пеÑеÑиÑÐ»ÐµÐ½Ñ Ð² ТаблиÑе F.9, а опеÑаÑоÑÑ â в ТаблиÑе F.10.
ТаблиÑа F.9. ФÑнкÑии intarray
ТаблиÑа F.10. ÐпеÑаÑоÑÑ intarray
| ÐпеÑаÑÐ¾Ñ | ÐозвÑаÑÐ°ÐµÑ | ÐпиÑание |
|---|---|---|
int[] && int[] | boolean | пеÑеÑекаеÑÑÑ Ñ â true, еÑли маÑÑÐ¸Ð²Ñ Ð¸Ð¼ÐµÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм один обÑий ÑÐ»ÐµÐ¼ÐµÐ½Ñ |
int[] @> int[] | boolean | вклÑÑÐ°ÐµÑ â true, еÑли левÑй маÑÑив ÑодеÑÐ¶Ð¸Ñ Ð¿ÑавÑй маÑÑив |
int[] <@ int[] | boolean | вклÑÑаеÑÑÑ Ð² â true, еÑли левÑй маÑÑив ÑодеÑжиÑÑÑ Ð² пÑавом маÑÑиве |
# int[] | int | ÑиÑло ÑлеменÑов в маÑÑиве |
int[] # int | int | Ð¸Ð½Ð´ÐµÐºÑ ÑлеменÑа (Ð´ÐµÐ»Ð°ÐµÑ Ñо же, ÑÑо и ÑÑнкÑÐ¸Ñ idx) |
int[] + int | int[] | вÑÑавлÑÐµÑ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð² маÑÑив (добавлÑÐµÑ ÐµÐ³Ð¾ в ÐºÐ¾Ð½ÐµÑ Ð¼Ð°ÑÑива) |
int[] + int[] | int[] | ÑоединÑÐµÑ Ð¼Ð°ÑÑÐ¸Ð²Ñ (пÑавÑй маÑÑив добавлÑеÑÑÑ Ð² ÐºÐ¾Ð½ÐµÑ Ð»ÐµÐ²Ð¾Ð³Ð¾) |
int[] - int | int[] | ÑдалÑÐµÑ Ð¸Ð· маÑÑива запиÑи, ÑавнÑе пÑÐ°Ð²Ð¾Ð¼Ñ Ð°ÑгÑменÑÑ |
int[] - int[] | int[] | ÑдалÑÐµÑ Ð¸Ð· левого маÑÑива ÑлеменÑÑ Ð¿Ñавого маÑÑива |
int[] | int | int[] | обÑединение аÑгÑменÑов |
int[] | int[] | int[] | обÑединение маÑÑивов |
int[] & int[] | int[] | пеÑеÑеÑение маÑÑивов |
int[] @@ query_int | boolean | true, еÑли маÑÑив ÑдовлеÑвоÑÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ (Ñм. ниже) |
query_int ~~ int[] | boolean | true, еÑли запÑоÑÑ ÑдовлеÑвоÑÑÐµÑ Ð¼Ð°ÑÑив (коммÑÑиÑÑÑÑий опеÑаÑÐ¾Ñ Ðº @@) |
(Ðо веÑÑии PostgreSQL 8.2 опеÑаÑоÑÑ Ð²ÐºÐ»ÑÑÐµÐ½Ð¸Ñ @> и <@ обознаÑалиÑÑ ÑооÑвеÑÑÑвенно как @ и ~. ÐÑи имена по-пÑÐµÐ¶Ð½ÐµÐ¼Ñ Ð´ÐµÐ¹ÑÑвÑÑÑ, но ÑÑиÑаÑÑÑÑ ÑÑÑаÑевÑими и в конÑе конÑов бÑдÑÑ ÑпÑаздненÑ. ÐамеÑÑÑе, ÑÑо ÑÑаÑÑе имена пÑоизоÑли из ÑоглаÑениÑ, коÑоÑÐ¾Ð¼Ñ ÑанÑÑе Ñледовали клÑÑевÑе геомеÑÑиÑеÑкие ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ
!)
ÐпеÑаÑоÑÑ &&, @> и <@ ÑавнознаÑÐ½Ñ Ð²ÑÑÑоеннÑм опеÑаÑоÑам PostgreSQL Ñ Ñеми же именами, за иÑклÑÑением Ñого, ÑÑо они ÑабоÑаÑÑ ÑолÑко Ñ ÑелоÑиÑленнÑми маÑÑивами, не ÑодеÑжаÑими NULL, Ñогда как вÑÑÑоеннÑе опеÑаÑоÑÑ ÑабоÑаÑÑ Ñ Ð¼Ð°ÑÑивами лÑбÑÑ
Ñипов. ÐлагодаÑÑ ÑÑÐ¾Ð¼Ñ Ð¾Ð³ÑаниÑениÑ, в болÑÑинÑÑве ÑлÑÑаев они ÑабоÑаÑÑ Ð±ÑÑÑÑее, Ñем вÑÑÑоеннÑе опеÑаÑоÑÑ.
ÐпеÑаÑоÑÑ @@ и ~~ пÑовеÑÑÑÑ, ÑдовлеÑвоÑÑÐµÑ Ð»Ð¸ маÑÑив запÑоÑÑ, пÑедÑÑавлÑÐµÐ¼Ð¾Ð¼Ñ Ð² виде знаÑÐµÐ½Ð¸Ñ ÑпеÑиализиÑованного Ñипа даннÑÑ
query_int. ÐапÑÐ¾Ñ ÑодеÑÐ¶Ð¸Ñ ÑелоÑиÑленнÑе знаÑениÑ, ÑÑавниваемÑе Ñ ÑлеменÑами маÑÑива, возможно Ñ Ð¸ÑполÑзованием опеÑаÑоÑов & (AND), | (OR) и ! (NOT). ÐÑи необÑ
одимоÑÑи могÑÑ Ð¸ÑполÑзоваÑÑÑÑ Ñкобки. ÐапÑимеÑ, запÑоÑÑ 1&(2|3) ÑдовлеÑвоÑÑÑÑ Ð·Ð°Ð¿ÑоÑÑ, коÑоÑÑе ÑодеÑÐ¶Ð°Ñ 1 и Ñакже ÑодеÑÐ¶Ð°Ñ 2 или 3.
F.18.2. ÐоддеÑжка индекÑов
ÐодÑÐ»Ñ intarray поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¸Ð½Ð´ÐµÐºÑÑ Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑоÑов &&, @>, <@ и @@, а Ñакже обÑÑнÑÑ Ð¿ÑовеÑÐºÑ ÑавенÑÑва маÑÑивов.
ÐодÑÐ»Ñ Ð¿ÑедоÑÑавлÑÐµÑ Ð´Ð²Ð° клаÑÑа опеÑаÑоÑов GiST: gist__int_ops (иÑполÑзÑеÑÑÑ Ð¿Ð¾ ÑмолÑаниÑ), подÑ
одÑÑий Ð´Ð»Ñ Ð¼Ð°Ð»ÐµÐ½ÑкиÑ
и ÑÑедниÑ
по ÑазмеÑÑ Ð½Ð°Ð±Ð¾Ñов даннÑÑ
, и gist__intbig_ops, пÑименÑÑÑий ÑигнаÑÑÑÑ Ð±Ð¾Ð»ÑÑего ÑазмеÑа и подÑ
одÑÑий Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑаÑии болÑÑиÑ
набоÑов даннÑÑ
(Ñо еÑÑÑ ÑÑолбÑов, ÑодеÑжаÑиÑ
много ÑазлиÑнÑÑ
знаÑений маÑÑива). Ð ÑÑой ÑеализаÑии иÑполÑзÑеÑÑÑ ÑÑÑÑкÑÑÑа даннÑÑ
RD-деÑева Ñо вÑÑÑоеннÑм ÑжаÑием Ñ Ð¿Ð¾ÑеÑÑми.
ÐÑÑÑ Ñакже неÑÑандаÑÑнÑй клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов GIN, gin__int_ops, поддеÑживаÑÑий Ñе же опеÑаÑоÑÑ.
ÐÑÐ±Ð¾Ñ Ð¼ÐµÐ¶Ð´Ñ Ð¸Ð½Ð´ÐµÐºÑами GiST и GIN завиÑÐ¸Ñ Ð¾Ñ Ð¾ÑноÑиÑелÑнÑÑ Ñ Ð°ÑакÑеÑиÑÑик пÑоизводиÑелÑноÑÑи GiST и GIN, коÑоÑÑе здеÑÑ Ð½Ðµ ÑаÑÑмаÑÑиваÑÑÑÑ.
F.18.3. ÐÑимеÑ
-- ÑообÑение Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑноÑиÑÑÑÑ Ðº одной или неÑколÑким «ÑекÑиÑм»
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
-- ÑоздаÑÑ ÑпеÑиализиÑованнÑй индекÑ
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__int_ops);
-- вÑвеÑÑи ÑообÑÐµÐ½Ð¸Ñ Ð¸Ð· ÑекÑий 1 или 2 â опеÑаÑÐ¾Ñ Ð¿ÐµÑеÑеÑениÑ
SELECT message.mid FROM message WHERE message.sections && '{1,2}';
-- вÑвеÑÑи ÑообÑÐµÐ½Ð¸Ñ Ð¸Ð· ÑекÑий 1 и 2 â опеÑаÑÐ¾Ñ Ð²ÐºÐ»ÑÑениÑ
SELECT message.mid FROM message WHERE message.sections @> '{1,2}';
-- ÑÐ¾Ñ Ð¶Ðµ ÑезÑлÑÑаÑ, но Ñ Ð¾Ð¿ÐµÑаÑоÑом запÑоÑа
SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;F.18.4. ТеÑÑиÑование пÑоизводиÑелÑноÑÑи
РкаÑалоге иÑÑ
одного кода contrib/intarray/bench ÑодеÑжиÑÑÑ Ð¿Ð°ÐºÐµÑ ÑеÑÑов, коÑоÑÑе можно пÑовеÑÑи на ÑÑÑановленном ÑеÑвеÑе PostgreSQL. (ÐÐ»Ñ ÑÑого нÑжно ÑÑÑановиÑÑ Ð¿Ð°ÐºÐµÑ DBD::Pg.) ЧÑÐ¾Ð±Ñ Ð·Ð°Ð¿ÑÑÑиÑÑ ÑÑи ÑеÑÑÑ, вÑполниÑе:
cd .../contrib/intarray/bench createdb TEST psql -c "CREATE EXTENSION intarray" TEST ./create_test.pl | psql TEST ./bench.pl
СкÑÐ¸Ð¿Ñ bench.pl пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð½ÐµÑколÑко аÑгÑменÑов, о коÑоÑÑÑ
можно ÑзнаÑÑ, запÑÑÑив его без аÑгÑменÑов.
F.18.5. ÐвÑоÑÑ
РазÑабоÑÐºÑ Ð¾ÑÑÑеÑÑвили ФÑÐ´Ð¾Ñ Ð¡Ð¸Ð³Ð°ÐµÐ² (<[email protected]>) и Ðлег ÐаÑÑÑнов (<[email protected]>). ÐополниÑелÑнÑе ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ найÑи на ÑÑÑаниÑе http://www.sai.msu.su/~megera/postgres/gist/. ÐндÑей ÐкÑÑбÑÑÑкий пÑоделал оÑлиÑнÑÑ ÑабоÑÑ, добавив новÑе ÑÑнкÑии и опеÑаÑоÑÑ.