Introduction à la base de données PostgreSQL 2-utilisation

2.1. Introduction

Ce chapitre est un aperçu de la façon d'effectuer des opérations simples à l'aide de SQL. Le but de ce didacticiel est simplement de vous donner une introduction, pas un didacticiel SQL complet. Il existe de nombreux livres sur SQL, notamment Understanding the New SQL et A Guide to the SQL Standard. Ce que vous devez savoir, c'est que certaines fonctionnalités du langage PostgreSQL sont des extensions du standard.

Dans les exemples suivants, nous supposons que vous avez créé une base de données nommée mydb, comme décrit dans le chapitre précédent, et que vous avez démarré psql.

Les exemples de ce manuel se trouvent également dans le répertoire src / tutorial / de la distribution du code source de PostgreSQL (la distribution binaire de PostgreSQL peut ne pas être en mesure de compiler ces fichiers). Pour utiliser ces fichiers, entrez d'abord dans le répertoire, puis exécutez make:

   $ cd ..../src/tutorial
   $ make

Cela crée un script et compile un fichier C contenant des fonctions et des types définis par l'utilisateur. Pour démarrer ce didacticiel, procédez comme suit:

   $ cd ..../src/tutorial
   $ psql -s mydb
   ...
   mydb=> \i basics.sql

La commande \ i lit les commandes à partir du fichier spécifié. L'option -s de psql vous met en mode pas-à-pas, qui se mettra en pause avant d'envoyer chaque instruction au serveur. Les commandes utilisées dans cette section se trouvent dans le fichier basics.sql

2.2. Concept

PostgreSQL est un système de gestion de base de données relationnelle (SGBDR). Cela signifie qu'il s'agit d'un système de gestion de données stockées sous forme relationnelle. La relation est en fait un terme mathématique pour les tableaux. Aujourd'hui, le concept de stockage des données dans des tables est devenu un sens commun inhérent, mais il existe d'autres méthodes pour organiser les bases de données. Les fichiers et répertoires sur les systèmes d'exploitation de type Unix constituent un exemple de base de données hiérarchique. Un développement plus moderne est la base de données orientée objet.

Chaque table est un ensemble de lignes nommées, et chaque ligne d'une table donnée se compose d'un ensemble de champs nommés identiques. Et chaque champ est un type de données spécifique. Bien que la position de chaque champ dans chaque ligne soit fixe, il est important de se rappeler que SQL ne donne aucune garantie sur l'ordre des lignes dans le tableau (bien que leur affichage puisse être clairement trié).

Les tables forment une base de données et une série de bases de données gérées par un certain serveur PostgreSQL forment un cluster de bases de données.

2.3. Créer une nouvelle table

Vous pouvez créer une table en déclarant le nom de la table et tous les noms de champs et leurs types:

   CREATE TABLE weather (
       city            varchar(80),
       temp_lo         int,           -- low temperature
       temp_hi         int,           -- high temperature
       prcp            real,          -- precipitation
       date            date
   );

Vous pouvez entrer ces codes dans psql avec un caractère de nouvelle ligne, et il peut reconnaître la commande jusqu'à ce que le point-virgule se termine.

Vous pouvez utiliser librement des espaces (c'est-à-dire des espaces, des tabulations et des retours à la ligne) dans les commandes SQL. Cela signifie que vous pouvez taper des commandes dans un alignement différent de celui ci-dessus, et même écrire tout le code sur une seule ligne. Deux tirets ("-") introduisent des commentaires. Tout ce qui suit jusqu'à la fin de la ligne sera ignoré. SQL n'est pas sensible à la casse des mots-clés et des identificateurs, sauf si l'identificateur est entouré de guillemets doubles pour conserver leurs attributs de casse (pas le cas ci-dessus).

varchar (80) déclare un type de données qui peut stocker n'importe quelle chaîne de 80 caractères maximum. int est un type entier normal. real est un type utilisé pour stocker des nombres à virgule flottante simple précision. Le type de date doit être explicite. (Oui, le nom du champ de type date est également date. Cela peut être plus pratique, ou cela peut prêter à confusion - voyez par vous-même.)

PostgresSQL prend en charge les types SQL standard int, smallint, real, double precision, char (N), varchar (N), date, time, timestamp et interval, ainsi que d'autres types courants et types géométriques riches. PostgreSQL peut personnaliser n'importe quel nombre de types de données définis par l'utilisateur. Par conséquent, le nom du type n'est pas un mot clé grammatical, sauf dans les cas particuliers requis par la norme SQL.

Le deuxième exemple enregistrera les noms des villes et leurs emplacements géographiques associés:

   CREATE TABLE cities (
       name            varchar(80),
       location        point
   );

Le type de données point est un exemple de type de données unique à PostgreSQL.

Enfin, nous mentionnerons également que si vous n'avez plus besoin d'une table, ou que vous souhaitez créer une table différente, vous pouvez la supprimer avec la commande suivante:

   DROP TABLE tablename;

2.4. Ajouter des lignes au tableau

La commande INSERT suivante est utilisée pour ajouter des lignes à la table:

   INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');

Il convient de noter que tous les types de données utilisent un format d'entrée assez clair. Les constantes qui ne sont pas de simples valeurs numériques doivent être entourées de guillemets simples ('), comme dans l'exemple. Le type de date est en fait assez flexible pour le format acceptable, mais dans ce tutoriel, nous nous en tiendrons ici à un format d'affichage clair.

