BRIN signifie Block Range Index, soit index par intervalles de bloc. BRIN est conçu pour gérer de grosses tables dont certaines ont des colonnes ayant une corrélation naturelle avec leur stockage physique.
BRIN fonctionne en terme d'intervalle de blocs (ou « intervalle de pages »). Un intervalle de bloc est un groupe de blocs physiquement adjacents dans la table ; Pour chaque gamme de bloc, un résumé des informations est stocké par l'index. Un exemple courant est une table avec une colonne date, contenant les références des ventes d'un magasin. Chaque commande y serait enregistrée chronologiquement. Dans la plupart des cas, les données seront donc insérées dans le même ordre où elles apparaîtront par la suite. De la même manière, une table, avec une colonne code postal, pourrait avoir tous les codes d'une même ville rassemblés naturellement au même endroit.
Les index BRIN peuvent répondre à des requêtes via un parcours d'index bitmap classique, et retourneront toutes les lignes de toutes les pages dans chaque intervalle si le résumé des informations contenues dans l'index est cohérent avec les conditions de la requête. L'exécuteur de la requête doit revérifier ces lignes et annuler celles qui ne répondent pas aux conditions initiales de la requête. En d'autres termes, on parle d'index à perte (lossy). Comme l'index BRIN est un petit index, parcourir cet index ajoute une légère surcharge par rapport à un parcours séquentiel mais permet d'éviter de parcourir des grandes parties de la table où on sait qu'on ne trouvera pas de lignes à remonter.
Les données spécifiques qu'un index BRIN va stocker, de même que les requêtes spécifiques auquel l'index va pouvoir répondre dépendent de la classe d'opérateur choisie pour chaque colonne de l'index. Les types de données possédant un ordre de tri linéaire peuvent utiliser une classe d'opérateur qui ne conserve que la valeur minimale et la valeur maximale dans chaque intervalle de bloc. Par exemple, un type géométrique peut stocker une bounding box pour tous les objets de l'intervalle de bloc.
La taille de l'intervalle de bloc est déterminée à la création de l'index
par le paramètre pages_per_range
Le nombre des entrées de
l'index sera égal à la taille de la relation en page, divisée par la valeur
sélectionnée dans pages_per_range
. De ce fait, plus ce
nombre est bas, plus l'index sera volumineux (il y a plus d'entrées d'index
à stocker) mais, en même temps, le résumé des informations stockées pourra
être plus précis, et un nombre plus important de blocs de données pourront
être ignorés pendant le parcours d'index.
Lors de la création de l'index, toutes les pages de la table sont parcourues et un résumé des lignes de l'index est créé pour chaque intervalle, incluant certainement aussi un intervalle incomplet à la fin. Lors de l'ajout de nouvelles données dans des pages déja incluses dans des résumés, cela va entrainer la mise à jour du résumé, avec les informations sur les nouvelles lignes insérées. Lorsqu'une nouvelle page est créée et qu'elle ne correspond à aucun des derniers intervalles résumés, l'intervalle auquel appartient la nouvelle page n'acquiert pas automatiquement un résumé ; ces lignes restent sans résumé jusqu'à ce qu'une exécution de résumé soit demandée plus tard, créant ainsi le résumé initial pour cet intervalle.
Il existe plusieurs façons de déclencher le résumé initial d'un intervalle de blocs. Si la table est traitée par VACUUM, soit manuellement soit par l'autovacuum, tous les intervalles de blocs existants non résumés sont résumés. De plus, si le paramètre autosummarize de l'index est activé, ce qui n'est pas le cas par défaut, à chaque fois que l'autovacuum est exécuté dans cette base, le résumé surviendra pour tous les intervalles de blocs non résumés qui ont été remplis, que la table elle-même soit traitée par l'autovacuum ou pas ; voir ci-dessous.
Dernièrement, les fonctions suivantes peuvent être utilisées
(lors de l'exécution de ces fonctions, le paramètre
search_path est temporairement modifié à
pg_catalog, pg_temp
) :
brin_summarize_new_values(regclass)
qui résume tous les blocs sans résumé ;
|
brin_summarize_range(regclass, bigint)
qui résume seulement l'intervalle contenant le bloc donné
s'il n'est pas résumé.
|
Quand le résumé automatique est activé, une requête est envoyée à
l'autovacuum
pour exécuter un résumé cible pour un
intervalle de bloc quand une insertion est détecté pour le premier élément
du premier bloc du prochain intervalle de bloc, opération à réaliser la
prochaine fois qu'un autovacuum worker finit son exécution dans la même
base. Si la queue des demandes est remplie, la demande n'est pas
enregistrée et un message est enregistré dans les traces du serveur :
LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was not recorded
Quand cela arrive, l'intervalle restera non résumé jusqu'à la prochaine exécution d'un vacuum standard sur la table ou jusqu'à ce qu'une des fonctions mentionnées ci-dessus soit appelée.
Inversement, un intervalle peut se voir supprimer son résumé avec la
fonction brin_desummarize_range(regclass, bigint)
, qui
est utile quand l'enregistrement de l'index n'est plus une très bonne
représentation car les valeurs existantes ont changées. Voir Section 9.28.8 pour les détails.
La distribution du noyau PostgreSQL inclut la classe d'opérateur BRIN montrée dans Tableau 64.4.
La classe d'opérateur minmax stocke les valeurs minimale et maximale apparaissant dans l'intervalle de la colonne indexée. L'opérateur de classe inclusion stocke une valeur qui est incluse dans les valeurs contenues dans l'intervalle de la colonne indexée. Les classes d'opérateur bloom génèrent un filtre Bloom pour toutes les valeurs dans l'intervalle. Les classes d'opérateur minmax-multi conservent les multiples valeurs minimale et maximale, représentant les valeurs apparaissant dans la colonne indexée dans l'intervalle.
Tableau 64.4. Classe d'opérateur BRIN intégrée
Nom | Opérateurs indexables |
---|---|
bit_minmax_ops | = (bit,bit) |
< (bit,bit) | |
> (bit,bit) | |
<= (bit,bit) | |
>= (bit,bit) | |
box_inclusion_ops | @> (box,point) |
<< (box,box) | |
&< (box,box) | |
&> (box,box) | |
>> (box,box) | |
<@ (box,box) | |
@> (box,box) | |
~= (box,box) | |
&& (box,box) | |
<<| (box,box) | |
&<| (box,box) | |
|&> (box,box) | |
|>> (box,box) | |
bpchar_bloom_ops | = (character,character) |
bpchar_minmax_ops | = (character,character) |
< (character,character) | |
<= (character,character) | |
> (character,character) | |
>= (character,character) | |
bytea_bloom_ops | = (bytea,bytea) |
bytea_minmax_ops | = (bytea,bytea) |
< (bytea,bytea) | |
<= (bytea,bytea) | |
> (bytea,bytea) | |
>= (bytea,bytea) | |
char_bloom_ops | = ("char","char") |
char_minmax_ops | = ("char","char") |
< ("char","char") | |
<= ("char","char") | |
> ("char","char") | |
>= ("char","char") | |
date_bloom_ops | = (date,date) |
date_minmax_ops | = (date,date) |
< (date,date) | |
<= (date,date) | |
> (date,date) | |
>= (date,date) | |
date_minmax_multi_ops | = (date,date) |
< (date,date) | |
<= (date,date) | |
> (date,date) | |
>= (date,date) | |
float4_bloom_ops | = (float4,float4) |
float4_minmax_ops | = (float4,float4) |
< (float4,float4) | |
> (float4,float4) | |
<= (float4,float4) | |
>= (float4,float4) | |
float4_minmax_multi_ops | = (float4,float4) |
< (float4,float4) | |
> (float4,float4) | |
<= (float4,float4) | |
>= (float4,float4) | |
float8_bloom_ops | = (float8,float8) |
float8_minmax_ops | = (float8,float8) |
< (float8,float8) | |
<= (float8,float8) | |
> (float8,float8) | |
>= (float8,float8) | |
float8_minmax_multi_ops | = (float8,float8) |
< (float8,float8) | |
<= (float8,float8) | |
> (float8,float8) | |
>= (float8,float8) | |
inet_inclusion_ops | << (inet,inet) |
<<= (inet,inet) | |
>> (inet,inet) | |
>>= (inet,inet) | |
= (inet,inet) | |
&& (inet,inet) | |
inet_bloom_ops | = (inet,inet) |
inet_minmax_ops | = (inet,inet) |
< (inet,inet) | |
<= (inet,inet) | |
> (inet,inet) | |
>= (inet,inet) | |
inet_minmax_multi_ops | = (inet,inet) |
< (inet,inet) | |
<= (inet,inet) | |
> (inet,inet) | |
>= (inet,inet) | |
int2_bloom_ops | = (int2,int2) |
int2_minmax_ops | = (int2,int2) |
< (int2,int2) | |
> (int2,int2) | |
<= (int2,int2) | |
>= (int2,int2) | |
int2_minmax_multi_ops | = (int2,int2) |
< (int2,int2) | |
> (int2,int2) | |
<= (int2,int2) | |
>= (int2,int2) | |
int4_bloom_ops | = (int4,int4) |
int4_minmax_ops | = (int4,int4) |
< (int4,int4) | |
> (int4,int4) | |
<= (int4,int4) | |
>= (int4,int4) | |
int4_minmax_multi_ops | = (int4,int4) |
< (int4,int4) | |
> (int4,int4) | |
<= (int4,int4) | |
>= (int4,int4) | |
int8_bloom_ops | = (bigint,bigint) |
int8_minmax_ops | = (bigint,bigint) |
< (bigint,bigint) | |
> (bigint,bigint) | |
<= (bigint,bigint) | |
>= (bigint,bigint) | |
int8_minmax_multi_ops | = (bigint,bigint) |
< (bigint,bigint) | |
> (bigint,bigint) | |
<= (bigint,bigint) | |
>= (bigint,bigint) | |
interval_bloom_ops | = (interval,interval) |
interval_minmax_ops | = (interval,interval) |
< (interval,interval) | |
<= (interval,interval) | |
> (interval,interval) | |
>= (interval,interval) | |
interval_minmax_multi_ops | = (interval,interval) |
< (interval,interval) | |
<= (interval,interval) | |
> (interval,interval) | |
>= (interval,interval) | |
macaddr_bloom_ops | = (macaddr,macaddr) |
macaddr_minmax_ops | = (macaddr,macaddr) |
< (macaddr,macaddr) | |
<= (macaddr,macaddr) | |
> (macaddr,macaddr) | |
>= (macaddr,macaddr) | |
macaddr_minmax_multi_ops | = (macaddr,macaddr) |
< (macaddr,macaddr) | |
<= (macaddr,macaddr) | |
> (macaddr,macaddr) | |
>= (macaddr,macaddr) | |
macaddr8_bloom_ops | = (macaddr8,macaddr8) |
macaddr8_minmax_ops | = (macaddr8,macaddr8) |
< (macaddr8,macaddr8) | |
<= (macaddr8,macaddr8) | |
> (macaddr8,macaddr8) | |
>= (macaddr8,macaddr8) | |
macaddr8_minmax_multi_ops | = (macaddr8,macaddr8) |
< (macaddr8,macaddr8) | |
<= (macaddr8,macaddr8) | |
> (macaddr8,macaddr8) | |
>= (macaddr8,macaddr8) | |
name_bloom_ops | = (name,name) |
name_minmax_ops | = (name,name) |
< (name,name) | |
<= (name,name) | |
> (name,name) | |
>= (name,name) | |
numeric_bloom_ops | = (numeric,numeric) |
numeric_minmax_ops | = (numeric,numeric) |
< (numeric,numeric) | |
<= (numeric,numeric) | |
> (numeric,numeric) | |
>= (numeric,numeric) | |
numeric_minmax_multi_ops | = (numeric,numeric) |
< (numeric,numeric) | |
<= (numeric,numeric) | |
> (numeric,numeric) | |
>= (numeric,numeric) | |
oid_bloom_ops | = (oid,oid) |
oid_minmax_ops | = (oid,oid) |
< (oid,oid) | |
> (oid,oid) | |
<= (oid,oid) | |
>= (oid,oid) | |
oid_minmax_multi_ops | = (oid,oid) |
< (oid,oid) | |
> (oid,oid) | |
<= (oid,oid) | |
>= (oid,oid) | |
pg_lsn_bloom_ops | = (pg_lsn,pg_lsn) |
pg_lsn_minmax_ops | = (pg_lsn,pg_lsn) |
< (pg_lsn,pg_lsn) | |
> (pg_lsn,pg_lsn) | |
<= (pg_lsn,pg_lsn) | |
>= (pg_lsn,pg_lsn) | |
pg_lsn_minmax_multi_ops | = (pg_lsn,pg_lsn) |
< (pg_lsn,pg_lsn) | |
> (pg_lsn,pg_lsn) | |
<= (pg_lsn,pg_lsn) | |
>= (pg_lsn,pg_lsn) | |
range_inclusion_ops | = (anyrange,anyrange) |
< (anyrange,anyrange) | |
<= (anyrange,anyrange) | |
>= (anyrange,anyrange) | |
> (anyrange,anyrange) | |
&& (anyrange,anyrange) | |
@> (anyrange,anyelement) | |
@> (anyrange,anyrange) | |
<@ (anyrange,anyrange) | |
<< (anyrange,anyrange) | |
>> (anyrange,anyrange) | |
&< (anyrange,anyrange) | |
&> (anyrange,anyrange) | |
-|- (anyrange,anyrange) | |
text_bloom_ops | = (text,text) |
text_minmax_ops | = (text,text) |
< (text,text) | |
<= (text,text) | |
> (text,text) | |
>= (text,text) | |
tid_bloom_ops | = (tid,tid) |
tid_minmax_ops | = (tid,tid) |
< (tid,tid) | |
> (tid,tid) | |
<= (tid,tid) | |
>= (tid,tid) | |
tid_minmax_multi_ops | = (tid,tid) |
< (tid,tid) | |
> (tid,tid) | |
<= (tid,tid) | |
>= (tid,tid) | |
timestamp_bloom_ops | = (timestamp,timestamp) |
timestamp_minmax_ops | = (timestamp,timestamp) |
< (timestamp,timestamp) | |
<= (timestamp,timestamp) | |
> (timestamp,timestamp) | |
>= (timestamp,timestamp) | |
timestamp_minmax_multi_ops | = (timestamp,timestamp) |
< (timestamp,timestamp) | |
<= (timestamp,timestamp) | |
> (timestamp,timestamp) | |
>= (timestamp,timestamp) | |
timestamptz_bloom_ops | = (timestamptz,timestamptz) |
timestamptz_minmax_ops | = (timestamptz,timestamptz) |
< (timestamptz,timestamptz) | |
<= (timestamptz,timestamptz) | |
> (timestamptz,timestamptz) | |
>= (timestamptz,timestamptz) | |
timestamptz_minmax_multi_ops | = (timestamptz,timestamptz) |
< (timestamptz,timestamptz) | |
<= (timestamptz,timestamptz) | |
> (timestamptz,timestamptz) | |
>= (timestamptz,timestamptz) | |
time_bloom_ops | = (time,time) |
time_minmax_ops | = (time,time) |
< (time,time) | |
<= (time,time) | |
> (time,time) | |
>= (time,time) | |
time_minmax_multi_ops | = (time,time) |
< (time,time) | |
<= (time,time) | |
> (time,time) | |
>= (time,time) | |
timetz_bloom_ops | = (timetz,timetz) |
timetz_minmax_ops | = (timetz,timetz) |
< (timetz,timetz) | |
<= (timetz,timetz) | |
> (timetz,timetz) | |
>= (timetz,timetz) | |
timetz_minmax_multi_ops | = (timetz,timetz) |
< (timetz,timetz) | |
<= (timetz,timetz) | |
> (timetz,timetz) | |
>= (timetz,timetz) | |
uuid_bloom_ops | = (uuid,uuid) |
uuid_minmax_ops | = (uuid,uuid) |
< (uuid,uuid) | |
> (uuid,uuid) | |
<= (uuid,uuid) | |
>= (uuid,uuid) | |
uuid_minmax_multi_ops | = (uuid,uuid) |
< (uuid,uuid) | |
> (uuid,uuid) | |
<= (uuid,uuid) | |
>= (uuid,uuid) | |
varbit_minmax_ops | = (varbit,varbit) |
< (varbit,varbit) | |
> (varbit,varbit) | |
<= (varbit,varbit) | |
>= (varbit,varbit) |
Certaines des classes d'opérateur intégrées permettent aux paramétres
spécifiés d'affecter leurs comportements. Chaque opérateur de classe a
son propre ensemble de paramètres autorisés. Seules les classes
d'opérateur bloom
et minmax-multi
permettent de spécifier ces paramètres :
Les classes d'opérateur bloom acceptent ces paramètres :
n_distinct_per_range
Définit le nombre estimé de valeurs non NULL distinctes dans un
intervalle de blocs, utilisé par les index bloom BRIN
pour dimensionner le filtre Bloom. Il se comporte similairement à
l'option n_distinct
pour ALTER TABLE. Quand la valeur affectée est positive, il
est supposé que chaque intervalle de blocs contient ce nombre de valeurs
non NULL distinctes. Quand la valeur affectée est négative mais
supérieure ou égale à -1, il est supposé que le nombre de valeurs non
NULL distinctes croît linéairement avec le nombre maximum possible de
lignes dans l'intervalle de blocs(environ 290 lignes par bloc). La
valeur par défaut est -0,1
, et le nombre minimum de
valeurs distinctes non NULL est 16
.
false_positive_rate
Définit le taux désiré de faux positifs utilisé par les index bloom BRIN pour dimensionner le filtre Bloom. La valeur doit être comprise entre 0,0001 et 0,25. La valeur par défaut est 0,01, ce qui correspond à 1% pour le taux de faux positifs.
Les classes d'opérateur minmax-multi accepte ces paramètres :
values_per_range
Définit le nombre maximum de valeurs conservées par les index minmax BRIN pour résumer un intervalle de blocs. Chaque valeur peut représenter un point, ou une limite d'un intervalle. La valeur doit être comprise entre 8 et 256, et la valeur par défaut est 32.
L'interface BRIN possède un niveau élevé d'abstraction, qui nécessite l'implémentation de la méthode d'accès rien que pour l'implémentation de la sémantique des types de données accédées. La couche BRIN s'occupera par contre elle-même de la concurrence, l'accès et la recherche dans la structure de l'index.
Tout ce qu'il faut pour faire fonctionner la méthode d'accès BRIN est d'implémenter quelques méthodes utilisateurs, déterminant pour l'index les genre de valeurs stockées dans le résumé et la manière dont elles interagissent avec les nœuds du parcours. En bref, BRIN combine l'extensibilité avec la généralité, la réutilisation du code et une interface claire.
Il y a quatre méthodes qu'un opérateur de classe pour BRIN doit fournir :
BrinOpcInfo *opcInfo(Oid type_oid)
Retourne les informations internes au sujet du résumé de données de la
colonne indexée. Cette valeur doit pointer vers une structure
BrinOpcInfo
(allouée avec la fonction palloc),
qui a cette définition :
typedef struct BrinOpcInfo { /* Nombre de colonnes stockées dans une colonne indexée de cette classe d'opérateur */ uint16 oi_nstored; /* Pointeur opaque pour l'utilisation privée de la classe d'opérateur */ void *oi_opaque; /* Type des entrées cachées de la colonne stockées */ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; } BrinOpcInfo;
BrinOpcInfo
.oi_opaque
peut être utilisé par les routines d'opérateur de classe pour
transmettre des informations entre les procédures de support pendant le
parcours de l'index.
bool consistent(BrinDesc *bdesc, BrinValues *column,
ScanKey *keys, int nkeys)
Retourne si toutes les entrées ScanKey sont cohérentes avec les valeurs
indexées données pour cet intervalle. Le nombre d'attributs à utiliser
est passé en tant que partie de la clé de parcours. De multiples clés
de parcours pour un même attribut peuvent être passées en une
fois ; le nombre d'entrées est déterminé par le paramètre
nkeys
.
bool consistent(BrinDesc *bdesc, BrinValues *column,
ScanKey key)
Retourne la clé de parcours si elle est cohérente avec les valeurs indexées données pour cet intervalle. Le nombre attribué à utiliser est passé en tant que partie de la clé de parcours. Cette version est une variante pour compatibilité descendante plus ancienne de la fonction de cohérence.
bool addValue(BrinDesc *bdesc, BrinValues *column,
Datum newval, bool isnull)
Renvoie à une ligne indexée et une valeur indexée, modifie les
attributs indiqués de cette ligne, de manière à ce que le cumul
représente la nouvelle valeur. Si une modification a été apportée à la
ligne, la valeur true
est retournée.
bool unionTuples(BrinDesc *bdesc, BrinValues *a,
BrinValues *b)
Consolidation de deux lignes d'index. Ceci en prenant deux lignes d'index et en modifiant l'attribut indiqué de la première des deux, de manière à ce qu'elle représente les deux lignes. La seconde ligne n'est pas modifiée.
Une classe d'opérateur pour BRIN peut indiquer en option la méthode suivante :
void options(local_relopts *relopts)
Définit un ensemble de paramètres visibles aux utilisateurs qui contrôlent le comportement d'une classe d'opérateur.
La fonction options
se voit donné un pointeur
vers une structure local_relopts
qui doit
être remplie avec un ensemble d'options spécifiques à la classe
d'opérateur. Les options peuvent être accédées à partir des autres
fonctions de support en utilisant les macros
PG_HAS_OPCLASS_OPTIONS()
et
PG_GET_OPCLASS_OPTIONS()
.
Étant donné que l'extraction des clés des valeurs indexées et la représentation de la clé dans BRIN sont flexibles, elles peuvent dépendre de paramètres spécifiés par l'utilisateur.
La distribution du noyau inclut du support pour les quatre types de classe d'opérateur : minmax, minmax-multi, inclusion et bloom. Les définitions de classes d'opérateur qui les utilisent sont envoyées en types de données basiques appropriées. Des classes d'opérateurs appropriées peuvent être définies par l'utilisateur pour d'autres types de données utilisant des définitions équivalentes, et ceci sans avoir besoin d'écrire du code source. La déclaration des entrées appropriées dans le catalogue est suffisante. Notez que les hypothèses sur les sémantiques de stratégie d'opérateurs sont embarquées dans les fonctions de support du code source.
Les classes d'opérateurs qui implémentent des sémantiques complètement différentes sont utilisables. Les implémentations fournies par les quatre principales fonctions de support présentées ci-dessous sont écrites. Notez que la compatibilité ascendante entre les versions majeures n'est pas garantie : par exemple, les fonctions de support additionnelles peuvent être requises dans des versions ultérieures.
Pour écrire une classe d'opérateur pour un type de données qui implémente un résultat complétement ordonné, il est possible d'utiliser les fonctions de support "minmax" avec les opérateurs correspondant tel que décrit dans Tableau 64.5. Tous les membres de classe d'opérateurs (fonctions et opérateurs) sont obligatoires.
Tableau 64.5. Fonctions et numéros de support pour les classes d'opérateur Minmax
Membre de classe d'opérateur | Objet |
---|---|
Fonction de support 1 | Fonction interne brin_minmax_opcinfo() |
Fonction de support 2 | Fonction interne brin_minmax_add_value() |
Fonction de support 3 | Fonction interne brin_minmax_consistent() |
Fonction de support 4 | Fonction interne brin_minmax_union() |
Stratégie d'opérateur 1 | Opérateur strictement inférieur |
Stratégie d'opérateur 2 | Opérateur inférieur |
Stratégie d'opérateur 3 | Opérateur d'égalité |
Stratégie d'opérateur 4 | Opérateur supérieur |
Stratégie d'opérateur 5 | Opérateur strictement supérieur |
Pour écrire un opérateur de classe pour un type de données complexe, qui aurait des valeurs incluses dans un autre type, il est possible d'utiliser la fonction de support d'inclusion avec l'opérateur correspondant, tel que décrit dans Tableau 64.6. Cela nécessite uniquement une simple fonction d'addition, qui peut être écrite dans n'importe quel langage. Des fonctions supplémentaires peuvent être définies pour obtenir des fonctionnalités additionnelles. Tous les opérateurs sont optionnels. Certains opérateurs requièrent d'autres opérateurs, affichés en tant que dépendances de la table.
Tableau 64.6. Fonctions et numéros de support pour les classes d'opérateur d'inclusion
Membre de classe d'opérateur | Objet | Dépendance |
---|---|---|
Fonction de support 1 | Fonction interne brin_inclusion_opcinfo() | |
Fonction de support 2 | Fonction interne brin_inclusion_add_value() | |
Fonction de support 3 | Fonction interne brin_inclusion_consistent() | |
Fonction de support 4 | Fonction interne brin_inclusion_union() | |
Fonction de support 11 | Fonction de fusion de deux élements | |
Fonction de support 12 | Fonction optionnelle de vérification si les deux éléments peuvent être fusionnés | |
Fonction de support 13 | Fonction optionnelle de vérification si un élément est contenu dans un autre | |
Fonction de support 14 | Fonction optionnelle de vérification si un élement est vide | |
Stratégie d'opérateur 1 | Opérateur A-gauche-de | Stratégie d'opérateur 4 |
Stratégie d'opérateur 2 | Opérateur Ne-s-etend-pas-à-la-droite-de | Stratégie d'opérateur 5 |
Stratégie d'opérateur 3 | Opérateur chevauchement | |
Stratégie d'opérateur 4 | Opérateur Ne-s-etend-pas-à-la-gauche-de | Stratégie d'opérateur 1 |
Stratégie d'opérateur 5 | Opérateur A-droite-de | Stratégie d'opérateur 2 |
Stratégie d'opérateur 6, 18 | Opérateur Equivalent-ou-identique-à | Stratégie d'opérateur 7 |
Stratégie d'opérateur 7, 16, 24, 25 | Opérateur Contient-ou-identique-à | |
Stratégie d'opérateur 8, 26, 27 | Opérateur Contient-ou-identique-à | Stratégie d'opérateur 3 |
Stratégie d'opérateur 9 | Opérateur Ne-s-étend-pas-plus-loin | Stratégie d'opérateur 11 |
Stratégie d'opérateur 10 | Opérateur Est-le-suivant | Stratégie d'opérateur 12 |
Stratégie d'opérateur 11 | Opérateur Est-le-précédent | Stratégie d'opérateur 9 |
Stratégie d'opérateur 12 | Opérateur Ne-s-étend-pas-plus-loin | Stratégie d'opérateur 10 |
Stratégie d'opérateur 20 | Opérateur Strictement-inférieur-à | Stratégie d'opérateur 5 |
Stratégie d'opérateur 21 | Opérateur Inférieur-à | Stratégie d'opérateur 5 |
Stratégie d'opérateur 22 | Opérateur Strictement-supérieur-à | Stratégie d'opérateur 1 |
Stratégie d'opérateur 23 | Opérateur supérieur-à | Stratégie d'opérateur 1 |
Les numéros 1 à 10 des fonctions support sont reservés pour les fonctions
internes BRIN, de ce fait le niveau des fonctions SQL commence à 11. La
fonction de support 11 est la principale fonction utilisée pour construire
l'index. Elle doit accepter deux arguments, avec le même type de données que
la la classe d'opérateur, et renvoyer l'union des deux. La classe
d'opérateur inclusion peut stocker des valeurs unies de types différents si
elles sont définies avec le paramètre STORAGE
La valeur
renvoyée par la fonction union doit correspondre au type de données
STORAGE
Les numéros 12 et 14 des fonctions de support sont fournies pour supporter les irrégularités des types de données internes. La fonction 12 est utilisée pour supporter les adresses réseaux de différentes familles qui ne sont pas fusionnables. La fonction 14 est utilisée pour supporter les intervalles vides. La fonction 13 est une fonction optionnelle mais recommandée. Elle permet à une nouvelle valeur d'être vérifiée avant d'être passée à la fonction d'union. Puisque BRIN peut raccourcir certaines opérations lorsque l'union n'est pas modifiée, utiliser cette fonction peut améliorer les performances de l'index.
Pour écrire une classe d'opérateur pour un type de données qui implémente seulement l'opérateur égalité et supporte le hachage, il est possible d'utiliser les procédures d'appui bloom aux côtés des opérateurs correspondants, comme montré dans Tableau 64.7. Tout membre de classe d'opérateur (procédures et opérateurs) sont obligatoires.
Tableau 64.7. Procédures et numéros de support pour les classes d'opérateur Bloom
Membre de la classe d'opérateur | Objet |
---|---|
Procédure support 1 | Fonction interne brin_bloom_opcinfo() |
Procédure support 2 | Fonction interne brin_bloom_add_value() |
Procédure support 3 | Fonction interne brin_bloom_consistent() |
Procédure support 4 | Fonction interne brin_bloom_union() |
Fonction de support 5 | fonction interne brin_bloom_options() |
Procédure support 11 | Fonction pour calculer le hachage d'un élément |
Stratégie d'opérateur 1 | Opérateur égal-à |
Les procédures support numéros 1-10 sont réservées pour les fonctions internes BRIN, ainsi les fonctions au niveau SQL débutent avec le numéro 11. La fonction support numéro 11 est la principale fonction requise pour construire un index. Elle doit accepter un argument avec le même type de données que la classe d'opérateur et retourner un hachage de la valeur.
La classe d'opérateur minmax-multi est aussi prévue pour les types de données implémentant un ensemble totalement ordonné, et peut être vue comme une simple extension de la classe d'opérateur minmax. Tandis que la classe d'opérateur minmax résume les valeurs pour chaque intervalle de bloc dans un intervalle unique et contigu, minmax-multi permet de résumer dans de multiples intervalles plus petits pour améliorer la gestion des valeurs aberrantes. Il est possible d'utiliser les procédures support minmax-multi aux côtés des opérateurs correspondant, comme indiqué dans Tableau 64.8. Tous les membres de classe d'opérateur (procédures et opérateurs) sont obligatoires.
Tableau 64.8. Procédure et numéros de support pour les classes d'opérateur minmax-multi
Membre de classe d'opérateur | Objet |
---|---|
Procédure support 1 | Fonction interne brin_minmax_multi_opcinfo() |
Procédure support 2 | Fonction interne brin_minmax_multi_add_value() |
Procédure support 3 | Fonction interne brin_minmax_multi_consistent() |
Procédure support 4 | Fonction interne brin_minmax_multi_union() |
Fonction de support 5 | Fonction interne brin_minmax_multi_options() |
Procédure support 11 | Fonction de calcul de distance entre deux valeurs (longueur d'un intervalle) |
Stratégie d'opérateur 1 | Opérateur inférieur-à |
Stratégie d'opérateur 2 | Opérateur inférieur-ou-égal-à |
Stratégie d'opérateur 3 | Opérateur égal-à |
Stratégie d'opérateur 4 | Opérateur supérieur-ou-égal-à |
Stratégie d'opérateur 5 | Opérateur supérieur-à |
Les classes d'opérateur minmax et inclusion supportent les opérateurs
utilisables sur des types de données croisés, même si cela complexifie la
gestion des dépendances. La classe d'opérateur minmax a besoin d'un
ensemble complet d'opérateurs pour être définie avec deux arguments qui
auraient le même type de données. Cela permet aux types de données
additionnels d'être supportés en définissant un ensemble d'opérateurs
supplémentaires. Les opérateurs de la classe d'opérateur inclusion sont
dépendants d'autres stratégies d'opérateur tel que décrit dans le Tableau 64.6, ou des mêmes stratégie
d'opérateur qu'eux-même. Cela nécessite que l'opérateur dépendant soit
défini avec le type de données STORAGE
pour l'argument
du côté gauche, et que l'autre type de données supportée se trouve du côté
droit de l'opérateur de support. Vous pouvez consulter
float4_minmax_ops
comme exemple pour minmax et
box_inclusion_ops
comme exemple pour inclusion.