Comprendre les Bases de Données : Une Exploration de PostgreSQL
Introduction aux Bases de Données
Lorsque j’ai commencé à travailler sur des applications côté serveur nécessitant la persistance des données, je ne comprenais pas vraiment l’importance des bases de données. Pourquoi sont-elles si essentielles ? Ne peut-on pas simplement enregistrer des données sur un disque et y accéder au besoin ? (Réponse : non.)
En m’immergeant dans des projets concrets plutôt que de simples expériences, j’ai réalisé que les bases de données sont en quelque sorte magiques, et que SQL est le langage qui permet d’exploiter cette magie. On pourrait facilement considérer les bases de données comme une boîte noire où il suffit de s’assurer que les tables sont correctement indexées et que les requêtes sont optimisées, et le reste se déroule sans effort.
Cependant, les bases de données ne sont pas aussi complexes qu’elles en ont l’air. Bien qu’elles présentent une certaine complexité, en explorant un peu le moteur de la base de données, on découvre qu’il s’agit principalement d’abstractions puissantes et intelligentes. Comme pour la plupart des logiciels, la complexité réside souvent dans les cas particuliers, notamment en ce qui concerne la concurrence.
Plongée dans PostgreSQL
Je vais examiner de plus près les moteurs de bases de données, en me concentrant sur PostgreSQL, qui est le système de gestion de bases de données le plus utilisé par les développeurs, selon les enquêtes de Stack Overflow de 2023 et 2024.
Installation de PostgreSQL
PostgreSQL stocke toutes ses données dans un répertoire nommé de manière appropriée : /var/lib/postgresql/data
. Pour explorer cela, nous allons créer une installation vide de PostgreSQL à l’aide de Docker et monter le répertoire de données dans un dossier local afin de voir ce qui s’y trouve. (N’hésitez pas à suivre ces étapes et à explorer les fichiers par vous-même !)
docker run --rm -v ./pg-data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=password postgres:16
Vous devriez voir une série de messages intéressants, tels que selecting dynamic shared memory implementation ... posix
et performing post-bootstrap initialization ... ok
, suivis de LOG: database system is ready to accept connections
. Une fois cela fait, arrêtez le serveur avec ctrl-C pour examiner les fichiers créés.
$ ls -l pg-data
Vous constaterez qu’il y a de nombreux dossiers, mais la plupart d’entre eux sont vides.
Terminologie Essentielle
Avant d’approfondir, voici un aperçu rapide de quelques termes clés :
Terme | Signification |
---|---|
Cluster de bases de données | Le terme « cluster » désigne ici une instance unique d’un serveur PostgreSQL exécutant plusieurs bases de données sur la même machine. |
Conclusion
En explorant les bases de données, en particulier PostgreSQL, nous découvrons un monde fascinant d’abstractions et de mécanismes qui, bien que complexes, sont accessibles à ceux qui prennent le temps de les comprendre. Les bases de données ne sont pas seulement des outils de stockage, mais des systèmes dynamiques qui permettent de gérer efficacement les données dans des applications modernes.
Comprendre la Structure et le Fonctionnement de PostgreSQL
Introduction à PostgreSQL
PostgreSQL est un système de gestion de bases de données relationnelles puissant et open-source. Il est largement utilisé pour sa robustesse et sa capacité à gérer des volumes de données importants. Cet article explore les concepts fondamentaux de PostgreSQL, y compris la connexion à la base de données, les transactions, et la structure des données.
Connexion à la Base de Données
Lorsqu’un client établit une connexion avec le serveur PostgreSQL, un processus secondaire est créé pour gérer cette connexion. Ce mécanisme permet de gérer efficacement les requêtes des utilisateurs tout en maintenant la performance du serveur.
Sessions de Base de Données
Une fois la connexion authentifiée, une session est établie. Cette session permet au client d’exécuter des requêtes SQL. Les sessions sont essentielles pour interagir avec la base de données et effectuer des opérations sur les données.
Transactions : Unité de Travail
Les requêtes SQL sont exécutées dans le cadre de transactions, qui représentent des unités de travail. Chaque transaction est traitée comme un tout : elle peut être validée (commit) ou annulée (rollback) en cas d’échec. Cela garantit l’intégrité des données, car toutes les modifications apportées dans une transaction sont soit entièrement appliquées, soit complètement annulées.
Instantanés de Transaction
Chaque transaction a sa propre vue de la base de données, connue sous le nom d’instantané. Dans un environnement où plusieurs sessions accèdent simultanément aux mêmes données, chaque session peut voir un instantané différent, ce qui permet d’éviter les conflits de lecture et d’écriture. Il est également possible de synchroniser et d’exporter ces instantanés.
Schémas et Organisation des Données
Une base de données est composée de plusieurs schémas, qui sont des espaces de noms logiques pour les tables, les fonctions et autres objets de la base de données. Le schéma par défaut est appelé « public ». Si aucun schéma n’est spécifié lors de la création d’une table, le schéma public est utilisé par défaut.
Tables et Espaces de Tables
Les bases de données contiennent plusieurs tables, chacune représentant une collection non ordonnée d’éléments avec un nombre défini de colonnes, chacune ayant un type spécifique. Un espace de tables, quant à lui, représente une séparation physique des données, contrairement aux schémas qui sont une séparation logique.
Lignes et Tuples
Une table est constituée de plusieurs lignes, chaque ligne étant une collection de points de données définissant un élément spécifique. Un tuple est similaire à une ligne, mais il est immuable. Il représente l’état d’une ligne à un moment donné et est un terme plus général pour désigner une collection de données.
Exploration des Dossiers et Fichiers de PostgreSQL
Il est intéressant de comprendre la structure des fichiers et des dossiers dans PostgreSQL, même si tous ne sont pas nécessaires pour une utilisation de base. Voici un aperçu des principaux répertoires :
Répertoire de Base
Le répertoire de base contient un sous-répertoire pour chaque base de données, où sont stockés les fichiers de données.
Fichiers Globaux
Le dossier global contient des fichiers pour des tables accessibles à l’ensemble du cluster, comme pg_database
.
Timestamps de Transactions
Le répertoire pg_commit_ts
stocke les horodatages des validations de transactions, bien qu’il soit vide si aucune transaction n’a encore été effectuée.
Mémoire Partagée Dynamique
PostgreSQL utilise un sous-système de mémoire partagée dynamique pour permettre le partage de mémoire entre plusieurs processus. Les fichiers d’objets de mémoire partagée sont stockés dans le dossier pg_dynshmem
.
Configuration de l’Authentification
Le fichier pg_hba.conf
permet de configurer l’accès au cluster en fonction du nom d’hôte. Par exemple, la configuration par défaut permet aux connexions locales sans mot de passe.
Décodage Logique
Le dossier pg_logical
contient des données de statut pour le décodage logique, un processus qui permet de récupérer l’état attendu de la base de données à partir du journal des écritures.
Réplication
La réplication est essentielle pour la synchronisation des données entre plusieurs instances de serveur. Le dossier pg_replslot
contient des données pour les différents slots de réplication, garantissant que les entrées du journal des écritures sont conservées pour des répliques spécifiques.
Transactions Sérialisables
Le dossier pg_serial
contient des informations sur les transactions sérialisables, qui représentent le niveau le plus strict d’isolation des transactions.
Instantanés Exportés
Le répertoire pg_snapshots
contient des instantanés exportés, utilisés par des outils comme pg_dump
pour sauvegarder les données.
Conclusion
Comprendre la structure et le fonctionnement de PostgreSQL est essentiel pour tirer le meilleur parti de ce système de gestion de bases de données. En maîtrisant les concepts de connexion, de transactions et d’organisation des données, les utilisateurs peuvent gérer efficacement leurs bases de données et garantir l’intégrité des données.
Comprendre la Structure des Dossiers de PostgreSQL
Lorsqu’on explore PostgreSQL, il est essentiel de se familiariser avec la structure des dossiers qui composent cette base de données. Chaque dossier joue un rôle spécifique dans le fonctionnement et la gestion des données. Voici un aperçu des principaux dossiers que vous rencontrerez.
Dossiers de Statistiques
Le dossier pg_stat/
est crucial, car il contient des fichiers de statistiques permanents. PostgreSQL utilise ces statistiques pour optimiser les plans de requêtes. Par exemple, si le planificateur de requêtes doit effectuer un scan séquentiel sur une table, il peut estimer le nombre de lignes présentes pour déterminer la mémoire à allouer. Une bonne compréhension de ces statistiques est indispensable pour analyser et améliorer les performances des requêtes.
En revanche, le dossier pg_stat_tmp/
contient des fichiers temporaires relatifs aux statistiques, contrairement à pg_stat/
qui conserve des fichiers permanents.
Transactions et Sous-Transactions
Le dossier pg_subtrans/
est dédié aux sous-transactions, qui permettent de diviser une transaction unique en plusieurs sous-transactions. Ce dossier stocke les données d’état de ces sous-transactions.
Espaces de Table
Le dossier pg_tblspc/
contient des références symboliques vers différents espaces de table. Un espace de table est un emplacement physique utilisé pour stocker certains objets de la base de données, configuré par l’administrateur de la base de données. Par exemple, un index fréquemment utilisé peut être placé sur un disque SSD rapide, tandis que le reste de la table peut être stocké sur un disque moins coûteux et plus lent.
Transactions Préparées
Le dossier pg_twophase/
est utilisé pour les transactions préparées, permettant de dissocier une transaction de la session actuelle et de la stocker sur le disque. Cela est particulièrement utile pour les engagements en deux phases, garantissant que les modifications sont soit toutes validées, soit toutes annulées.
Configuration du Serveur
Le fichier postgresql.auto.conf
contient des paramètres de configuration du serveur, automatiquement mis à jour par les commandes alter system
. En revanche, postgresql.conf
regroupe tous les paramètres configurables pour une instance PostgreSQL, allant de autovacuum_naptime
à zero_damaged_pages
. Pour une compréhension approfondie de ces paramètres, il est conseillé de consulter des ressources spécialisées.
Exploration des Dossiers de Base de Données
Le dossier base/
contient un sous-dossier pour chaque base de données de votre cluster. À la création d’un nouveau serveur PostgreSQL, trois bases de données sont automatiquement générées :
postgres
– Cette base de données par défaut permet de se connecter au serveur et de gérer d’autres bases de données.template0
ettemplate1
– Ces bases servent de modèles pour la création de nouvelles bases de données.
Les sous-dossiers sont identifiés par des numéros, correspondant aux Identifiants d’Objet (OID) des bases de données, comme 1
pour postgres
, 4
pour template0
, et 5
pour template1
.
Création et Manipulation de Données
Les bases de données par défaut étant vides, il est intéressant de créer une nouvelle base de données pour explorer les fichiers de données. Pour cela, nous allons exécuter un conteneur PostgreSQL :
Nous pouvons utiliser n’importe quel ensemble de données pour nos expérimentations.
Création d’une Base de Données de Pays avec PostgreSQL
Introduction à la Gestion des Données Géographiques
Dans cet article, nous allons explorer comment télécharger des données sur les pays et les intégrer dans une base de données PostgreSQL. Ce processus est essentiel pour quiconque souhaite gérer des informations géographiques de manière efficace.
Téléchargement des Données des Pays
Pour commencer, nous allons récupérer des données sur les pays à partir d’une source en ligne. Nous utiliserons la commande curl
pour télécharger un fichier CSV contenant ces informations.
curl 'https://raw.githubusercontent.com/lukes/ISO-3166-Countries-with-Regional-Codes/master/all/all.csv' --output ./pg-data/countries.csv
Cette commande télécharge le fichier CSV et le sauvegarde dans le répertoire spécifié.
Accès à la Base de Données
Pour examiner notre base de données, nous pouvons utiliser des outils locaux comme psql
ou TablePlus
. Cependant, pour simplifier le processus, nous allons accéder directement à notre conteneur Docker exécutant PostgreSQL.
pg_container_id=$(docker ps --filter expose=5432 --format "{{.ID}}")
docker exec -it $pg_container_id psql -U postgres
Ici, nous récupérons l’ID du conteneur PostgreSQL en filtrant par le port exposé, puis nous exécutons une commande pour ouvrir un shell interactif psql
.
Création de la Base de Données
Une fois que nous avons accès à psql
, nous pouvons créer notre nouvelle base de données et y importer les données des pays.
create database blogdb;
c blogdb;
create table countries (
id integer primary key generated always as identity,
name text not null unique,
alpha_2 char(2) not null,
alpha_3 char(3) not null,
numeric_3 char(3) not null,
iso_3166_2 text not null,
region text,
sub_region text,
intermediate_region text,
region_code char(3),
sub_region_code char(3),
intermediate_region_code char(3)
);
Cette série de commandes crée une base de données nommée blogdb
et une table countries
avec des colonnes pour stocker diverses informations sur chaque pays.
Importation des Données
Pour charger les données dans notre table, nous utiliserons la commande COPY
qui permet d’importer des données à partir d’un fichier CSV.
copy countries (name, alpha_2, alpha_3, numeric_3, iso_3166_2, region, sub_region, intermediate_region, region_code, sub_region_code, intermediate_region_code) from './pg-data/countries.csv' with (format csv, header);
Cette commande importe les données du fichier CSV dans la table countries
, en tenant compte des en-têtes du fichier.
Conclusion
En suivant ces étapes, vous pouvez facilement créer une base de données PostgreSQL pour gérer des informations sur les pays. Ce processus est non seulement utile pour les développeurs, mais également pour les chercheurs et les analystes de données qui ont besoin d’accéder à des données géographiques précises.
Exploration des Fichiers de Base de Données
Nous avons réussi à créer une table contenant 249 enregistrements, avec un index unique associé à la colonne name
.
Vérification des Fichiers
Jetons un coup d’œil à notre dossier base/
:
Il est évident que notre base de données blogdb
a pour identifiant 16388
. Si vous travaillez avec plusieurs bases de données sur le même cluster, il se peut que vous ne connaissiez pas ce numéro. Si vous suivez cet exemple chez vous, le numéro pourrait être différent. Pour le découvrir, exécutez la commande suivante :
Examinons maintenant le contenu de ce dossier :
Exploration des Fichiers dans une Base de Données
Une Surprenante Abondance de Fichiers
Il est étonnant de constater qu’il existe un nombre considérable de fichiers, même si nous n’avons que 249 lignes. Qu’est-ce qui se passe réellement ?
Utilisation des Catalogues Systèmes
Pour mieux comprendre cette situation, nous pouvons nous appuyer sur plusieurs catalogues systèmes utiles :
Identification de l’Espace de Noms
Tout d’abord, il est essentiel de déterminer l’OID de l’espace de noms ‘public’ dans lequel se trouve notre table. Pour cela, il est nécessaire d’exécuter la commande dans la base de données ‘blogdb’, sinon vous obtiendrez l’OID de l’espace de noms ‘public’ de la base de données à laquelle vous êtes actuellement connecté.
SELECT to_regnamespace('public')::oid;
Cette commande renverra l’OID correspondant, qui est crucial pour les étapes suivantes.
Listing des Tables et Index
Ensuite, nous allons lister toutes les tables, index, et autres objets qui résident dans cet espace de noms. Voici la commande à exécuter :
SELECT * FROM pg_class WHERE relnamespace = to_regnamespace('public')::oid;
Cette requête nous fournira une vue d’ensemble des objets présents dans l’espace de noms ‘public’, incluant des informations telles que le nom de la relation, le type, le propriétaire, et bien d’autres attributs.
Analyse des Résultats
Les résultats de cette requête peuvent révéler des détails intéressants sur la structure de la base de données. Par exemple, vous pourriez découvrir des séquences, des tables, et des index qui sont tous essentiels pour le bon fonctionnement de votre base de données.
Conclusion
bien que le nombre de lignes puisse sembler limité, la richesse des fichiers et des objets dans une base de données peut être surprenante. En utilisant les catalogues systèmes, nous pouvons obtenir une compréhension approfondie de la structure et des composants de notre base de données, ce qui est essentiel pour une gestion efficace et une optimisation des performances.
Dans cette analyse, nous constatons que nous avons en réalité seulement quatre objets de type table ; le reste des fichiers dans ce dossier est constitué de modèles standards. Si vous examinez les dossiers de la base de données tels que template0
, template1
ou postgres
(c’est-à-dire 1/
, 2/
ou 5/
), vous remarquerez que presque tous les fichiers sont identiques à ceux de notre base de données blogdb
.
Alors, que sont ces objets pg_class
et quel est leur lien avec tous ces fichiers ?
Nous pouvons identifier que countries
est présent avec des valeurs oid et relfilenode de 16390, ce qui correspond à notre table réelle. De plus, il y a countries_pkey
avec des valeurs oid et relfilenode de 16395, qui représente l’index de notre clé primaire. Enfin, nous avons countries_name_key
avec 16397, qui est l’index pour notre nom unique.
La contrainte ici est que countries_id_seq
a une valeur de 16389, ce qui correspond à la séquence utilisée pour générer de nouveaux identifiants (nous utilisons primary key generated always as identity
, qui, tout comme serial
, produit de nouvelles valeurs dans une séquence numérique croissante).
Le relfilenode fait référence au « filenode » de l’objet, qui représente le nom du fichier sur le disque. Commençons par examiner notre table countries
.
Pour un objet général, vous êtes susceptible de voir trois fichiers ou plus : 3
{filenode}
– Postgres divise les grands objets en plusieurs fichiers appelés segments, afin d’éviter des problèmes que certains systèmes d’exploitation rencontrent avec les fichiers volumineux (principalement pour des raisons historiques). Par défaut, ces fichiers mesurent 1 Go, bien que cela soit configurable. C’est le premier fichier de segment.{filenode}.1
,{filenode}.2
– ce sont les fichiers de segment suivants. Nous n’avons pas encore plus de 1 Go de données, donc nous n’avons pas ces fichiers.{filenode}_fsm
– il s’agit du fichier de la carte d’espace libre (FSM) pour l’objet, qui contient un arbre binaire indiquant combien d’espace libre est disponible dans chaque page du tas. Ne vous inquiétez pas, nous allons expliquer exactement ce qu’est le tas et les pages dans un instant.{filenode}_vm
– c’est le fichier de la carte de visibilité (VM) pour l’objet, qui vous informe sur la visibilité des tuples dans vos pages. Nous aborderons cela plus en détail plus tard.
Qu’est-ce que le tas ?
Tous ces fichiers de données principaux (à l’exception des fichiers FSM et VM) sont appelés le tas.
Un aspect crucial des tables qui n’est pas évident au premier abord est que, même si elles peuvent avoir des clés primaires séquentielles, les tables ne sont pas ordonnées. (C’est pourquoi nous avons besoin d’un objet de séquence distinct pour produire les valeurs d’identifiant séquentielles.) Pour cette raison, les tables sont parfois appelées un sac de lignes. Postgres les désigne comme un tas. Pour toute table réelle qui est ajoutée, mise à jour et nettoyée, les lignes dans le tas ne seront pas dans l’ordre séquentiel de leur clé primaire.
Il est important de noter que le tas dans Postgres est très différent du tas en mémoire système (par opposition à la pile). Ce sont des concepts liés et si vous êtes familier avec la structure de la pile par rapport au tas en mémoire, vous pourriez trouver le diagramme de page dans la section suivante très familier, mais il est essentiel de se rappeler qu’il s’agit de concepts très distincts.
Le tas d’objet se compose de nombreuses pages différentes (également appelées blocs) stockées séquentiellement dans le fichier.
Alors, qu’est-ce qu’une page ?
Dans un fichier de segment unique, vous trouverez plusieurs pages de taille fixe assemblées. Par défaut, une page mesure 8 Ko, donc nous nous attendrions à ce que tous nos fichiers d’objet soient des multiples de 8 Ko. Dans ce cas, notre fichier de table fait 32 Ko, ce qui signifie qu’il doit contenir 4 pages.
Vous vous demandez peut-être – pourquoi utiliser des pages ? Pourquoi ne pas avoir une seule page par segment ? La réponse est que chaque page est écrite en une seule opération atomique et plus la taille de la page est grande, plus il y a de chances qu’il y ait un échec d’écriture pendant l’opération. Plus la taille de la page est élevée, plus la base de données sera performante, mais plus la probabilité d’échecs d’écriture sera élevée. Les responsables de Postgres ont choisi 8 Ko comme valeur par défaut, et ils savent ce qu’ils font, donc il n’y a généralement pas de raison de modifier cela.
Ce diagramme montre la structure d’une page et comment elle se rapporte au segment et à l’objet entier.
Dans notre exemple, notre table principale fait 2,7 GiB, ce qui nécessite 3 segments distincts de 1 GiB chacun. Cela représente 131 072 pages de 8 KiB dans 1 GiB, chaque page contenant environ 40 éléments (en supposant que chaque élément occupe environ 200 octets).
Mise en page des pages
Examinons de plus près la mise en page de notre page.
Vous pouvez voir qu’il y a trois zones dans la page :
- Les en-têtes et pointeurs de ligne, qui croissent « vers le haut », ce qui signifie que le pointeur de ligne n + 1 a un décalage initial plus élevé dans la page que le pointeur de ligne n – la fin du dernier pointeur de ligne est appelée « inférieur ».
- Les données spéciales et les éléments qui croissent « vers le bas », ce qui signifie que l’élément n + 1 a un décalage initial plus bas dans la page que l’élément n – la fin du dernier élément est appelée « supérieur ».
- L’espace libre, qui se trouve entre le dernier pointeur de ligne et le dernier élément, c’est-à-dire qui va de « inférieur » à « supérieur » – vous pouvez calculer l’espace libre restant dans la page en faisant « supérieur » – « inférieur ».
L’en-tête de la page contient des informations telles que :
- Un contrôle de somme de la page
- Le décalage vers la fin des pointeurs de ligne (a.k.a. « inférieur »)
- Le décalage vers la fin de l’espace libre (c’est-à-dire vers le début des éléments, a.k.a. « supérieur »)
- Le décalage vers le début de l’espace spécial
- Des informations de version
Il existe en fait une extension intégrée appelée pageinspect
que nous pouvons utiliser pour examiner les informations de l’en-tête de notre page :
1
blogdb=# create extension pageinspect;
2
CREATE EXTENSION
3
4
blogdb=# select * from page_header(get_raw_page('countAnalyse des Pages de Base de Données : Comprendre l'Espace Libre
Introduction à l'Espace Libre dans les Pages
Lors de l'examen des pages d'une base de données, un aspect crucial à considérer est l'espace libre disponible. Cet espace peut avoir un impact significatif sur la performance et l'efficacité des opérations de la base de données. Dans cet article, nous allons explorer les valeurs d'espace libre dans différentes pages et ce qu'elles révèlent sur la structure des données.
Détails des Pages et de l'Espace Libre
En analysant les pages, nous remarquons que la valeur de special
est identique à celle de pagesize
, ce qui indique qu'il n'existe pas de section de données spéciale pour cette page. Cette section est généralement réservée à d'autres types de pages, comme les index, où elle stocke des informations sur la structure de l'arbre binaire.
Comparaison des Valeurs d'Espace Libre
En examinant les valeurs lower
et upper
pour chaque page, nous pouvons tirer des conclusions sur l'espace libre :
- Page 0 : 376 - 292 = 84 octets d'espace libre
- Page 1 : 408 - 308 = 100 octets d'espace libre
- Page 2 : 416 - 296 = 120 octets d'espace libre
- Page 3 : 3288 - 196 = 3092 octets d'espace libre
Interprétation des Résultats
Ces résultats nous permettent de faire certaines déductions :
- La taille moyenne des lignes dans notre table des pays est d'environ 100 octets, ce qui correspond à l'espace libre disponible dans les pages complètes.
- L'espace libre dans la page 3 est particulièrement élevé, ce qui pourrait indiquer une faible utilisation de cette page ou une possibilité d'optimisation pour des insertions futures.
Conclusion
L'analyse de l'espace libre dans les pages d'une base de données est essentielle pour comprendre la structure et l'efficacité des données. En surveillant ces valeurs, les administrateurs de bases de données peuvent mieux gérer l'espace et optimiser les performances. Une gestion proactive de l'espace libre peut également aider à anticiper les besoins futurs en matière de stockage et à améliorer la réactivité des systèmes de gestion de bases de données.
Analyse des Données de Pages dans une Base de Données
Introduction à l'Inspection des Pages
L'examen des pages d'une base de données est essentiel pour comprendre la structure et l'efficacité des données stockées. En utilisant des fonctions spécifiques, nous pouvons obtenir des informations précieuses sur la taille des lignes et la disposition des données.
Vérification de la Taille des Lignes
Pour confirmer la taille des lignes dans une page de données, nous pouvons utiliser la fonction heap_page_items()
fournie par l'extension pageinspect
. Cette fonction permet d'extraire des informations détaillées sur les éléments présents dans une page spécifique d'une table.
Exemple de Requête SQL
Voici un exemple de requête SQL qui illustre comment utiliser cette fonction :
SELECT lp, lp_off, lp_len, t_ctid, t_data
FROM heap_page_items(get_raw_page('countries', 1))
LIMIT 10;
Cette requête extrait les colonnes suivantes :
lp
: le numéro de ligne
lp_off
: l'offset de la ligne
lp_len
: la longueur de la ligne
t_ctid
: l'identifiant de la ligne
t_data
: les données de la ligne
Résultats de la Requête
Les résultats de cette requête peuvent ressembler à ceci :
lp
lp_off
lp_len
t_ctid
t_data
1
8064
123
(1,1)
x440000002545...
2
7944
114
(1,2)
x450000001145...
3
7840
97
(1,3)
x460000001145...
4
7720
116
(1,4)
x470000001345...
5
7600
115
(1,5)
x480000001345...
6
7448
148
(1,6)
x490000003946...
7
7344
103
(1,7)
x4a0000001d46...
8
7248
89
(1,8)
x4b0000000b46...
9
7144
97
(1,9)
...
Ces données fournissent un aperçu de la manière dont les informations sont organisées dans la page de la table countries
.
Conclusion
L'utilisation de la fonction heap_page_items()
est un moyen efficace d'analyser la structure des données dans une base de données. En comprenant la taille et la disposition des lignes, les administrateurs de bases de données peuvent optimiser les performances et la gestion des données.
Comprendre les Détails des Données dans PostgreSQL
Introduction aux Identifiants de Tuple
Dans PostgreSQL, chaque élément de données est associé à un identifiant unique, connu sous le nom de ctid (Current Tuple ID). Ce dernier permet de localiser précisément un élément dans la base de données, en utilisant un format spécifique qui indique la page et l'index de l'élément au sein de cette page. Par exemple, un ctid de (1, 1) désigne le premier élément de la première page, bien que les pages soient indexées à partir de zéro.
Exploration des Données Stockées
Il est fascinant de constater que l'on peut accéder aux données brutes stockées dans PostgreSQL. Ces données sont représentées sous forme de chaînes hexadécimales, qui correspondent exactement aux octets enregistrés sur le disque. Pour illustrer cela, nous pouvons utiliser un script Python afin d'extraire et de visualiser ces données.
Extraction des Données avec Python
Voici un exemple de commande pour récupérer les données d'une table spécifique, en l'occurrence "countries", à partir de la première page :
row_data=$(docker exec $pg_container_id psql -U postgres blogdb --tuples-only -c "select t_data from heap_page_items(get_raw_page('countries', 1)) limit 1;")
Ensuite, nous pouvons convertir cette chaîne hexadécimale en un format lisible :
python3 -c "print(bytearray.fromhex(r'$row_data'.strip().replace('x', '')).decode('utf-8', errors='ignore'))" > row_data.bin
Visualisation des Données
Pour visualiser le contenu extrait, nous pouvons utiliser la commande suivante :
cat row_data.bin
Cela nous permet de voir les données sous une forme plus compréhensible, par exemple :
D%Guinée équatorialeGQ GNQ 226 ISO 3166-2:GQ Afrique 'Afrique subsaharienne' Afrique centrale
Conclusion
L'exploration des données dans PostgreSQL offre une perspective fascinante sur la manière dont les informations sont stockées et récupérées. Grâce à des outils comme Python et des commandes simples, il est possible d'accéder à des données brutes et de les interpréter, ce qui peut s'avérer extrêmement utile pour les développeurs et les analystes de données.
Exploration des Données de la Guinée Équatoriale
Introduction à la Guinée Équatoriale
La Guinée Équatoriale, un petit pays situé en Afrique centrale, est souvent méconnue. Avec une population d'environ 1,4 million d'habitants, elle se distingue par sa diversité culturelle et ses ressources naturelles abondantes, notamment le pétrole et le gaz. Ce pays insulaire, composé de plusieurs îles et d'une partie continentale, est un exemple fascinant de l'interaction entre l'environnement et le développement économique.
Données Démographiques et Géographiques
La Guinée Équatoriale est divisée en plusieurs régions, chacune ayant ses propres caractéristiques géographiques et culturelles. Le pays est principalement composé de deux grandes îles, Bioko et Annobón, ainsi que d'une partie continentale. En termes de classification régionale, la Guinée Équatoriale fait partie de l'Afrique subsaharienne, plus précisément de l'Afrique centrale.
Ressources Naturelles et Économie
L'économie de la Guinée Équatoriale repose largement sur l'exploitation de ses ressources naturelles. En effet, le pays est l'un des plus grands producteurs de pétrole d'Afrique, ce qui a considérablement influencé son développement économique. Selon les dernières statistiques, le secteur pétrolier représente environ 90 % des exportations du pays. Cependant, cette dépendance à l'égard des hydrocarbures pose des défis en matière de diversification économique.
Culture et Société
La culture de la Guinée Équatoriale est un mélange riche d'influences africaines et espagnoles, reflet de son histoire coloniale. Les langues officielles sont l'espagnol, le français et le portugais, ce qui témoigne de cette diversité. Les traditions locales, telles que la musique et la danse, jouent un rôle essentiel dans la vie quotidienne des habitants.
Défis Sociaux et Environnementaux
Malgré ses richesses, la Guinée Équatoriale fait face à des défis importants, notamment en matière de gouvernance et de droits de l'homme. Les inégalités économiques sont marquées, et une grande partie de la population vit dans la pauvreté. De plus, la déforestation et la dégradation de l'environnement sont des préoccupations croissantes, exacerbées par l'exploitation des ressources naturelles.
Conclusion
La Guinée Équatoriale est un pays aux multiples facettes, riche en ressources et en culture, mais confronté à des défis significatifs. Pour assurer un avenir durable, il est crucial que le pays diversifie son économie et améliore les conditions de vie de sa population. En mettant l'accent sur la durabilité et l'inclusion sociale, la Guinée Équatoriale peut aspirer à un développement équilibré et prospère.
0x 44 00 00 00
équivaut à 68
(doit être en little endian), donc les quatre premiers octets représentent l'ID de la ligne.
- Ensuite, il y a un octet aléatoire comme
0x25
ou 0x07
, suivi des données des colonnes – le reste des colonnes étant de type chaîne, elles sont toutes stockées en UTF-8. Si vous avez des informations sur la signification de ces octets inter-colonnes, n'hésitez pas à laisser un commentaire ! Je n'ai pas réussi à le déterminer.
Nous n'avons pas encore abordé le sujet de TOAST – ce sera un thème pour un prochain article 🍞.
Que se passe-t-il lorsqu'une ligne est modifiée ou supprimée ?
Postgres utilise le MVCC (Contrôle de Concurrence Multi-Version) pour gérer l'accès simultané aux données. Le terme "multi-version" signifie que lorsqu'une transaction modifie une ligne, elle ne touche pas du tout le tuple existant sur le disque. Au lieu de cela, elle crée un nouveau tuple à la fin de la dernière page avec la ligne modifiée. Lorsqu'elle valide la mise à jour, elle remplace la version des données que la nouvelle transaction verra, passant de l'ancien tuple au nouveau.
Illustrons cela avec un exemple :
Nous pouvons constater qu'après la mise à jour de la ligne, son ctid change de (0,9)
à (3,44)
(probablement à la fin de la dernière page). Les anciennes données et le ctid sont également supprimés de l'emplacement de l'ancien élément.
Qu'en est-il des suppressions ? Examinons cela :
Shares: