PostgreSQLLa base de données la plus sophistiquée au monde.

F.4. cube

Ce module code le type de données cube pour représenter des cubes à plusieurs dimensions.

F.4.1. Syntaxe

Ce qui suit est un ensemble de représentations externes valides pour le type cube. x, y... sont des nombres en virgule flottante :

Tableau F.1. Représentations externes d'un cube

x point uni-dimensionnel (ou interval unidimensionnel de longueur nulle)
(x) Identique à ci-dessus
x1,x2,...,xn Un point dans un espace à n dimensions, représenté en interne comme un cube de volume nul
(x1,x2,...,xn) Identique à ci-dessus
(x),(y) Interval uni-dimensionnel débutant à x et finissant à y ou vice-versa ; l'ordre n'importe pas
[(x),(y)] Identique à ci-dessus
(x1,...,xn),(y1,...,yn) Cube à n dimensions représenté par paires de coins diagonalement opposés
[(x1,...,xn),(y1,...,yn)] Identique à ci-dessus

L'ordre de saisie des coins opposés d'un cube n'a aucune importance. Les fonctions cube s'occupent de la bascule nécessaire à l'obtention d'une représentation uniforme « bas gauche, haut droit ».

Les espaces sont ignorées, [(x),(y)] est donc identique à [ ( x ), ( y ) ].

F.4.2. Précision

Les valeurs sont enregistrées en interne sous la forme de nombres en virgule flottante. Cela signifie que les nombres avec plus de 16 chiffres significatifs sont tronqués.

F.4.3. Utilisation

Le module cube inclut une classe d'opérateur pour index GiST pour les valeurs de type cube. Les opérateurs supportés par la classe d'opérateur GiST incluent :

  • a = b                  Identique à
        
    

    Les cubes a et b sont identiques.

  • a && b                Recouvre
        
    

    Les cubes a et b se chevauchent.

  • a @> b                Contient
        
    

    Le cube a contient le cube b.

  • a <@ b                Contenu dans
      
    

    Le cube a est contenu dans le cube b.

(Avant PostgreSQL 8.2, les opérateurs de contenance @> et <@ étaient appelés respectivement @ et ~. Ces noms sont toujours disponibles mais sont déclarés obsolètes et seront supprimés un jour. Les anciens noms sont inversés par rapport à la convention suivie par les types de données géométriques !)

Les opérateurs du standard B-tree sont aussi fournis, par exemple :

[a, b] < [c, d]                Plus petit que
[a, b] > [c, d]                Plus grand que
  

Ces opérateurs n'ont vraiment de sens que pour le tri. Ces opérateurs comparent en premier (a) à (c) et, s'ils sont égaux, comparent (b) à (d). Cela fait un bon tri dans la plupart des cas, ce qui permet d'utiliser ORDER BY avec ce type.

Les fonctions suivantes sont disponibles :

Tableau F.2. Fonctions cube

