PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 16.2 » Annexes » Modules et extensions supplémentaires fournis » intarray -- manipuler des tableaux d'entiers

F.20. intarray -- manipuler des tableaux d'entiers #

Le module intarray fournit un certain nombre de fonctions et d'opérateurs utiles pour manipuler des tableaux d'entiers sans valeurs NULL. Il y a aussi un support pour les recherches par index en utilisant certains des opérateurs.

Toutes ces opérations rejeteront une erreur si un tableau fourni contient des éléments NULL.

La plupart des opérations sont seulement intéressants pour des tableaux à une dimension. Bien qu'elles accepteront des tableaux à plusieurs dimensions, les données sont traitées comme s'il y avait un tableau linéaire.

Ce module est considéré comme « trusted », ce qui signifie qu'il peut être installé par des utilisateurs simples (sans attribut SUPERUSER) et qui ont l'attribut CREATE sur la base de données courante.

F.20.1. Fonctions et opérateurs d'intarray #

Les fonctions fournies par le module intarray sont affichées dans Tableau F.9 alors que les opérateurs sont indiqués dans Tableau F.10.

Tableau F.9. Fonctions intarray

Function

Description

Example(s)

icount ( integer[] ) → integer

Retourne le nombre d'éléments dans le tableau.

icount('{1,2,3}'::integer[])3

sort ( integer[], dir text ) → integer[]

Trie le tableau par ordre croissant ou décroissant. dir doit valoir asc ou desc.

sort('{1,3,2}'::integer[], 'desc'){3,2,1}

sort ( integer[] ) → integer[]

sort_asc ( integer[] ) → integer[]

Trie par ordre croissant.

sort(array[11,77,44]){11,44,77}

sort_desc ( integer[] ) → integer[]

Trie par ordre décroissant.

sort_desc(array[11,77,44]){77,44,11}

uniq ( integer[] ) → integer[]

Supprime les doublons adjacents. Souvent utilisé avec sort pour supprimer tous les doublons.

uniq('{1,2,2,3,1,1}'::integer[]){1,2,3,1}

uniq(sort('{1,2,3,2,1}'::integer[])){1,2,3}

idx ( integer[], item integer ) → integer

Retourne l'index du premier élément correspondant à item, ou 0 si pas de correspondance.

idx(array[11,22,33,22,11], 22)2

subarray ( integer[], start integer, len integer ) → integer[]

Extrait une partie d'un tableau depuis la position start, avec len éléments.

subarray('{1,2,3,2,1}'::integer[], 2, 3){2,3,2}

subarray ( integer[], start integer ) → integer[]

Extrait une partie de tableau en commençant à la position start.

subarray('{1,2,3,2,1}'::integer[], 2){2,3,2,1}

intset ( integer ) → integer[]

Crée un tableau d'un seul élément.

intset(42){42}


Tableau F.10. Opérateurs d'intarray

Opérateur

Description

integer[] && integer[]boolean

Est-ce que les tableaux se recoupent (ont-ils au moins un élément en commun) ?

integer[] @> integer[]boolean

Est-ce que le tableau contient le tableau de droite ?

integer[] <@ integer[]boolean

Est-ce que le tableau de gauche est contenu dans le tableau de droite ?

# integer[]integer

Retourne le nombre d'élements dans le tableau.

integer[] # integerinteger

Retourne l'indice du premier élément du tableau correspondant à l'argument de droite, ou 0 s'il n'y a pas de correspondance. (Identique à la fonction idx.)

integer[] + integerinteger[]

Ajoute un élement en fin de tableau.

integer[] + integer[]integer[]

Concatène les tableaux.

integer[] - integerinteger[]

Supprime les entrées correspondantes à l'argument de droite dans le tableau.

integer[] - integer[]integer[]

Supprime les éléments du tableau de droite dans le tableau de gauche.

integer[] | integerinteger[]

Calcule l'union des arguments.

integer[] | integer[]integer[]

Calcule l'union des tableaux en arguments.

integer[] & integer[]integer[]

Calcule l'intersection des tableaux en arguments.

integer[] @@ query_intboolean

Est-ce que le tableau satisfait la requête ? (voir ci-dessous)

query_int ~~ integer[]boolean