Le type de point nécessite une paire de coordonnées en entrée, comme suit:

   INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');

La syntaxe utilisée jusqu'à présent vous oblige à vous souvenir de l'ordre des champs. Une syntaxe facultative vous permet de lister explicitement les champs:

   INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)
       VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');

Si vous en avez besoin, vous pouvez répertorier les champs dans un autre ordre ou ignorer certains champs. Par exemple, nous ne connaissons pas la quantité de précipitations:

       INSERT INTO weather (date, city, temp_hi, temp_lo)
           VALUES ('1994-11-29', 'Hayward', 54, 37);

De nombreux développeurs pensent qu'il vaut mieux répertorier les champs explicitement que de se fier à l'ordre implicite.

Veuillez saisir toutes les commandes ci-dessus afin que vous ayez des données disponibles dans les sections suivantes.

Vous pouvez également charger de grandes quantités de données à partir de fichiers texte à l'aide de la commande COPY. C'est généralement plus rapide, car la commande COPY est optimisée pour ce type d'application, mais elle est moins flexible que INSERT. tel que:

   COPY weather FROM '/home/user/weather.txt';

Ici, le nom de fichier du fichier source doit être accessible par le serveur principal, pas par le client, car le serveur principal lit le fichier directement. Vous pouvez en savoir plus sur la commande COPY dans la section COPY.

2.5. Interroger une table

La récupération des données d'une table interroge en fait cette table. La commande SQL SELECT est utilisée à cet effet. L'instruction est divisée en une liste de sélection (la partie qui répertorie les champs à renvoyer), une liste de tables (la partie qui répertorie la table à partir de laquelle les données sont extraites) et des conditions facultatives (la partie qui déclare les restrictions). Par exemple, pour récupérer toutes les lignes de la table météo, tapez:

   SELECT * FROM weather;[1]

Ici * est l'abréviation de "toutes les colonnes". Le même résultat peut être obtenu par la requête suivante:

   SELECT city, temp_lo, temp_hi, prcp, date FROM weather;

Et la sortie devrait être:

        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
    San Francisco |      43 |      57 |    0 | 1994-11-29
    Hayward       |      37 |      54 |      | 1994-11-29
   (3 rows)

Vous pouvez écrire des expressions arbitraires dans la liste de sélection, pas seulement des références de colonne. Par exemple, vous pouvez:

   SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;

Cela devrait donner:

        city      | temp_avg |    date
   ---------------+----------+------------
    San Francisco |       48 | 1994-11-27
    San Francisco |       50 | 1994-11-29
    Hayward       |       45 | 1994-11-29
   (3 rows)

Veuillez noter comment la clause AS renomme ici la colonne de sortie. (La clause AS est facultative.)

Une requête peut être "modifiée" avec la clause WHERE pour déclarer où la ligne est nécessaire. La clause WHERE contient une expression booléenne (valeur de vérité) et seules les lignes où la valeur de l'expression booléenne est true seront renvoyées. Les opérateurs booléens couramment utilisés (AND, OR et NOT) sont autorisés dans les conditions. Par exemple, la requête suivante récupère la météo à San Francisco un jour de pluie:

   SELECT * FROM weather
       WHERE city = 'San Francisco' AND prcp > 0.0;

résultat:

        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
   (1 row)