cube(float8) returns cube Crée un cube uni-dimensionnel de coordonnées identiques. cube(1) == '(1)'
cube(float8, float8) returns cube Crée un cube uni-dimensionnel. cube(1,2) == '(1),(2)'
cube(float8[]) returns cube Crée un cube de volume nul en utilisant les coordonnées définies par le tableau. cube(ARRAY[1,2]) == '(1,2)'
cube(float8[], float8[]) returns cube Crée un cube avec les coordonnées haut droit et bas gauche définies par deux tableaux de flottants, obligatoirement de même taille. cube('{1,2}'::float[], '{3,4}'::float[]) == '(1,2),(3,4)'
cube(cube, float8) returns cube Construit un nouveau cube en ajoutant une dimension à un cube existant avec les mêmes valeurs pour les deux parties de la nouvelle coordonnée. Ceci est utile pour construire des cubes pièce par pièce à partir de valeurs calculées. cube('(1)',2) == '(1,2),(1,2)'
cube(cube, float8, float8) returns cube Crée un nouveau cube en ajoutant une dimension à un cube existant. Ceci est utile pour construire des cubes pièce par pièce à partir de valeurs calculées. cube('(1,2)',3,4) == '(1,3),(2,4)'
cube_dim(cube) returns int Renvoie le nombre de dimensions du cube.
cube_ll_coord(cube, int) returns double Renvoie la n-ième coordonnée pour le coin en bas à gauche d'un cube.
cube_ur_coord(cube, int) returns double Renvoie la n-ième coordonnée pour le coin en haut à droite d'un cube.
cube_is_point(cube) returns bool Renvoie true si un cube est aussi un point, c'est-à-dire si les deux coins de définition sont identiques.
cube_distance(cube, cube) returns double Renvoie la distance entre deux cubes. Si les deux cubes sont des points, il s'agit de la fonction de distance habituelle.
cube_subset(cube, int[]) returns cube Crée un nouveau cube à partir d'un cube existant en utilisant une liste d'index de dimension d'un tableau. Peut être utilisé pour trouver les coordonnées bas gauche et haut droit d'une dimension, par exemple : cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2]) = '(3),(7)'. Peut aussi être utilisé pour supprimer des dimensions, ou pour les réordonner, par exemple : cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]) = '(5, 3, 1, 1),(8, 7, 6, 6)'.
cube_union(cube, cube) returns cube Réalise l'union de deux cubes.
cube_inter(cube, cube) returns cube Réalise l'intersection de deux cubes.
cube_enlarge(cube c, double r, int n) returns cube Augmente la taille d'un cube suivant un rayon précisé dans au moins n dimensions. Si le rayon est négatif, la boîte est diminuée. C'est utile pour créer des boîtes limitantes autour d'un point dans le but de rechercher les points voisins. Toutes les dimensions définies sont modifiées de la valeur du rayon r. Les coordonnées bas gauche sont décrémentées de r et les coordonnées haut droit sont incrémentées de r. Si une coordonnée bas gauche est incrémentée au-delà de la valeur correspondante haut droit (ce qui ne peut arriver que lorsque r < 0), les deux coordonnées sont positionnées à leur moyenne. Si n est plus grand que le nombre de dimensions définies et que le cube est augmenté (r >= 0), alors 0 est utilisé comme base des coordonnées supplémentaires.

F.4.4. Par défaut

Le développeur pense que l'union :

select cube_union('(0,5,2),(2,3,1)', '0');
cube_union
-------------------
(0, 0, 0),(2, 5, 2)
(1 row)

n'est pas en contradiction avec le bon sens. Pas plus que l'intersection

select cube_inter('(0,-1),(1,1)', '(-2),(2)');
cube_inter
-------------
(0, 0),(1, 0)
(1 row)

Dans toutes les opérations binaires sur des boîtes de tailles différentes, l'auteur suppose que la plus petite est une projection cartésienne, c'est-à-dire qu'il y a des zéros à la place des coordonnées omises dans la représentation sous forme de chaîne. Les exemples ci-dessus sont équivalents à :

cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)');
cube_inter('(0,-1),(1,1)','(-2,0),(2,0)');

Le prédicat de contenance suivant utilise la syntaxe en points alors qu'en fait, le second argument est représenté en interne par une boîte. Cette syntaxe rend inutile la définition du type point et des fonctions pour les prédicats (boîte,point).

select cube_contains('(0,0),(1,1)', '0.5,0.5');
cube_contains
--------------
t
(1 row)

F.4.5. Notes

Pour des exemples d'utilisation, voir les tests de régression sql/cube.sql.

Pour éviter toute mauvaise utilisation, le nombre de dimensions des cubes est limité à 100. Cela se configure dans cubedata.h.

F.4.6. Crédits

Auteur d'origine : Gene Selkov, Jr. , Mathematics and Computer Science Division, Argonne National Laboratory.

F.4.7. Note de l'auteur

Mes remerciements vont tout particulièrement au professeur Joe Hellerstein (http://db.cs.berkeley.edu/~jmh/) qui a su extraire l'idée centrale de GiST (http://gist.cs.berkeley.edu/), et à son étudiant précédant, Andy Dong (http://best.me.berkeley.edu/~adong/), pour son exemple rédigé dans Illustra. Mes remerciements vont également aux développeurs de PostgreSQL qui m'ont permis de créer mon propre monde et de pouvoir y vivre sans être dérangé. Toute ma gratitude aussi à Argonne Lab et au département américain de l'énergie pour les années de support dans mes recherches sur les bases de données.

Des modifications mineures ont été effectuées sur ce module par Bruno Wolff III en août/septembre 2002. Elles incluent la modification de la précision (de simple à double) et l'ajout de quelques nouvelles fonctions.

Des mises à jour supplémentaires ont été réalisées par Joshua Reich en juillet 2006. Elles concernent l'ajout de cube(float8[], float8[]) et le nettoyage du code pour utiliser le protocole d'appel V1 à la place de la forme V0 maintenant obsolète.