forked from gleu/pgdocs_fr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
intagg.xml
136 lines (114 loc) · 4.43 KB
/
intagg.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?xml version="1.0" encoding="UTF-8"?>
<!-- Dernière modification
le $Date$
par $Author$
révision $Revision$ -->
<sect1 id="intagg">
<title>intagg</title>
<indexterm zone="intagg">
<primary>intagg</primary>
</indexterm>
<para>
Le module <filename>intagg</filename> fournit un
agrégateur d'entiers et un énumérateur. <filename>intagg</filename> est
maintenant obsolète car il existe des fonctions intégrées qui fournissent
les mêmes fonctionnalités. Néanmoins, le module est toujours disponible
pour fournir des fonctions de compatibilité.
</para>
<sect2>
<title>Fonctions</title>
<para>
L'agrégateur est une fonction d'agrégat
<function>int_array_aggregate(integer)</function> qui produit un tableau
d'entiers contenant exactement les entiers fournis en argument.
Cette fonction appelle <function>array_agg</function> pour des raisons de
compatibilité.
</para>
<para>
L'énumérateur est une fonction
<function>int_array_enum(integer[])</function> qui renvoie
<type>setof integer</type>. C'est essentiellement une opération reverse de
l'agrégateur : elle étend un tableau d'entiers en un ensemble de
lignes. Cette fonction appelle <function>unnest</function>, pour des raisons
de compatibilité.
</para>
</sect2>
<sect2>
<title>Exemples d'utilisation</title>
<para>
Un grand nombre de bases de données utilisent la notion de table <quote>une vers
plusieurs</quote> (<foreignphrase>one to many</foreignphrase>). Ce type de table
se trouve habituellement entre deux tables indexés, par exemple :
</para>
<programlisting>
CREATE TABLE left (id INT PRIMARY KEY, ...);
CREATE TABLE right (id INT PRIMARY KEY, ...);
CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);
</programlisting>
<para>
Il est typiquement utilisé de cette façon :
</para>
<programlisting>
SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
WHERE one_to_many.left = <replaceable>item</replaceable>;
</programlisting>
<para>
Cela renvoie tous les éléments de la table de droite pour un enregistrement
de la table de gauche donné. Il s'agit d'une construction assez commune en SQL.
</para>
<para>
Cette méthode devient complexe lorsqu'il existe de nombreuses entrées dans la
table <structname>one_to_many</structname>. Souvent, une jointure
de ce type résulte en un parcours d'index et une récupération de chaque enregistrement de
la table de droite pour une entrée particulière de la table de gauche.
Sur un système dynamique, il n'y a pas grand chose à faire. Au contraire,
lorsqu'une partie des données est statique, une table de résumé peut être
créée par agrégation.
</para>
<programlisting>
CREATE TABLE summary as
SELECT left, int_array_aggregate(right) AS right
FROM one_to_many
GROUP BY left;
</programlisting>
<para>
Ceci crée une table avec une ligne par élément gauche et un tableau d'éléments
droits. En l'absence de méthode d'utilisation de tableau, c'est réellement
inutilisable, d'où l'énumérateur.
</para>
<para>
Exemple :
</para>
<programlisting>
SELECT left, int_array_enum(right) FROM summary WHERE left = <replaceable>item</replaceable>;
</programlisting>
<para>
La requête ci-dessus, qui utilise <function>int_array_enum</function>, produit les mêmes résultats
que celle-ci :
</para>
<programlisting>
SELECT left, right FROM one_to_many WHERE left = <replaceable>item</replaceable>;
</programlisting>
<para>
La différence tient dans le fait que la requête qui utilise la table de résumé
ne récupère qu'une ligne de la table alors que la requête directe à
<structname>one_to_many</structname> doit faire un parcours d'index et
récupérer une ligne par enregistrement.
</para>
<para>
Sur un système particulier, un <command>EXPLAIN</command> a montré qu'une requête avec
un coût de 8488 a été réduite à une requête d'un coût de 329. La requête
originale était une jointure impliquant la table
<structname>one_to_many</structname>, remplacée par :
</para>
<programlisting>
SELECT right, count(right) FROM
( SELECT left, int_array_enum(right) AS right
FROM summary JOIN (SELECT left FROM left_table WHERE left = <replaceable>item</replaceable>) AS lefts
ON (summary.left = lefts.left)
) AS list
GROUP BY right
ORDER BY count DESC;
</programlisting>
</sect2>
</sect1>