Vous pouvez exiger que les requêtes renvoyées soient triées:

   SELECT * FROM weather
       ORDER BY city;
        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    Hayward       |      37 |      54 |      | 1994-11-29
    San Francisco |      43 |      57 |    0 | 1994-11-29
    San Francisco |      46 |      50 | 0.25 | 1994-11-27

Dans cet exemple, l'ordre de tri n'est pas absolument clair, vous pouvez donc voir un tri aléatoire des données de ligne pour San Francisco. Mais si vous utilisez l'instruction suivante, vous obtiendrez toujours le résultat ci-dessus

   SELECT * FROM weather
       ORDER BY city, temp_lo;

Vous pouvez utiliser la commande suivante pour supprimer les lignes en double dans le résultat de la requête:

   SELECT DISTINCT city
       FROM weather;
        city
   ---------------
    Hayward
    San Francisco
    (2 rows)

Une fois de plus, l'ordre des lignes de résultats peut être modifié. Vous pouvez combiner DISTINCT et ORDER BY pour obtenir des résultats cohérents: [2]

   SELECT DISTINCT city
       FROM weather
       ORDER BY city;

[1] Bien que SELECT * soit utile pour les requêtes temporaires, nous pensons généralement que c'est un mauvais style dans le code de production, car l'ajout d'un champ à la table modifie le résultat.

[2] Dans certains systèmes de base de données, y compris les anciennes versions de PostgreSQL, l'exécution de DISTINCT triera les lignes, donc ORDER BY est redondant. Mais ce n'est pas une exigence de la norme SQL, et le PostgreSQL actuel ne garantit pas que DISTINCT provoquera le tri des lignes de données.

2.6. Connexion entre les tables

Jusqu'à présent, notre requête n'a accédé qu'à une seule table à la fois. La requête peut accéder à plusieurs tables à la fois ou accéder à une table d'une manière ou d'une autre tout en traitant encore plusieurs lignes de données dans la table. Nous appelons une requête qui accède à plusieurs lignes de données dans la même table ou dans des tables différentes en même temps qu'une requête de jointure. Par exemple, si vous souhaitez répertorier tous les enregistrements météorologiques et les coordonnées des villes liées à ces enregistrements. Pour atteindre cet objectif, nous devons comparer le champ de la ville de chaque ligne de la table météo avec le champ du nom de toutes les lignes de la table des villes et sélectionner les lignes qui correspondent à ces valeurs.

Remarque: il ne s'agit que d'un modèle conceptuel. Cette connexion est généralement effectuée de manière plus efficace que la comparaison réelle de chaque paire de lignes possible, mais celles-ci sont invisibles pour l'utilisateur.

Cette tâche peut être réalisée avec la requête suivante:

   SELECT *
       FROM weather, cities
       WHERE city = name;
         city      | temp_lo | temp_hi | prcp |    date    |     name      | location
   ---------------+---------+---------+------+------------+---------------+-----------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
    San Francisco |      43 |      57 |    0 | 1994-11-29 | San Francisco | (-194,53)
   (2 rows)

Observez deux aspects de l'ensemble de résultats:

Il n'y a pas de ligne de résultat pour la ville Hayward. En effet, il n'y a pas de ligne correspondante Hayward dans la table des villes, de sorte que la connexion ignore la ligne sans correspondance dans la table météo. Nous verrons comment résoudre ce problème plus tard.

Deux champs contiennent le nom de la ville. Ceci est correct car les champs des tables météo et villes sont réunis. Cependant, nous ne voulons pas de ceux-ci, donc vous voudrez probablement lister explicitement les champs de sortie au lieu d'utiliser *:

Exercice: Regardez la sémantique de l'omission de la clause WHERE.

Étant donné que chaque champ a un nom différent, l'analyseur trouvera automatiquement à quelle table ils appartiennent. S'il y a des noms de champs en double dans les deux tables, vous devez utiliser des noms de champs qualifiés pour indiquer celui que vous voulez. La requête est la suivante :

   SELECT weather.city, weather.temp_lo, weather.temp_hi,
          weather.prcp, weather.date, cities.location
       FROM weather, cities
       WHERE cities.name = weather.city;

Il est généralement considéré comme un bon style de limiter tous les noms de champ dans une requête de jointure, de sorte que même si un nom de colonne en double est ajouté ultérieurement à l'une des tables, la requête n'échouera pas.