Est-ce que le tableau satisfait la requête ? (commuteur pour @@)


Les opérateurs &&, @> et <@ sont équivalents aux opérateurs internes PostgreSQL de même nom, sauf qu'ils travaillent sur des tableaux d'entiers, sans valeurs NULL, alors que les opérateurs internes travaillent sur des tableaux de tout type. Cette restriction les rend plus rapides que les opérateurs internes dans de nombreux cas.

Les opérateurs @@ et ~~ testent si un tableau satisfait une requête, qui est exprimée comme une valeur d'un type de données spécialisé query_int. Une requête consiste en des valeurs de type integer qui sont vérifiées avec les éléments du tableau, parfois combinées en utilisant les opérateurs & (AND), | (OR) et ! (NOT). Les parenthèses peuvent être utilisées si nécessaire. Par exemple, la requête 1&(2|3) établit une correspondance avec les tableaux qui contiennent 1 et aussi soit 2 soit 3.

F.20.2. Support des index #

intarray fournit un support d'index pour les opérateurs &&, @> et @@, ainsi que pour l'égalité de tableaux.

Deux classes d'opérateur pour index GiST, avec paramètres, sont fournies : gist__int_ops (utilisé par défaut) convient pour des tableaux d'ensembles de données de petites et moyennes tailles alors que gist__intbig_ops utilise une signature plus importante et est donc plus intéressant pour indexer des gros ensembles de données. (c'est-à-dire les colonnes contenant un grand nombre de valeurs de tableaux distinctes). L'implantation utilise une structure de données RD-tree avec une compression interne à perte.

gist__int_ops donne une approximation d'un ensemble d'entiers sous forme d'un tableau d'intervalles d'entiers. Son paramètre entier optionnel numranges détermine le nombre maximal d'intervalles dans une clé d'index. La valeur par défaut de numranges est 100. Les valeurs valides sont entre 1 et 253. Utiliser des tableaux plus grands comme clés d'index GiST entraîne une recherche plus précise (en parcourant une fraction plus petite de l'index et donc moins de pages de la table), au détriment d'un index plus gros.

gist__intbig_ops donne une approximation d'un ensemble d'entiers sous forme d'une signature bitmap. Son paramètre entier optionnel siglen détermine la taille de la signature en octets. La taille de signature par défaut est 16 octets. Les valeurs valides pour la taille de signature est entre 1 et 2024 octets. Une signature plus longue entraîne une recherche plus précise (en parcourant une fraction plus petite de l'index et donc moins de pages de la table), au détriment d'un index plus gros.

Il y a aussi une classe d'opérateur GIN,gin__int_ops supportant les mêmes opérateurs ainsi que <@, mais qui n'est pas disponible par défaut.

Le choix d'un indexage GiST ou IN dépend des caractéristiques relatives de performance qui sont discutées ailleurs.

F.20.3. Exemple #

-- un message peut être dans un ou plusieurs « sections »
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);

-- crée un index spécialisé with sigature length of 32 bytes
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen=32));

-- sélectionne les messages dans la section 1 ou 2 - opérateur OVERLAP
SELECT message.mid FROM message WHERE message.sections && '{1,2}';

-- sélectionne les messages dans sections 1 et 2 - opérateur CONTAINS
SELECT message.mid FROM message WHERE message.sections @> '{1,2}';

-- idem, en utilisant l'opérateur QUERY
SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;
  

F.20.4. Tests de performance #

Le répertoire des sources (contrib/intarray/bench) contient une suite de tests de performance, qui peut être exécutée sur un serveur PostgreSQL déjà installé. (Cela nécessite aussi l'installation de DBD::Pg.). Pour l'exécuter :

   cd .../contrib/intarray/bench
   createdb TEST
   psql -c "CREATE EXTENSION intarray" TEST
   ./create_test.pl | psql TEST
   ./bench.pl
  

Le script bench.pl contient un grand nombre d'options. Elles sont affichées quand il est exécuté sans arguments.

F.20.5. Auteurs #

Ce travail a été réalisé par Teodor Sigaev () et Oleg Bartunov (). Voir le site de GiST pour des informations supplémentaires. Andrey Oktyabrski a fait un gros travail en ajoutant des nouvelles fonctions et opérateurs.