Jusqu'à présent, ce type de requête de jointure peut également être écrit sous la forme suivante:

   SELECT *
       FROM weather INNER JOIN cities ON (weather.city = cities.name);

Cette grammaire n'est pas aussi couramment utilisée que celle ci-dessus, nous l'écrivons ici pour vous faciliter la compréhension des sujets qui suivent.

Nous allons maintenant voir comment récupérer les enregistrements Hayward. Ce que nous voulons que la requête fasse, c'est analyser la table météo et trouver les lignes correspondantes dans la table des villes pour chaque ligne. Si nous ne trouvons pas de ligne correspondante, nous avons besoin de "valeurs vides" pour remplacer les champs dans la table des villes. Ce type de requête est appelé une jointure externe. (Les connexions que nous avons vues auparavant sont toutes des connexions internes.) Une telle commande ressemble à ceci:

   SELECT *
       FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
        city      | temp_lo | temp_hi | prcp |    date    |     name      | location
   ---------------+---------+---------+------+------------+---------------+-----------
    Hayward       |      37 |      54 |      | 1994-11-29 |               |
    San Francisco |      46 |      50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
    San Francisco |      43 |      57 |    0 | 1994-11-29 | San Francisco | (-194,53)
   (3 rows)

Cette requête est une jointure externe gauche, car les lignes de la table sur le côté gauche de l'opérateur de jointure doivent apparaître au moins une fois dans la sortie, et les lignes sur le côté droit ne sortiront que celles correspondant à la ligne de gauche Lignes correspondantes. Si la ligne de sortie de la table de gauche ne correspond pas à la ligne de la table de droite correspondante, alors le champ de la ligne de droite sera rempli avec NULL.

Pratique; il y a de bonnes connexions et des connexions complètes. Essayez de découvrir ce qu'ils font.

Nous pouvons également connecter une table à nous-mêmes. C'est ce qu'on appelle l'auto-connexion. Par exemple, supposons que nous souhaitons rechercher des enregistrements météorologiques qui se situent dans la plage de températures d'autres enregistrements météorologiques. De cette façon, nous devons comparer les champs temp_lo et temp_hi de chaque ligne de la table météo avec les champs temp_lo et temp_hi des autres lignes de la table météo. Nous pouvons atteindre cet objectif avec la requête suivante:

   SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
       W2.city, W2.temp_lo AS low, W2.temp_hi AS high
       FROM weather W1, weather W2
       WHERE W1.temp_lo < W2.temp_lo
       AND W1.temp_hi > W2.temp_hi;
        city      | low | high |     city      | low | high
   ---------------+-----+------+---------------+-----+------
    San Francisco |  43 |   57 | San Francisco |  46 |   50
    Hayward       |  37 |   54 | San Francisco |  46 |   50
   (2 rows)

Ici, nous renommons la table météo en W1 et W2 pour distinguer les côtés gauche et droit de la connexion. Vous pouvez également utiliser ces alias pour enregistrer certaines frappes dans d'autres requêtes, telles que:

   SELECT *
       FROM weather w, cities c
       WHERE w.city = c.name;

Vous rencontrerez souvent de telles abréviations à l'avenir.

2.7. Fonctions d'agrégation

Comme la plupart des autres produits de base de données relationnelle, PostgreSQL prend en charge les fonctions d'agrégation. Une fonction d'agrégation calcule un résultat à partir de plusieurs lignes d'entrée. Par exemple, nous avons des fonctions d'agrégation qui calculent le nombre (nombre), la somme (somme), la moyenne (moyenne), le maximum (maximum) et le minimum (minimum) sur un ensemble de lignes.

Par exemple, nous pouvons utiliser l'instruction suivante pour trouver la température la plus élevée dans tous les enregistrements

   SELECT max(temp_lo) FROM weather;
    max
   -----
     46
   (1 row)

Si nous voulons savoir dans quelle ville la lecture a eu lieu, nous pouvons utiliser

SELECT ville FROM temps WHERE temp_lo = max (temp_lo); FAUX

Mais cette requête ne peut pas être exécutée car la fonction d'agrégation max ne peut pas être utilisée dans la clause WHERE. (Cette restriction existe car la clause WHERE détermine quelles lignes peuvent entrer dans la phase d'agrégation; par conséquent, elle doit être calculée avant que la fonction d'agrégation ne soit exécutée.) Cependant, nous pouvons généralement utiliser d'autres méthodes pour atteindre notre objectif; ici, nous pouvons utiliser des sous-requêtes:

   SELECT city FROM weather
       WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
        city
   ---------------
    San Francisco
   (1 row)

C'est correct, car la sous-requête est un calcul indépendant et elle calcule sa propre agrégation indépendamment de la requête externe.

L'agrégation est également couramment utilisée dans les clauses GROUP BY. Par exemple, nous pouvons obtenir la valeur la plus élevée de basse température dans chaque ville.

   SELECT city, max(temp_lo)
       FROM weather
       GROUP BY city;
        city      | max
   ---------------+-----
    Hayward       |  37
    San Francisco |  46
   (2 rows)

Cela nous donne une sortie pour chaque ville. Chaque résultat d'agrégation est calculé sur la ligne qui correspond à la ville. Nous pouvons filtrer ces groupes avec HAVING:

    SELECT city, max(temp_lo)
       FROM weather
       GROUP BY city
       HAVING max(temp_lo) < 40;
     city   | max
   ---------+-----
    Hayward |  37
   (1 row)

Cela ne donne que les villes où la valeur temp_lo avait une température inférieure à 40 degrés. Enfin, si nous ne nous soucions que des villes dont les noms commencent par "S", nous pouvons utiliser

   SELECT city, max(temp_lo)
       FROM weather
       WHERE city LIKE 'S%'(1)
       GROUP BY city
       HAVING max(temp_lo) < 40;

(1) LIKE effectue une correspondance de motifs, comme expliqué dans la section 9.7.

Il est très important pour nous de comprendre la relation entre l'agrégation et les clauses SQL WHERE et HAVING. La différence fondamentale entre WHERE et HAVING est la suivante: WHERE sélectionne les lignes d'entrée avant les calculs de regroupement et d'agrégation (par conséquent, il contrôle quelles lignes entrent dans le calcul d'agrégation), tandis que HAVING sélectionne les lignes groupées après le regroupement et l'agrégation. Par conséquent, la clause WHERE ne peut pas contenir de fonctions d'agrégation; il est inutile d'essayer d'utiliser des fonctions d'agrégation pour déterminer quelles lignes sont entrées pour les opérations d'agrégation. En revanche, la clause HAVING contient toujours des fonctions d'agrégation. (Strictement parlant, vous pouvez écrire une clause HAVING qui n'utilise pas l'agrégation, mais cela est rarement utile. Les mêmes conditions peuvent être utilisées plus efficacement dans la phase WHERE.)

Dans l'exemple précédent, nous pouvons appliquer la restriction de nom de ville dans WHERE car elle ne nécessite pas d'agrégation. C'est plus efficace que d'augmenter la limite dans HAVING, car nous évitons les calculs de regroupement et d'agrégation pour les lignes qui échouent à la vérification WHERE.

2.8. Mise à jour

Vous pouvez mettre à jour les lignes existantes avec la commande UPDATE. Supposons que vous constatiez que tous les comptages de température au 28 novembre sont inférieurs de deux degrés, vous pouvez alors mettre à jour les données de la manière suivante:

   UPDATE weather
       SET temp_hi = temp_hi - 2,  temp_lo = temp_lo - 2
       WHERE date > '1994-11-28';

Regardez le nouvel état des données:

   SELECT * FROM weather;
        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
    San Francisco |      41 |      55 |    0 | 1994-11-29
    Hayward       |      35 |      52 |      | 1994-11-29
   (3 rows)

2.9. Supprimer

Les lignes de données peuvent être supprimées de la table avec la commande DELETE. En supposant que vous n'êtes plus intéressé par la météo de Hayward, vous pouvez supprimer ces lignes du tableau de la manière suivante:

   DELETE FROM weather WHERE city = 'Hayward';所有属于Hayward的天气记录都将被删除。 
   SELECT * FROM weather;
        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
    San Francisco |      41 |      55 |    0 | 1994-11-29
   (2 rows)

Nous devons être prudents lorsque nous utilisons des déclarations de la forme suivante

   DELETE FROM tablename;

S'il n'y a pas de condition, DELETE supprimera toutes les lignes de la table spécifiée et l'effacera. Le système ne vous demandera pas de confirmation avant de faire cela!

Je suppose que tu aimes

Origine blog.csdn.net/qq_37061368/article/details/112978506
conseillé
Classement