<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
  <title>Data Bene - Tag: 'Logiciel libre'</title>
  <subtitle>Base de données relationnelles, open-source et adaptives.</subtitle>
  <link href="https://www.data-bene.io/fr/blog/tags/logiciel-libre.xml" rel="self" type="application/atom+xml" />
  <updated>2026-01-03T00:00:00Z</updated>
  <id>https://www.data-bene.io/fr/blog/tags/logiciel-libre.xml</id>
    <entry>
      <title>Open Source Experience 2025</title>
      <link href="https://www.data-bene.io/fr/blog/open-source-experience-2025/" />
      <updated>2026-01-03T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/open-source-experience-2025/</id>
     <content type="html"><![CDATA[ <p>L’édition 2025 de l’<a href="https://www.opensource-experience.com/" rel="noopener">Open Source Experience (OSXP)</a> s’est tenue les 10 et 11 décembre sous le thème « Open Source, clé de l’autonomie stratégique de l’Europe ». L’accent portait, comme vous l’imaginez, entièrement sur la redéfinition de l’avenir numérique européen comme étant mené par les innovations open source à travers toutes les technologies (incluant la gestion des données, le cloud et la cybersécurité). Cette année, de nombreuses conférences se sont largement concentrées sur l’intersection entre l’open source et les technologies d’IA (en accord avec l’accent que l’industrie technologique a mis sur l’IA en général, en 2025).</p>
<h2 id="levenement"><a class="heading-anchor" href="#levenement">L’événement</a></h2>
<p>L’événement a duré 2 jours avec 90 exposants, 130 sessions, 150 intervenants et plus de 4 000 participants - une conférence de très grande envergure, située à la Cité des Sciences et de l’Industrie à Paris.</p>
<p>Ce lieu particulier était plus petit que celui de l’année dernière (Le Palais des Congrès) et les salles dans lesquelles nous sommes allés étaient toutes pleines en raison de leur petite taille (environ 20 ou 30 places tout au plus).</p>
<h2 id="le-format-des-conferences"><a class="heading-anchor" href="#le-format-des-conferences">Le format des conférences</a></h2>
<p>Les présentations ont été données en anglais et en français. Fait intéressant, il n’y avait pas de “salles silencieuses” cette année (où des écouteurs sont fournis à chaque participant). Tout le monde n’a pas apprécié ce format l’année dernière, mais c’était utile pour suivre deux conférences, ou basculer entre elles en fonction du contenu ou des questions.</p>
<p>Deux membres de notre équipe étaient présents et ont pu découvrir divers exposants et salles dédiées aux conférences répartis sur trois étages. Ces dernières duraient 20 minutes et bien que trop courtes pour entrer dans les détails, ce format était intéressant pour découvrir les nouvelles technologies et attiser notre curiosité d’un coup d’œil.</p>
<h2 id="le-contenu-des-conferences"><a class="heading-anchor" href="#le-contenu-des-conferences">Le contenu des conférences</a></h2>
<p>Il y avait six pistes dans lesquelles les conférences étaient catégorisées :</p>
<ul class="list">
<li>Modèles économiques et gouvernance pour des stratégies ouvertes durables</li>
<li>Intelligence artificielle et calcul scientifique pour l’analyse des données</li>
<li>Architecture cloud et virtualisation pour un avenir autonome</li>
<li>Développement - l’innovation logicielle en action</li>
<li>Cybersécurité et chaîne de production logicielle : l’Open Source comme fondement de confiance</li>
<li>Outils collaboratifs et applications métier : reprendre l’autonomie numérique</li>
</ul>
<p>Nous avons trouvé le sujet des solutions open source dans le secteur public le plus intéressant. En particulier, il était facile de voir que notre dépendance en tant que société mondiale aux cinq grandes entreprises technologiques (GAFAM : Google, Apple, Facebook, Amazon et Microsoft) a considérablement augmenté ces dernières années. Les logiciels open source sont une solution directe pour protéger notre droit collectif à la vie privée à l’ère numérique, ce qui explique exactement pourquoi des conférences comme celle-ci sont si importantes pour la découverte d’alternatives OSS et l’innovation qui conduit à un développement ultérieur dans ce secteur.</p>
<h2 id="la-participation"><a class="heading-anchor" href="#la-participation">La participation</a></h2>
<p>La fréquentation a été particulièrement importante dès le premier jour. Nous avons été ravis d’avoir l’occasion d’échanger en “présentiel”, et de rencontrer nos partenaires, en particulier <a href="https://www.ow2.org/" rel="noopener">OW2</a> qui organise également un évènement Open Source, annuel, en Juin. (L’appel à conférence est ouvert jusqu’au 14 février 2026 - consultez l’appel à propositions d’OW2Con’26 <a href="https://www.ow2con.org/view/2026/Call_For_Presentations" rel="noopener">ici</a>.)</p>
<p>L’évènement étant entièrement sur les technologies open source, nous avons pu discuter avec les nombreux participants de sujets tels que le support PostgreSQL, les difficultés et impacts organisationnel pour les entreprises souhaitant innover et adopter PostgreSQL, avec en trame de fond la demande du marché pour se libérer des contraintes de licence des éditeurs logiciels.</p>
<p>Nous avons également eu le plaisir de rencontrer des acteurs de l’innovation “hardware” open-source, en résonnance avec notre propre R&amp;D sur les processeurs RISC-V.</p>
<p>De nombreux projets libres et open source étaient représentés. Quelques exemples incluent <a href="https://nextcloud.com" rel="noopener">Nextcloud</a> (une plateforme de collaboration cloud auto-hébergée que nous utilisons personnellement pour l’hébergement ici chez Data Bene), qui est une alternative à Nextcloud), et <a href="https://opentalk.eu/en" rel="noopener">OpenTalk</a>, une solution de visioconférence conforme au RGPD, opérant dans des centres de données allemands.</p>
<h2 id="en-conclusion"><a class="heading-anchor" href="#en-conclusion">En conclusion</a></h2>
<p>L’événement était réussi et bien organisé. La seule chose qui aurait amélioré l’expérience aurait été des présentations plus longues pour explorer les divers sujets abordés plus en profondeur. Si vous souhaitez découvrir de nouveaux projets open source, notez que l’événement est également une très bonne opportunité pour échanger en toute liberté sur ces sujets.</p>
<p>Les rediffusions vidéo pour 2025 n’ont pas encore été publiées, mais les enregistrements des conférences passées peuvent être trouvés sur le <a href="https://www.opensource-experience.com/en/video-replays" rel="noopener">site officiel, ici</a>.</p>
<p>Dans l’ensemble, nous avons beaucoup apprécié l’événement et espérons y assister l’année prochaine !</p>
 ]]></content>
			<author>
				<name>Grégory Tiram</name>
			</author>
    </entry>
    <entry>
      <title>Transitionnez facilement vers PostgreSQL depuis Oracle</title>
      <link href="https://www.data-bene.io/fr/blog/transitionnez-facilement-vers-postgresql-depuis-oracle/" />
      <updated>2025-12-10T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/transitionnez-facilement-vers-postgresql-depuis-oracle/</id>
     <content type="html"><![CDATA[ <p>Si vous avez besoin de transition rapidement d’Oracle vers PostgreSQL, sans vous préoccuper des conversions de types ou autres packages Oracle qui nécessitent des modifications pour être compatible PostgreSQL, une solution utile est IvorySQL !</p>
<h2 id="introduction"><a class="heading-anchor" href="#introduction">Introduction</a></h2>
<p>De plus en plus d’entreprises cherchent à se libérer des coûts et des contraintes d’Oracle en migrant vers PostgreSQL. Mais comment réussir cette transition sans y passer des mois ? Voici une méthode éprouvée, rapide et sécurisée, basée sur des retours d’expérience et des outils open source.</p>
<h3 id="commencer-par-evaluer-et-cartographier"><a class="heading-anchor" href="#commencer-par-evaluer-et-cartographier">Commencer par évaluer et cartographier</a></h3>
<p>Avant de migrer, il est essentiel de faire l’état des lieux : lister les objets Oracle par une extraction complète (tables, vues, séquences, procédures, fonctions, packages).</p>
<p>Mais aussi avoir des échanges réguliers avec le client pour affiner les constats et valider les orientations, mais aussi d’identifier les dépendances (applications connectées avec quelle technologie, jobs, interfaces,…)</p>
<p>Et enfin, repérer les spécificités Oracle du client (fonctions spécifiques comme ROWID, DUAL, DBMS_XXX,…) et tout autre mot-clé demandant une attention particulière.</p>
<h3 id="choisir-les-bons-outils-open-source"><a class="heading-anchor" href="#choisir-les-bons-outils-open-source">Choisir les bons outils open source</a></h3>
<p>La réussite d’une transition vers PostgreSQL - car il s’agit bien d’une transition progressive et non d’une migration - repose autant sur la stratégie que sur les outils.</p>
<p>Il ne suffit pas de copier des objets : il faut comprendre les subtilités du moteur Oracle et les transposer intelligemment dans l’univers PostgreSQL.</p>
<p>Parmi les outils incontournables, Ora2Pg joue un rôle central. Il permet non seulement de générer des rapports d’inventaire clairs, mais aussi d’automatiser la conversion des schémas, des données et du code PL/SQL. C’est un accélérateur précieux pour les projets bien structurés.</p>
<p>Mais dans certains contextes, la réalité est plus complexe. De nombreux clients accumulent une dette technique importante, avec des milliers de lignes de code procédural. Tenter de tout réécrire en PL/pgSQL dans un délai court reviendrait à épuiser les équipes, tout en compromettant la migration elle-même. Maintenir deux bases de code — l’une en PL/SQL, l’autre en PL/pgSQL — pendant une phase de transition complète est souvent intenable sur le plan organisationnel.</p>
<p>C’est précisément là qu’IvorySQL offre une alternative puissante. Ce fork de PostgreSQL, enrichi de compatibilités Oracle (PL/SQL, ROWID, DUAL, etc.), permet de réduire considérablement le besoin de réécriture immédiate. En combinant IvorySQL avec une documentation ciblée et des scripts de validation métier, on obtient une transition plus rapide, plus fiable, et surtout mieux maîtrisée.</p>
<p>Une fois en production, les équipes disposent du temps nécessaire pour réécrire progressivement leur code procédural en PL/pgSQL, sans pression ni rupture fonctionnelle.</p>
<h3 id="integration-et-tests"><a class="heading-anchor" href="#integration-et-tests">Intégration et tests</a></h3>
<p>L’un des grands avantages d’IvorySQL, c’est qu’il réalise une partie de l’intégration en amont. Grâce à son support natif du PL/SQL, des objets Oracle et de la syntaxe Oracle-compatible, de nombreux éléments migrés via Ora2Pg fonctionnent immédiatement sans adaptation lourde.</p>
<p>Cela ne dispense évidemment pas d’une phase de test, bien au contraire : il est essentiel de valider les comportements métier dans un environnement de préproduction IvorySQL. Les procédures, fonctions, packages, triggers et vues doivent être testés avec des cas réels, en comparant les résultats entre Oracle et IvorySQL pour garantir l’équivalence fonctionnelle.</p>
<p>Des scripts de comparaison peuvent être utilisés pour vérifier les réponses aux requêtes, les effets des transactions, ou les comportements des fonctions migrées. Mais dans bien des cas, IvorySQL permet de réduire considérablement le besoin de patchs ou de réécriture, ce qui accélère la mise en production et sécurise la transition.</p>
<h3 id="documenter-et-accompagner"><a class="heading-anchor" href="#documenter-et-accompagner">Documenter et accompagner</a></h3>
<p>Une transition réussie ne se limite pas à la technique : elle repose aussi sur une documentation claire et un accompagnement adapté. Il est essentiel de rédiger des cahiers de tests entiers et exhaustifs par objet complexe et modules (procédure, package, trigger…), afin de garder une trace des choix techniques, des adaptations réalisées, et des points d’attention.</p>
<p>L’accompagnement des équipes client est tout aussi important. Des ateliers ciblés permettent de transmettre les bonnes pratiques, d’expliquer les différences entre Oracle et PostgreSQL, et de faciliter la prise en main d’IvorySQL.</p>
<p>Enfin, la réussite d’une transition vers PostgreSQL repose aussi sur l’accompagnement des équipes techniques et fonctionnelles. Des sessions de formation ciblées permettent aux développeurs, DBA et chefs de projet de s’approprier les spécificités d’IvorySQL, de comprendre les différences avec Oracle, et de monter en compétence rapidement.</p>
<p>Ce dispositif s’appuie également sur un support technique structuré, qui aide à résoudre les blocages, à sécuriser les choix d’implémentation, et à fluidifier les échanges entre les équipes projet et les experts migration.</p>
<h2 id="ivorysql-dans-le-monde-reel"><a class="heading-anchor" href="#ivorysql-dans-le-monde-reel">IvorySQL dans le monde réel</a></h2>
<p>Lors d’une mission récente pour une entreprise du secteur privé, nous avons accompagné la transition d’une base Oracle vers IvorySQL dans un contexte contraint : dette technique importante, volumétrie élevée, et délais serrés.</p>
<p>Grâce à IvorySQL et notre capacité à automatiser cette transition, cette transition s’est faite rapidement et la quasi totalité des objets ont été intégrés sans réécriture.</p>
<p>La bascule d’IvorySQL vers PostgreSQL peut s’effectuer sereinement, dans la mesure où l’application fonctionne pleinement et répond aux attentes métier.</p>
<p>Les équipes ont pu se concentrer sur les tests métier, tandis que la formation ciblée et le support technique ont permis une montée en compétence rapide.</p>
<p>Il est indispensable de réussir ce genre de projet pour emmagasiner de la confiance et développer cette opération sur la totalité de votre parc d’instances Oracle !</p>
<p>Vous envisagez une transition Oracle vers PostgreSQL ? Parlons-en.</p>
<p>Contactez notre équipe d’experts, à tout moment: <a href="mailto:contact@data-bene.io">contact@data-bene.io</a></p>
<p>Le 26 novembre 2025, IvorySQL 5.0 a été publié - <a href="https://www.postgresql.org/about/news/ivorysql-50-released-major-oracle-compatibility-expansion-on-postgresql-180-foundation-3180/" rel="noopener">voir l’annonce ici</a> pour plus d’informations sur ce projet open source.</p>
 ]]></content>
			<author>
				<name>Stéphane Carton</name>
			</author>
    </entry>
    <entry>
      <title>Le saviez-vous ? Les tables dans PostgreSQL sont limitées à 1600 colonnes</title>
      <link href="https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/" />
      <updated>2025-11-13T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/</id>
     <content type="html"><![CDATA[ <p><strong>Saviez-vous qu’une table ne peut pas contenir plus de 1 600 colonnes ?</strong> Cet article de blog est inspiré d’une conversation avec Pierre Ducroquet.</p>
<h2 id="tout-dabord-la-documentation"><a class="heading-anchor" href="#tout-dabord-la-documentation">Tout d’abord, la documentation</a></h2>
<p><a href="https://www.postgresql.org/docs/current/limits.html" rel="noopener">L’annexe K</a> de la documentation PostgreSQL  indique qu’une table peut contenir jusqu’à 1 600 colonnes.</p>
<p>Il s’agit d’une <strong>limite codée en dur</strong>, visible dans le code source à l’adresse <code>src/include/access/htup_details.h</code> :</p>
<pre class="language-plaintext"><code class="language-plaintext">#define MaxTupleAttributeNumber 1664
#define MaxHeapAttributeNumber	1600</code></pre>
<h2 id="atteindre-la-limite-de-maniere-classique"><a class="heading-anchor" href="#atteindre-la-limite-de-maniere-classique">Atteindre la limite de manière classique</a></h2>
<p>Vérifions d’abord cette affirmation par quelques tests.</p>
<h3 id="jouer-avec-la-definition-de-la-table"><a class="heading-anchor" href="#jouer-avec-la-definition-de-la-table">Jouer avec la définition de la table</a></h3>
<p>Nous utilisons ici un script bash simple, facile à adapter aux différents tests.</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Exemple classique</span>

<span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tint_1601;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tint_1601(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1601</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tint_1601 ADD COLUMN i_%s int;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>Le résultat est le suivant :</p>
<pre class="language-plaintext"><code class="language-plaintext">NOTICE:  table "tint_1600" does not exist, skipping
ERROR:  tables can have at most 1600 columns
CONTEXT:  SQL statement "ALTER TABLE tint_1600 ADD COLUMN i_1601 int;"
PL/pgSQL function inline_code_block line 8 at EXECUTE</code></pre>
<p>Jusqu’ici, tout va bien (ou du moins, tout fonctionne comme prévu).</p>
<p>Vous pourriez tenter de remplacer le type <code>int4</code> par le type <code>int2</code> pour arriver à créer une table de plus de 1 600 colonnes. Mais cela ne fonctionnera pas plus, car il s’agit d’une limite codée en dur.</p>
<h3 id="jouer-avec-le-contenu-dune-table"><a class="heading-anchor" href="#jouer-avec-le-contenu-dune-table">Jouer avec le contenu d’une table</a></h3>
<p>Générons une table de 1600 colonnes à partir du script sql précédent :</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tint_1600;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tint_1600(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1600</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tint_1600 ADD COLUMN i_%s int;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>Construisons puis insérons un tuple de 1600 colonnes :</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    s <span class="token keyword">TEXT</span><span class="token punctuation">;</span>
    rows_inserted <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    s :<span class="token operator">=</span> <span class="token function">format</span><span class="token punctuation">(</span>
                 <span class="token string">'INSERT INTO tint_1600 VALUES (1%s);'</span>
               <span class="token punctuation">,</span> <span class="token keyword">repeat</span><span class="token punctuation">(</span> <span class="token string">',1'</span> <span class="token punctuation">,</span> <span class="token number">1599</span> <span class="token punctuation">)</span>
               <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> s<span class="token punctuation">;</span>

    GET DIAGNOSTICS rows_inserted <span class="token operator">=</span> ROW_COUNT<span class="token punctuation">;</span>
    RAISE NOTICE <span class="token string">'Rows inserted: %'</span><span class="token punctuation">,</span> rows_inserted<span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>The output is:</p>
<pre class="language-plaintext"><code class="language-plaintext">NOTICE:  Rows inserted: 1
DO</code></pre>
<p>Sans surprise, c’est encore un succès.</p>
<h3 id="trop-gros-pour-echouer"><a class="heading-anchor" href="#trop-gros-pour-echouer">Trop gros pour échouer ?</a></h3>
<p>Continuons à repousser les limites.</p>
<p>On créé maintenant une autre table de 1 600 colonnes, cette fois avec le type de données <code>char(127)</code>.</p>
<p>On réutilise notre script bash avec quelques modifications :</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Create a table with 1,600 columns: 1 x int + 1599 x char(127)</span>
<span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tint_1600;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tint_1600(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1600</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tint_1600 ADD COLUMN c_%s char(127) NOT NULL;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span>

<span class="token comment">-- Insert a tuple - 1 x int + 1599 x char(127)</span>
<span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    s <span class="token keyword">TEXT</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    s :<span class="token operator">=</span> <span class="token function">format</span><span class="token punctuation">(</span>
                 <span class="token string">'INSERT INTO tint_1600 VALUES (1%s);'</span>
               <span class="token punctuation">,</span> <span class="token keyword">repeat</span><span class="token punctuation">(</span> $q$<span class="token punctuation">,</span><span class="token string">'1'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">127</span><span class="token punctuation">)</span>$q$ <span class="token punctuation">,</span> <span class="token number">1599</span> <span class="token punctuation">)</span>
               <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> s<span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span><span class="token identifier"><span class="token punctuation">`</span><span class="token punctuation">`</span></span><span class="token punctuation">`</span>

Le résultat est :</code></pre>
<p>ERROR:  row is too big: size 25616, maximum size 8160</p>
<pre class="language-plaintext"><code class="language-plaintext">
Comme on peut le voir, la table comporte effectivement 1 600 colonnes, mais cette fois, le tuple ne peut pas tenir dans une seule page heap, ce qui explique l'erreur « row is too big: size 25616, maximum size 8160 ». Si vous avez fait attention au script, vous avez pu constater que les colonnes sont définies comme `NOT NULL`. Aussi, lors de la création de la table, PostgreSQL aurait pu se rendre compte que l'insertion de données serait impossible. Mais il n'y a pas eu d'alerte.

## Quid des JOINs ?

Pour simplifier, testons avec une jointure automatique :

```sql
SELECT a.*,b.* FROM tint_1600 a, tint_1600 b;
ERROR:  target lists can have at most 1664 entries</code></pre>
<p>Maintenant, c’est la clause <code>SELECT</code> de (<code>a.*,b.*</code>) qui a atteint sa propre limite (<code>MaxTupleAttributeNumber = 1664</code>).</p>
<h2 id="atteindre-la-limite-de-colonnes-de-maniere-inattendue"><a class="heading-anchor" href="#atteindre-la-limite-de-colonnes-de-maniere-inattendue">Atteindre la limite de colonnes de manière inattendue</a></h2>
<p>Il arrive que vous deviez modifier votre application, et que cela entraîne des modifications de schéma.<br>
La plupart du temps, il s’agit de modifications de tables, comme l’ajout ou la suppression de colonnes.</p>
<h3 id="explorer-add-/-drop-column"><a class="heading-anchor" href="#explorer-add-/-drop-column">Explorer <code>ADD</code> / <code>DROP COLUMN</code></a></h3>
<p>Voyons ce qui se passe côté SQL lorsque nous ajoutons, puis supprimons, une colonne.</p>
<pre class="language-sql"><code class="language-sql"><span class="token operator">=</span><span class="token comment"># CREATE TABLE tadc_1600(i_1 int NOT NULL);</span>

<span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span>

<span class="token operator">=</span><span class="token comment"># ALTER TABLE tadc_1600 ADD COLUMN i_2 int NOT NULL;</span>

<span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span>

<span class="token operator">=</span><span class="token comment"># SELECT attname,attnum,attstorage,attnotnull,attisdropped</span>
   <span class="token keyword">FROM</span> pg_attribute
   <span class="token keyword">WHERE</span> attrelid<span class="token operator">=</span><span class="token punctuation">(</span>
                   <span class="token keyword">SELECT</span> oid
                   <span class="token keyword">FROM</span> pg_class
                   <span class="token keyword">WHERE</span> relname<span class="token operator">=</span><span class="token string">'tadc_1600'</span>
                   <span class="token punctuation">)</span>
     <span class="token operator">AND</span> attnum <span class="token operator">></span> <span class="token number">0</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> attnum<span class="token punctuation">;</span>

 attname <span class="token operator">|</span> attnum <span class="token operator">|</span> attstorage <span class="token operator">|</span> attnotnull <span class="token operator">|</span> attisdropped
<span class="token comment">---------+--------+------------+------------+--------------</span>
 i_1     <span class="token operator">|</span>      <span class="token number">1</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
 i_2     <span class="token operator">|</span>      <span class="token number">2</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
<span class="token punctuation">(</span><span class="token number">2</span> <span class="token keyword">rows</span><span class="token punctuation">)</span>

<span class="token operator">=</span><span class="token comment"># ALTER TABLE tadc_1600 DROP COLUMN i_2;</span>

<span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span>

<span class="token operator">=</span><span class="token comment"># SELECT attname,attnum,attstorage,attnotnull,attisdropped</span>
   <span class="token keyword">FROM</span> pg_attribute
   <span class="token keyword">WHERE</span> attrelid<span class="token operator">=</span><span class="token punctuation">(</span>
                   <span class="token keyword">SELECT</span> oid
                   <span class="token keyword">FROM</span> pg_class
                   <span class="token keyword">WHERE</span> relname<span class="token operator">=</span><span class="token string">'tadc_1600'</span>
                   <span class="token punctuation">)</span>
     <span class="token operator">AND</span> attnum <span class="token operator">></span> <span class="token number">0</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> attnum<span class="token punctuation">;</span>

           attname            <span class="token operator">|</span> attnum <span class="token operator">|</span> attstorage <span class="token operator">|</span> attnotnull <span class="token operator">|</span> attisdropped
<span class="token comment">------------------------------+--------+------------+------------+--------------</span>
 i_1                          <span class="token operator">|</span>      <span class="token number">1</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">2.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">|</span>      <span class="token number">2</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
<span class="token punctuation">(</span><span class="token number">2</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>Lors de la suppression d’une colonne, cette colonne</p>
<ul class="list">
<li>est renommée en « . » + « pg.dropped.» + attnum + « . »,</li>
<li>devient NULLable,</li>
<li>est marquée comme supprimée.</li>
</ul>
<h3 id="iterer-sur-lajout/la-suppression-de-colonnes"><a class="heading-anchor" href="#iterer-sur-lajout/la-suppression-de-colonnes">Itérer sur l’ajout/la suppression de colonnes</a></h3>
<p>On peut se demander s’il existe une limite au nombre d’opérations d’ajout/suppression qui peuvent être exécutées sur une table donnée.</p>
<p>Comme d’habitude, testons :</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- ADD / DROP COLUMN example</span>
<span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tadc;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tadc(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1601</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tadc ADD COLUMN i_%s int;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tadc DROP COLUMN i_%s;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>Le résultat est :</p>
<pre class="language-plaintext"><code class="language-plaintext">ERROR:  tables can have at most 1600 columns
CONTEXT:  SQL statement "ALTER TABLE tadc ADD COLUMN i_1601 int;"
PL/pgSQL function inline_code_block line 8 at EXECUTE</code></pre>
<p>Oh oh ! On a atteint la limite des 1 600 ici aussi !</p>
<p>Explorons un peu ce qui se passe :</p>
<pre class="language-sql"><code class="language-sql"><span class="token operator">=</span><span class="token comment"># SELECT attname,attnum,attstorage,attnotnull,attisdropped</span>
   <span class="token keyword">FROM</span> pg_attribute
   <span class="token keyword">WHERE</span> attrelid<span class="token operator">=</span><span class="token punctuation">(</span>
                   <span class="token keyword">SELECT</span> oid
                   <span class="token keyword">FROM</span> pg_class
                   <span class="token keyword">WHERE</span> relname<span class="token operator">=</span><span class="token string">'tadc'</span>
                   <span class="token punctuation">)</span>
     <span class="token operator">AND</span> attnum <span class="token operator">></span> <span class="token number">0</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> attnum<span class="token punctuation">;</span>

             attname             <span class="token operator">|</span> attnum <span class="token operator">|</span> attstorage <span class="token operator">|</span> attnotnull <span class="token operator">|</span> attisdropped
<span class="token comment">---------------------------------+--------+------------+------------+--------------</span>
 i_1                             <span class="token operator">|</span>      <span class="token number">1</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">2.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">2</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">3.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">3</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">4.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">4</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">5.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">5</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t

 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">1599.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">|</span>   <span class="token number">1599</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">1600.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">|</span>   <span class="token number">1600</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
<span class="token punctuation">(</span><span class="token number">1600</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>La table <code>tadc</code> comporte 1 600 colonnes. Vous pouvez vous en apercevoir car toutes les modifications sont ajoutées à la table, et son contenu n’est pas réécrit.</p>
<p>Aussi, à ce stade, toute modification supplémentaire visant à ajouter ou supprimer des colonnes sera vouée à l’échec.</p>
<p>Comment faire pour me sortir de cette situation ?</p>
<h4 id="le-chevalier-du-vacuum-devrait-sauver-la-princesse-postgresql-non"><a class="heading-anchor" href="#le-chevalier-du-vacuum-devrait-sauver-la-princesse-postgresql-non">Le chevalier du VACUUM devrait sauver la princesse PostgreSQL, non ?</a></h4>
<p>Et non ! La commande <code>VACUUM</code> fonctionne au niveau du tuple, donc même si vous exécutez un <code>VACUUM FULL</code>, la structure de la table ne changera pas.</p>
<h4 id="donc-le-dragon-a-mange-le-chevalier-que-fait-on"><a class="heading-anchor" href="#donc-le-dragon-a-mange-le-chevalier-que-fait-on">Donc le dragon a mangé le chevalier, que fait-on ?</a></h4>
<p>Il ne s’agit pas d’un problème de tuples morts, mais plutôt d’un problème de catalogue.<br>
Vous devez créer une nouvelle définition de table.</p>
<p>Voici quelques solutions, des plus simples aux plus complexes :</p>
<ol class="list">
<li>
<p>Créer une nouvelle table avec interruption de service</p>
<ul class="list">
<li><code>CREATE TABLE LIKE (INCLUDING ALL)</code></li>
<li>Copier (<code>COPY</code>) les données de l’ancienne table vers la nouvelle</li>
<li>Renommer les tables</li>
<li>Supprimer l’ancienne table</li>
</ul>
</li>
<li>
<p>Exploiter la réplication logique pour minimiser les interruptions de service</p>
<ul class="list">
<li><code>CREATE TABLE LIKE (INCLUDING ALL)</code></li>
<li><code>CREATE local PUBLICATION/SUBSCRIPTION</code></li>
<li>Une fois les données synchronisées, arrêter/mettre en pause le service applicatif</li>
<li>Supprimer l’abonnement</li>
<li>Renommer les tables</li>
<li>Redémarrer/relancer l’application</li>
<li>Supprimer l’ancienne table</li>
</ul>
</li>
</ol>
<h2 id="contactez-nous"><a class="heading-anchor" href="#contactez-nous">Contactez-nous</a></h2>
<p>Vous avez d’autres idées pour résoudre ce problème ? Vous avez trouvé d’autres moyens étranges de déclencher cette erreur liée à la limite codée en dur ? <a href="https://www.data-bene.io/en/#contact" rel="noopener">Contactez-nous</a> ! Nous sommes toujours ravis d’échanger sur PostgreSQL.</p>
 ]]></content>
			<author>
				<name>Frédéric Delacourt</name>
			</author>
    </entry>
    <entry>
      <title>Statistiques cumulatives dans PostgreSQL 18</title>
      <link href="https://www.data-bene.io/fr/blog/statistiques-cumulatives-dans-postgresql-18/" />
      <updated>2025-09-29T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/statistiques-cumulatives-dans-postgresql-18/</id>
     <content type="html"><![CDATA[ <p>Dans <strong>PostgreSQL 18</strong>, le sous-système de statistiques et de supervision bénéficie d’une refonte majeure: statistiques cumulatives étendues, nouvelle visibilité I/O par backend, possibilité pour les extensions d’exporter / importer / ajuster les statistiques, et améliorations des contrôles GUC ainsi que du comportement de cache et de snapshot. Ces changements ouvrent de nouvelles perspectives pour l’analyse de performance, la simulation inter-environnements et une meilleure intégration avec les extensions. Dans cet article, j’explore les nouveautés, les points d’attention, les paramètres GUC, ainsi que la manière dont les auteurs d’extensions peuvent exploiter la nouvelle API en C.</p>
<h2 id="introduction-and-motivation"><a class="heading-anchor" href="#introduction-and-motivation">Introduction &amp; motivation</a></h2>
<p>Les statistiques (au sens large: compteurs de supervision, métriques I/O, et estimations pour le planificateur / optimiseur) sont au cœur à la fois de l’optimisation de performance et des décisions internes de PostgreSQL. Des statistiques transparentes, fiables et manipulables permettent entre autres aux DBAs d’adresser directement l’efficacité de PostgreSQL, et donnent aux «extensions» la possibilité d’améliorer l’expérience utilisateur.</p>
<p>Cela dit, le système historique de statistiques de PostgreSQL n’était pas exempt de frictions: capacité limitée à réinitialiser les statistiques des relations, métriques exprimées dans des unités pas toujours alignées avec les besoins utilisateurs, absence d’API C pour utiliser le moteur de statistiques cumulatives de PostgreSQL. PostgreSQL 18 répond directement à ces préoccupations.</p>
<p>Voici un résumé des améliorations clés.</p>
<h2 id="un-avertissement-sur-les-statistiques"><a class="heading-anchor" href="#un-avertissement-sur-les-statistiques">Un avertissement sur les statistiques</a></h2>
<p>Bien que les statistiques soient extrêmement utiles, leur collecte peut consommer du temps et des ressources. PostgreSQL 18 introduit un point important: avec l’élargissement du spectre des métriques collectables, la taille maximale de la table de hachage a été augmentée. Gardez cela à l’esprit, surtout si vous concevez des systèmes à grande échelle avec des architectures «un ensemble de tables par client»: on a constaté que la limite de 1 Go pouvait être atteinte avec quelques millions de tables.</p>
<h2 id="quoi-de-neuf-dans-postgresql-18-et-les-«-stats-»"><a class="heading-anchor" href="#quoi-de-neuf-dans-postgresql-18-et-les-«-stats-»">Quoi de neuf dans PostgreSQL 18 et les « stats »</a></h2>
<p>Voici les nouvelles fonctionnalités majeures ou les améliorations concernant les statistiques et la supervision.</p>
<p>De manière générale, <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-IO-VIEW" rel="noopener">pg_stat_io</a> rapporte désormais l’activité I/O en octets plutôt qu’en pages, ce qui est plus pratique pour l’analyse. De plus, les statistiques WAL y ont été déplacées depuis <code>pg_stat_wal</code>, offrant ainsi une vue unique et complète.</p>
<h3 id="mises-a-jour"><a class="heading-anchor" href="#mises-a-jour">Mises à jour</a></h3>
<p><a href="https://www.postgresql.org/docs/18/pgupgrade.html" rel="noopener">pg_upgrade</a> est désormais capable de conserver les statistiques de l’optimiseur, supprimant la nécessité de relancer un <code>ANALYZE</code> complet pour obtenir de bons plans de requêtes après une montée de version: une avancée très attendue pour les grandes bases!</p>
<p>Attention toutefois: les statistiques personnalisées ajoutées par une extension ainsi que celles créées avec <a href="https://www.postgresql.org/docs/18/sql-createstatistics.html" rel="noopener">CREATE STATISTICS</a> ne sont pas conservées.</p>
<p>Vous voudrez sûrement examiner les nouvelles options de <a href="https://www.postgresql.org/docs/18/app-vacuumdb.html" rel="noopener">vacuumdb</a> (<code>--missing-stats-only</code>) pour n’analyser que ce qui est nécessaire.</p>
<p>Dans la même veine, l’option <code>--[no-]statistics</code> a été ajoutée à <a href="https://www.postgresql.org/docs/18/app-pgdump.html" rel="noopener">pg_dump</a>, <a href="https://www.postgresql.org/docs/18/app-pgdumpall.html" rel="noopener">pg_dumpall</a>, et <a href="https://www.postgresql.org/docs/18/app-pgrestore.html" rel="noopener">pg_restore</a>.</p>
<h3 id="maintenance"><a class="heading-anchor" href="#maintenance">Maintenance</a></h3>
<p>Il est désormais plus simple d’évaluer l’effort de maintenance sur les objets, puisque le temps total passé dans les opérations VACUUM et ANALYZE (y compris<br>
automatiques) est rapporté dans <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW" rel="noopener">pg_stat_all_tables</a> et ses variantes.</p>
<p>Un nouveau GUC à ne pas oublier: <a href="https://www.postgresql.org/docs/18/runtime-config-statistics.html#GUC-TRACK-COST-DELAY-TIMING" rel="noopener">track_cost_delay_timing</a>. Il collecte le temps passé à dormir (suite aux opérations retardées) pour <code>VACUUM</code> et <code>ANALYZE</code>. Très intéressant, mais comme les autres GUC <code>track_io*</code>, il multiplie les appels à l’horloge système, ce qui peut provoquer un impact sévère sur certaines plateformes. Toujours vérifier avec un outil comme <a href="https://www.postgresql.org/docs/18/pgtesttiming.html" rel="noopener">pg_test_timing</a> pour s’assurer que votre système peut le supporter!</p>
<p>Plus de questions sur l’activité du checkpointer grâce à <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-CHECKPOINTER-VIEW" rel="noopener">pg_stat_checkpointer</a>. Le nouvel attribut <code>num_done</code> indique le nombre de checkpoints <strong>terminés</strong>. Vous pouvez aussi savoir quel type de buffers a été écrit grâce à <code>slru_written</code>, et <code>buffers_written</code> qui ne concerne désormais que <code>shared_buffers</code>: auparavant, journal et vue n’affichaient pas les mêmes totaux, car un compteur <code>SLRU</code> <a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=17cc5f666" rel="noopener">existait dans un cas mais pas dans l’autre</a>.</p>
<h3 id="analyse"><a class="heading-anchor" href="#analyse">Analyse</a></h3>
<p>Envie d’en savoir plus sur l’I/O traité par un backend (PID) ? Appelez <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#PG-STAT-GET-BACKEND-IO" rel="noopener">pg_stat_get_backend_io(int)</a> et vous obtiendrez une sortie similaire à la vue <code>pg_stat_io</code>, mais pour ce processus. Pour les stats WAL de ce PID: utilisez <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#PG-STAT-GET-BACKEND-WAL" rel="noopener">pg_stat_get_backend_wal(int)</a>.</p>
<p>De nouveaux attributs <code>parallel_workers_to_launch</code> et <code>parallel_workers_launched</code> apparaissent dans <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW" rel="noopener">pg_stat_database</a>. Le ratio permet de savoir si nous avons assez de slots pour les workers parallèles.</p>
<p>Changements intéressants dans <a href="https://www.postgresql.org/docs/18/pgstatstatements.html" rel="noopener">pg_stat_statements</a>: plus de requêtes seront regroupées sous le même identifiant. Par exemple, les<br>
motifs <code>IN (1,2,3, ...)</code> n’utiliseront que la première et la dernière constante. Un changement plus contre-intuitif concerne le nom de table utilisé dans une requête: seul le nom est pris en compte, pas le schéma ni l’OID de relation. Cela permet de suivre les tables supprimées ou recréées, mais cela peut aussi regrouper les stats de tables sans lien ayant simplement le même nom. Pour séparer les stats de tables homonymes, il faudra les aliaser dans les requêtes (<code>FROM my.table mt, other.table ot</code>)…</p>
<p>Enfin, ajouts à <a href="https://www.postgresql.org/docs/18/view-pg-backend-memory-contexts.html" rel="noopener">pg_backend_memory_contexts</a> avec <code>path</code> (pour récupérer parent/enfant) et <code>type</code> pour distinguer les contextes <code>AllocSet</code>, <code>Generation</code>, <code>Slab</code> et <code>Bump</code>… Et au fait, que sont <code>Slab</code> et <code>Bump</code> ? Pas documentés ; il faut <a href="https://github.com/postgres/postgres/tree/master/src/backend/utils/mmgr" rel="noopener">lire les en-têtes des fichiers C ici</a>. Ils existent pour optimiser l’allocation, la réallocation et la réinitialisation mémoire selon les usages attendus. Par exemple, <code>Slab</code> est défini comme un «MemoryContext implementation designed for cases where large numbers of equally-sized objects can be allocated and freed efficiently with minimal memory wastage and fragmentation».</p>
<p>Ah, non, encore une dernière: <code>wal_buffers_full</code> a été ajouté à <code>pg_stat_statements</code> pour permettre un meilleur réglage de <code>wal_buffers</code>.</p>
<h3 id="replication"><a class="heading-anchor" href="#replication">Réplication</a></h3>
<p>De meilleures informations apparaissent désormais pour la gestion des conflits en réplication logique grâce à de nouveaux attributs dans <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION-STATS" rel="noopener">pg_stat_subscription_stats</a>. En référence, cet extrait du <a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=6c2b5edec" rel="noopener">commit</a> liste les attributs introduits:</p>
<ul class="list">
<li><code>confl_insert_exists</code>: nombre de fois où une insertion de ligne a violé une contrainte unique NOT DEFERRABLE.</li>
<li><code>confl_update_origin_differs</code>: nombre de fois où une mise à jour a été faite sur une ligne déjà modifiée par une autre origine.</li>
<li><code>confl_update_exists</code>: nombre de fois où la valeur mise à jour d’une ligne viole une contrainte unique NOT DEFERRABLE.</li>
<li><code>confl_update_missing</code>: nombre de fois où le tuple à mettre à jour est manquant.</li>
<li><code>confl_delete_origin_differs</code>: nombre de fois où une suppression a été effectuée sur une ligne déjà modifiée par une autre origine.</li>
<li><code>confl_delete_missing</code>: nombre de fois où le tuple à supprimer est manquant.</li>
</ul>
<h3 id="avance"><a class="heading-anchor" href="#avance">Avancé</a></h3>
<p>Un <a href="https://www.postgresql.org/docs/18/functions-admin.html#FUNCTIONS-ADMIN-STATSMOD" rel="noopener">nouveau jeu de fonctions</a> permet désormais de gérer les statistiques de relations et d’attributs (<code>relpages</code>, <code>avg_width</code>, etc.). Cela offre la possibilité d’exporter, importer et ajuster les stats à volonté, afin de répliquer le comportement du planificateur hors production, de maintenir des stats corrigées, et plus encore.</p>
<h3 id="mon-prefere-pour-les-auteurs-dextensions-la-nouvelle-api-c-de-stats"><a class="heading-anchor" href="#mon-prefere-pour-les-auteurs-dextensions-la-nouvelle-api-c-de-stats">Mon préféré pour les auteurs d’extensions: la nouvelle API C de stats</a></h3>
<p>L’une des évolutions les plus enthousiasmantes est ce que PostgreSQL 18 <em>ouvre</em> aux auteurs d’extensions.</p>
<p>Cette petite ligne au bas de la section <a href="https://www.postgresql.org/docs/18/release-18.html#RELEASE-18-MODULES" rel="noopener">E.1.3.9 Modules</a> est celle qui nous intéresse :</p>
<blockquote>
<p>Allow extensions to use the server’s cumulative statistics API (Michael Paquier)</p>
</blockquote>
<p>Jusqu’ici, la manipulation des statistiques était réservée à l’interne ; désormais, une API officielle et structurée est disponible pour construire (ou envelopper) autour.</p>
<p>Le <a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=7949d9594" rel="noopener">message de commit</a> est bien rédigé et couvre l’essentiel des nouveautés. Un sous-ensemble des options est <a href="https://www.postgresql.org/docs/18/xfunc-c.html#XFUNC-ADDIN-CUSTOM-CUMULATIVE-STATISTICS" rel="noopener">détaillé dans la documentation</a>. Cependant, il faut encore plonger dans le code source pour en savoir plus ; en particulier, il vaut la peine de regarder l’extension <code>injection points</code> (fournie avec PostgreSQL) qui utilise cette nouvelle API.</p>
<p>Pour aller plus loin sur la manière dont une extension peut exploiter ces nouvelles capacités, vous pourrez bientôt découvrir <strong>PACS (PostgreSQL Advanced Cumulative Statistics)</strong> sur Codeberg : mon projet qui propose une bibliothèque de wrappers et des utilitaires autour des nouvelles APIs de statistiques de PostgreSQL 18.</p>
<p>En attendant, la présentation que j’ai donnée à <a href="https://archive.fosdem.org/2025/schedule/event/fosdem-2025-4496-stats-roll-baby-stats-roll-/" rel="noopener">FOSDEM 2025</a> explore ce sujet plus en détail.</p>
 ]]></content>
			<author>
				<name>Cédric Villemain</name>
			</author>
    </entry>
    <entry>
      <title>Base de données la plus désirée trois années consécutives : L'attrait de PostgreSQL pour les développeurs</title>
      <link href="https://www.data-bene.io/fr/blog/base-de-donnees-la-plus-desiree-trois-annees-consecutives/" />
      <updated>2025-08-09T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/base-de-donnees-la-plus-desiree-trois-annees-consecutives/</id>
     <content type="html"><![CDATA[ <p>PostgreSQL vit plus qu’un simple moment de gloire—elle établit un schéma clair d’excellence soutenue. Pour la troisième année consécutive, cette base de données pilotée par la communauté a revendiqué la première place dans les résultats 2025 de l’enquête annuelle des développeurs de Stack Overflow, et les résultats révèlent à la fois ce que les développeurs valorisent aujourd’hui et où se dirige le paysage des bases de données.</p>
<p>Les résultats de l’enquête montrent que PostgreSQL est classée au plus haut rang parmi toutes les technologies de bases de données pour les développeurs qui veulent l’utiliser dans la prochaine année (47%) ou l’ont utilisée cette année et veulent continuer à l’utiliser l’année prochaine (66%) pour la troisième année d’affilée.</p>
<h2 id="les-chiffres-racontent-une-histoire-convaincante"><a class="heading-anchor" href="#les-chiffres-racontent-une-histoire-convaincante">Les chiffres racontent une histoire convaincante</a></h2>
<p>Les données de l’enquête de plus de 49 000 développeurs à travers 177 pays fournissent une preuve claire de l’attrait soutenu de PostgreSQL. Depuis 2023, PostgreSQL s’est constamment classée comme la technologie de base de données la plus désirée et la plus admirée parmi les développeurs.</p>
<p>En regardant les mesures spécifiques des visualisations de l’enquête, PostgreSQL mène avec 46,5% des développeurs voulant travailler avec elle dans l’année à venir, tandis qu’un impressionnant 65,5% de ceux qui l’ont utilisée veulent continuer à le faire. Ce ne sont pas seulement des chiffres impressionnants—ils représentent une cohérence qui est rare dans le paysage technologique en rapide évolution.</p>
<p>Les données de l’enquête révèlent également un schéma intéressant parmi les développeurs utilisant actuellement d’autres technologies de bases de données. Les développeurs travaillant avec MongoDB et Redis montrent un désir particulièrement fort d’ajouter PostgreSQL à leur boîte à outils l’année prochaine, voyant la valeur d’ajouter des compétences en bases de données relationnelles à leur répertoire.</p>
<h2 id="lavantage-communautaire-en-action"><a class="heading-anchor" href="#lavantage-communautaire-en-action">L’avantage communautaire en action</a></h2>
<p>Pourquoi PostgreSQL a-t-elle atteint ce niveau de succès soutenu ? La réponse réside dans son modèle de développement piloté par la communauté. En tant que projet open source, PostgreSQL bénéficie d’un développement collaboratif qui est à la fois transparent et réactif aux besoins du monde réel.</p>
<p>Le projet PostgreSQL représente le meilleur de ce que le développement piloté par la communauté peut accomplir. Avec plus de 400 contributeurs de code à travers plus de 140 entreprises de soutien, le projet se vante de plus de 55 000 commits et plus de 1,6 million de lignes de code soigneusement élaboré. Cette approche diverse et globalement distribuée du développement résulte en des tests plus approfondis, des corrections de bogues plus rapides, et des fonctionnalités plus innovantes que les modèles de développement commercial traditionnels n’atteignent typiquement.</p>
<p>Les versions majeures sont publiées annuellement avec approximativement 180 fonctionnalités par version, complétées par des versions mineures trimestrielles qui incluent de nombreuses améliorations et corrections. Cette cadence régulière d’innovation constamment contribuée par des individus partout dans le monde assure que PostgreSQL ne fait pas que suivre le rythme des besoins des développeurs—elle les anticipe. Plus que cela, chaque individu a la capacité de contribuer au projet pour s’assurer que partout où le logiciel prend du retard, la fonctionnalité change pour répondre aux demandes modernes.</p>
<h2 id="plus-quune-simple-base-de-donnees-relationnelle"><a class="heading-anchor" href="#plus-quune-simple-base-de-donnees-relationnelle">Plus qu’une simple base de données relationnelle</a></h2>
<p>Un facteur clé dans l’attrait large de PostgreSQL est qu’elle n’est pas limitée à être juste un système de base de données relationnelle. PostgreSQL est objet-relationnelle par conception, capable de gérer des types de données diverses incluant JSON/JSONB, XML, Clé-Valeur, géométriques, géospatiales, UUID natif, et données de séries temporelles. Cette polyvalence explique pourquoi les développeurs de milieux NoSQL trouvent PostgreSQL attractive—elle offre la fiabilité relationnelle tout en maintenant la flexibilité à laquelle ils sont habitués.</p>
<p>Le soutien étendu pour différents types de données, combiné avec les caractéristiques ACID (Atomicité, Cohérence, Isolation, Durabilité), permet une gestion de données optimisée, performante, et fiable indépendamment des exigences spécifiques en place. De plus, l’énorme réseau d’extensions piloté par la communauté de PostgreSQL s’appuie sur son extensibilité native, fournissant des solutions pour la gestion géospatiale, la récupération après sinistre, l’infrastructure de haute disponibilité, la surveillance, l’audit, et bien plus.</p>
<h2 id="le-paysage-plus-large-des-bases-de-donnees"><a class="heading-anchor" href="#le-paysage-plus-large-des-bases-de-donnees">Le paysage plus large des bases de données</a></h2>
<p>Tandis que PostgreSQL domine les positions de tête, l’enquête révèle un écosystème de bases de données sain et compétitif. Les classements complets montrent :</p>
<p><strong>Bases de données les plus désirées :</strong><br>
• PostgreSQL : 46,5%<br>
• SQLite : 28,3%<br>
• Redis : 23,5%<br>
• MySQL : 20,5%<br>
• MongoDB : 17,6%</p>
<p><strong>Bases de données les plus admirées :</strong><br>
• PostgreSQL : 65,5%<br>
• SQLite : 59%<br>
• Redis : 54,9%<br>
• MongoDB : 45,7%<br>
• MySQL : 43,2%</p>
<p>Ces chiffres reflètent un écosystème diversifié où différentes bases de données servent des objectifs spécifiques. La forte performance de SQLite souligne l’importance continue des solutions légères et intégrées. Redis maintient sa position comme une base de données spécialisée hautement considérée pour la mise en cache et les applications temps réel. Les bases de données traditionnelles comme MySQL et Microsoft SQL Server continuent de détenir des positions significatives, tandis que les nouvelles technologies comme DuckDB montrent des scores d’admiration impressionnants malgré des taux d’utilisation plus faibles.</p>
<h2 id="la-fondation-du-succes-durable-de-postgresql"><a class="heading-anchor" href="#la-fondation-du-succes-durable-de-postgresql">La fondation du succès durable de PostgreSQL</a></h2>
<p>Trois années consécutives au sommet des préférences des développeurs n’arrive pas par accident. La domination soutenue de PostgreSQL découle de forces fondamentales qui continuent de bien servir les développeurs alors que les paysages technologiques changent. La résilience intégrée dans PostgreSQL à travers son modèle de développement piloté par la communauté signifie qu’elle s’adapte sans perdre la stabilité. Son extensibilité la distingue de manières pratiques—plutôt que d’attendre les feuilles de route des fournisseurs ou de s’inquiéter des lacunes de fonctionnalités, les développeurs peuvent construire ce dont ils ont besoin ou tirer parti de l’écosystème étendu d’extensions communautaires. La nature open source assure que PostgreSQL reste focalisée sur les besoins des développeurs plutôt que sur les modèles d’affaires, avec des corrections de bogues qui se produisent rapidement et des fonctionnalités qui se développent basées sur des cas d’usage du monde réel.</p>
<p>Après 35 ans de développement actif et trois années consécutives comme la technologie de base de données la plus désirée, PostgreSQL a prouvé que le développement open source piloté par la communauté peut livrer à la fois une utilité immédiate et une valeur à long terme. Pour les développeurs et organisations regardant leurs choix de bases de données, PostgreSQL offre quelque chose d’increasingly rare : une technologie qui s’améliore avec le temps sans laisser ses utilisateurs derrière.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Retour de HOW2025</title>
      <link href="https://www.data-bene.io/fr/blog/retour-de-how2025/" />
      <updated>2025-07-14T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/retour-de-how2025/</id>
     <content type="html"><![CDATA[ <p>Les 27 et 28 juin se tenaient les conférences Highgo Open World, consacrées à l’écosystème PostgreSQL et au projet IvorySQL. Côté chiffres, le succès est notable : près de 1 000 participants sur place, jusqu’à 8 000 connexions simultanées sur les streams, et environ 25 000 spectateurs au total.</p>
<p>Le programme comptait 101 conférences techniques animées par 105 intervenants. La majorité des sessions étaient en mandarin, avec un track anglophone proposé en traduction simultanée. Vous pouvez consulter le programme complet sur <a href="https://ivorysql.io/schedule/" rel="noopener">IvorySQL.io</a> et retrouver les replays sur Weibo via <a href="https://ivorysql.io/2025/06/27/live-access-june27/" rel="noopener">ce lien.</a></p>
<p>Nous étions un petit groupe de la communauté internationale présents, dont <a href="https://postgresql.life/post/grant_zhou/" rel="noopener">Grant Zhou</a> qui assure entre autre la liaison et la collaboration avec l’association PostgreSQL en Chine et dans le reste du monde.</p>
<p>Sur le plan technique, le contenu était dense et particulièrement intéressant. J’ai retenu notamment :</p>
<ul class="list">
<li>
<p>La présentation d’Alena Rybakina sur le planificateur de requêtes PostgreSQL et les stratégies pour contourner certaines limites.</p>
</li>
<li>
<p>Un focus clair et concret sur Patroni (Haute-Disponibilité) par Alexander Kukushkin et Polina Bungina.</p>
</li>
<li>
<p>Florentz Tselai a présenté 2 sujets en appliquant ses préceptes: simplicité efficacité, sur l’utilisation de «l’IA» avec PostgreSQL et la gestion des données avec comme support Sun Tzu et les 36 stratagèmes.</p>
</li>
<li>
<p>Également une très bonne introduction à Bazel et son utilisation pour Monogres (à découvrir bientôt) présenté avec énergie par Alvaro Hernandez.</p>
<p>Monogres est une initiative très intéressante qui doit permettre de renforcer le contrôle de la supply chain logicielle, un thème  majeur dans l’IT de nos jours. Et j’y ai aussi vu une très belle occasion d’offrir une vitrine a des variations de PostgreSQL avec des fonctionnalités et des correctifs dont l’inclusion dans PostgreSQL lui-même même ou le backport dans des version majeures précédentes n’est pas toujours possible.</p>
</li>
<li>
<p>Michael Meskes avait l’honneur d’une conférence plénière pour un sujet qui le mérite largement: « From Code to Commerce: Open Source Business Models Today », une keynote sur l’open-source et les logiciels libres, appliqués à l’écosystème PostgreSQL.</p>
</li>
<li>
<p>Mon collègue Andrea a présenté les évolutions et les tendances des entreprises pour transiter vers IvorySQL et PostgreSQL</p>
</li>
<li>
<p>Pour ma part, j’ai présenté linux PSI dans le contexte PostgreSQL.</p>
</li>
</ul>
<p>Comme tout est en streaming, je vous encourage à aller explorer et visionner les sujets qui vous intéressent. Il y a ausi des conférences en anglais pré-enregistrées mais j’avoue avoir profité des créneaux pour échanger avec des participants.</p>
<p>En apparté des conférences, j’ai eu la chance de rencontrer plusieurs membres de la communauté PostgreSQL chinoise très réputés pour leur implication dans le succès de PostgreSQL localement. J’ai eu aussi l’occasion d’en apprendre d’avantage sur Cloudberry, en remplacement de Greenplum, merci Dianjin Wang!</p>
<hr>
<p>Pour Data Bene s’était également un moment prévu pour rencontrer l’équipe en charge d’IvorySQL, basée en grande partie dans le Shandong, la province où se trouve Jinan, ville hôte des conférences. Ivory est un projet auquel nous participons activement et qui permet aux entreprises de s’affranchir d’Oracle «en douceur». C’est un sujet important pour nos clients et qui occupe un place prépondérante dans notre partenariat avec Highgo: ils portent ce projet depuis plusieurs années déjà et nous voulons permettre aux entreprises européenes d’en profiter avec un accompagnement et expertise adaptée.</p>
<hr>
<p>Les conférences étaient très bien organisées et l’acceuil formidable, le «Social Event» au «beer garden» local parfaitement adapté à la chaleur de Jinan fin juin!</p>
<p>Vu le programme des conférences j’ai amèrement regreté de ne rien comprendre (Il y avait 1 track en Anglais et 5 en Mandarin) … mais il se dit déjà que l’an prochain les conférences en Mandarin pourraient peut être être traduites (en anglais), et la date avancée en Mai pour profiter d’un climat plus doux.</p>
<p>Il y a tellement à y apprendre que j’y retournerai avec grand plaisir.</p>
 ]]></content>
			<author>
				<name>Cédric Villemain</name>
			</author>
    </entry>
    <entry>
      <title>Une visite à PGConf.DE 2025 et des discussions sur PostgreSQL dans le contexte des sciences de la vie</title>
      <link href="https://www.data-bene.io/fr/blog/une-visite-a-pgconfde-2025-et-des-discussions-sur-PostgreSQL-dans-le-contexte-des-sciences-de-la-vie/" />
      <updated>2025-06-06T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/une-visite-a-pgconfde-2025-et-des-discussions-sur-PostgreSQL-dans-le-contexte-des-sciences-de-la-vie/</id>
     <content type="html"><![CDATA[ <p>C’est toujours un plaisir d’assister aux événements Postgres, et la <a href="http://PGConf.DE" rel="noopener">PGConf.DE</a> 2025 à Berlin n’a pas fait exception. Cette année, l’événement a permis de renouer de vieilles amitiés et a offert un environnement ouvert et accueillant pour en nouer de nouvelles. Et, bien sûr, il y a eu des exposés passionnants!</p>
<p>Lors de la conférence, j’ai eu l’occasion de parler de Postgres dans le contexte des sciences de la vie (voir la section suivante). Dans l’ensemble, j’ai trouvé qu’il y avait une belle diversité de présentations : une sélection qui couvrait le cœur de Postgres, son écosystème et bien plus encore.</p>
<p>Je suis convaincu qu’à la fin de la conférence, la plupart des participants, sinon tous, sont repartis plus riches qu’ils n’étaient venus, d’une manière ou d’une autre.</p>
<h2 id="presentations"><a class="heading-anchor" href="#presentations">Présentations</a></h2>
<p>En amont de cet événement, j’ai eu l’honneur de voir l’une de mes conférences retenue. Son titre était : « <a href="https://www.postgresql.eu/events/pgconfde2025/schedule/session/6541-postgres-and-life-science-from-cells-to-stars/" rel="noopener">Postgres et les sciences de la vie : des cellules aux étoiles</a>&quot; et il était organisé comme une méta-analyse / un hommage à l’extensibilité de Postgres et à ses diverses applications au monde naturel.</p>
<p>Afin de raconter au mieux cette histoire, j’ai présenté au public les cinq sujets suivants, de portée croissante :</p>
<ul class="list">
<li>Cartographie neuronale avec une interface graphique compatible PostGIS
<ul class="list">
<li><a href="https://github.com/catmaid/CATMAID" rel="noopener">Code source de CATMAID</a></li>
</ul>
</li>
<li>Examen hydrologique des rivières avec l’extension PgHydro
<ul class="list">
<li><a href="https://github.com/pghydro/pghydro" rel="noopener">Code source de PgHydro</a></li>
</ul>
</li>
<li>Méta-analyse de la biomasse des poissons avec Vanilla Postgres
<ul class="list">
<li><a href="https://www.nature.com/articles/s41597-024-04026-0" rel="noopener">Lien vers une publication évaluée par des pairs</a></li>
</ul>
</li>
<li>Tableau de bord de la COVID-19 avec l’extension Citus
<ul class="list">
<li><a href="https://www.citusdata.com/blog/2021/12/11/uk-covid-19-dashboard-built-using-postgres-and-citus/" rel="noopener">Lien vers l’article de blog</a></li>
</ul>
</li>
<li>Classification par étoiles basée sur des forks de Postgres et des modifications d’extensions
<ul class="list">
<li><a href="https://indico.cern.ch/event/1471762/contributions/6280216/" rel="noopener">Lien vers la présentation au Cern PGDay - 2025</a></li>
</ul>
</li>
</ul>
<p>J’ai apprécié la préparation et la présentation de cette conférence, qui a donné lieu à des échanges enrichissants. Deux points ont particulièrement retenu mon attention et me semblaient intéressants à aborder ici :</p>
<ol class="list">
<li>
<p>Quelles sont les trois technologies (outils/flux de travail) qui bénéficieraient le plus, en termes d’amélioration d’impact ou de facilité d’adoption, si leurs complexités étaient considérablement réduites/abstraites ?</p>
</li>
<li>
<p>Lors de ma présentation, j’ai affirmé que le cerveau était compatible avec l’ACID. Bien que je fasse principalement référence aux potentiels d’action des neurones, cette affirmation a été légitimement contestée.</p>
</li>
</ol>
<h3 id="1-outils-/-flux-de-travail-identifies"><a class="heading-anchor" href="#1-outils-/-flux-de-travail-identifies">1. Outils / flux de travail identifiés</a></h3>
<p><em>1. Quelles sont les trois technologies (outils/flux de travail) qui bénéficieraient le plus, en termes d’amélioration d’impact ou de facilité d’adoption, si leurs complexités étaient considérablement réduites/abstraites ?</em></p>
<h4 id="1-vectorisation-dimage"><a class="heading-anchor" href="#1-vectorisation-dimage">1. Vectorisation d’image</a></h4>
<p>Dès le départ, j’ai pensé à la classification des images issues de scanner à résonance magnétique. Ce sujet est très discuté au sein de la communauté médicale, et de nombreuses startups se sont également lancées dans ce domaine. Personnellement, je pense qu’il y a en effet une dynamique pour améliorer l’accessibilité, mais qu’il existe encore une forte séparation entre le développeur et l’utilisateur final. Bien que je n’aie pas de réponse toute faite à ce stade, je vous conseillerais, pour commencer, de vous renseigner sur <a href="https://github.com/pgvector/pgvector" rel="noopener">vecteur pg</a> et <a href="https://github.com/postgresml/postgresml" rel="noopener">postgresml</a>. Compte tenu de l’intégration des vecteurs et de l’apprentissage automatique dans ce défi, j’envisagerais d’utiliser un service d’intégration d’images pour convertir la sortie IRM brute en un format compatible avec pgvector.</p>
<h4 id="2-gestion-des-donnees-et-controle-des-versions"><a class="heading-anchor" href="#2-gestion-des-donnees-et-controle-des-versions">2. Gestion des données et contrôle des versions</a></h4>
<p>En tant qu’ancien universitaire, je peux témoigner de l’omniprésence des feuilles de calcul classiques (le format .csv étant moins courant, mais toujours utilisé). De plus, les fichiers sont généralement stockés dans des répertoires locaux, sur un serveur privé ou dans une infrastructure partagée, mais avec une architecture de dossiers classique. On imagine aisément les frictions potentielles lorsque la conversation s’étend à plusieurs chercheurs de différents groupes. Si l’on ajoute à cela un taux de rotation naturellement élevé des étudiants, associé à une mentalité de « j’aime faire les choses à ma façon », on comprend l’importance des normes. Si les améliorations peuvent être abordées sous différents angles, je souhaiterais me concentrer sur la gestion des données et le contrôle des versions.</p>
<p>Des données bien ordonnées et une bonne hygiène organisationnelle sont des gages de réussite dans tout domaine d’études. Cependant, le suivi des modifications se limite le plus souvent, voire exclusivement, aux documents texte. Bien que cela puisse surprendre le lecteur, le terme « dépôt de code » ne fait pas partie du vocabulaire universitaire courant. Même le terme « Linux » évoque un certain « mysterium tremendum et fascinans » (Otto, 1923). La sécurité des données étant une priorité, des options d’auto-hébergement telles que <a href="https://forgejo.org/" rel="noopener">Forgejo</a> pourraient être très utiles aux scientifiques du vivant, notamment en cas de réserves quant au stockage des données en ligne. Au lieu d’avoir plusieurs brouillons de fichiers, par exemple « draft-1_final », « draft_final_final », etc., des outils comme Forgejo permettent de suivre l’avancement des documents et d’offrir aux chercheurs une plus grande transparence sur les modifications passées (ce qui facilite la collaboration entre les équipes).</p>
<h4 id="3-conformite-et-audit"><a class="heading-anchor" href="#3-conformite-et-audit">3. Conformité et audit</a></h4>
<p>La confiance est un sujet central dans tout domaine de recherche, et dans certaines circonstances, l’audit (ou toute autre forme de preuve de travail) peut occuper une place centrale. Dans le cas présent, Postgres et l’une de ses extensions associées, <a href="https://github.com/pgaudit/pgaudit" rel="noopener">pgAudit</a>, peuvent constituer une avancée significative vers la conformité. En raison des capacités de Postgres, ce service peut parfois être perçu comme intimidant et réservé aux grands projets. Je pense qu’il pourrait devenir très répandu grâce à la publication d’un guide du type « Postgres pour les petits projets ».</p>
<h4 id="decouverte-et-exposition"><a class="heading-anchor" href="#decouverte-et-exposition">Découverte et exposition</a></h4>
<p>Au final, personne n’utilisera volontairement quelque chose sans en connaître l’existence. C’est pourquoi la découvrabilité est l’un des concepts les plus fondamentaux lorsqu’on parle d’impact et d’adoptabilité. Il appartient aux mainteneurs, aux contributeurs et aux communautés derrière ces outils open source de partager leurs avancées sur plusieurs plateformes et dans différentes conférences. Honnêtement, le moyen le plus simple d’aider est d’en parler et de mettre la main à la pâte.</p>
<h3 id="2-le-cerveau-et-la-conformite-a-lacid"><a class="heading-anchor" href="#2-le-cerveau-et-la-conformite-a-lacid">2. Le cerveau et la conformité à l’ACID</a></h3>
<p><em>2. Lors de ma conférence, j’ai affirmé que le cerveau était compatible avec l’ACID. Bien que je fasse principalement référence aux potentiels d’action des neurones, cette affirmation a été contestée à juste titre.</em></p>
<p>Ce fut une autre discussion passionnante après la présentation, et même si elle mériterait un article de blog dédié, je souhaitais partager rapidement mes réflexions. Dans l’une de mes diapositives, j’ai affirmé que le cerveau est compatible avec ACID, du moins dans le sens où les transactions sont tout ou rien. Les neurones, un type cellulaire courant dans le cerveau, ont la caractéristique de recevoir des signaux qui se compilent jusqu’à atteindre un seuil, après quoi le neurone envoie son propre signal, ou « se déclenche ». C’est une simplification grossière : voici un petit lien <a href="https://en.wikipedia.org/wiki/Action_potential" rel="noopener">Wikipédia</a> pour plus d’informations.</p>
<p>Cependant, des auditeurs perspicaces ont remarqué que le cerveau est complexe et comporte différentes régions. Il peut y avoir des pertes de mémoire et des activités pouvant altérer le fonctionnement et la conscience. Cependant, dans quelle mesure les influences externes sur le cerveau sont-elles liées à un système de base de données ? Si une base de données Postgres est corrompue, elle n’est plus compatible ACID, contrairement à ce qu’elle était auparavant. Tous ces points sont à la fois valables et intéressants. Il sera intéressant d’y réfléchir et de rédiger une réponse plus formelle.</p>
<h2 id="reflexions-finales"><a class="heading-anchor" href="#reflexions-finales">Réflexions finales</a></h2>
<p>En résumé, ce fut une excellente conférence. Je sais que je parle au nom de tous les participants en remerciant tous ceux qui y ont contribué, qu’ils soient membres du personnel, bénévoles, intervenants ou autres.</p>
<h2 id="references"><a class="heading-anchor" href="#references">Références</a></h2>
<p>Foote, K. J., Grant, J. W. A., &amp; Biron, P. M. (2024). A global dataset of salmonid biomass in streams. Scientific data, 11(1), 1172. <a href="https://doi.org/10.1038/s41597-024-04026-0" rel="noopener">https://doi.org/10.1038/s41597-024-04026-0</a></p>
<p>Giordano, C., &amp; Hadjibagheri, P. (2021, December 11). UK COVID-19 dashboard built using Postgres and Citus for millions of users. Microsoft TechCommunity Blog. <a href="https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/uk-covid-19-dashboard-built-using-postgres-and-citus-for/ba-p/3039052" rel="noopener">https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/uk-covid-19-dashboard-built-using-postgres-and-citus-for/ba-p/3039052</a></p>
<p>Kazimiers, T., et al. (2021). CATMAID (Collaborative Annotation Toolkit for Massive Amounts of Image Data) [Computer software]. GitHub. <a href="https://github.com/catmaid/CATMAID" rel="noopener">https://github.com/catmaid/CATMAID</a></p>
<p>Krefl, D., &amp; Nienartowicz, K. (2025, January 17). Harnessing Postgres and HPC for petabyte-scale variable star classification in astronomy [Conference presentation]. CERN PGDay 2025, Geneva, Switzerland. <a href="https://indico.cern.ch/event/1336647/contributions/5660229/" rel="noopener">https://indico.cern.ch/event/1336647/contributions/5660229/</a></p>
<p>Otto, R. (1923). The idea of the holy: An inquiry into the non-rational factor in the idea of the divine and its relation to the rational (J. W. Harvey, Trans.). Oxford University Press. (Original work published 1917)</p>
<p>Teixeira, A. de A., &amp; PgHydro Project. (2022). pghydro (Version 6.6) [Computer software]. GitHub. <a href="https://github.com/pghydro/pghydro" rel="noopener">https://github.com/pghydro/pghydro</a></p>
<p>Wikipedia contributors. (2025, May 16). Action potential. Wikipedia, The Free Encyclopedia. <a href="https://en.wikipedia.org/wiki/Action_potential" rel="noopener">https://en.wikipedia.org/wiki/Action_potential</a></p>
 ]]></content>
			<author>
				<name>Evan Stanton</name>
			</author>
    </entry>
    <entry>
      <title>Postgres Café : Contribuer à l'Open Source</title>
      <link href="https://www.data-bene.io/fr/blog/postgres-cafe-contribuer-a-l-open-source/" />
      <updated>2025-03-04T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/postgres-cafe-contribuer-a-l-open-source/</id>
     <content type="html"><![CDATA[ <p>C’est notre sixième épisode de <a href="https://www.youtube.com/watch?v=WwaJd2c9whM" rel="noopener">Café Postgres</a>, un podcast collaboratif de <a href="https://www.data-bene.io/en/" rel="noopener">Data Bene</a> &amp; <a href="https://xata.io/" rel="noopener">Xata</a> où nous discutons de tout, des extensions PostgreSQL aux contributions de la communauté. Dans l’épisode d’aujourd’hui, Sarah Conway et Gülçin Yıldırım Jelinek recontrent Andrea Cucciniello pour discuter de la manière dont les entreprises et les particuliers peuvent contribuer aux projets open source, et des raisons pour lesquelles ils pourraient envisager de le faire.</p>
<h2 id="episode-6-developpement-dextensions-postgresql-la-communaute-et-au-dela"><a class="heading-anchor" href="#episode-6-developpement-dextensions-postgresql-la-communaute-et-au-dela">Épisode 6 : Développement d’extensions PostgreSQL, la communauté et au-delà</a></h2>
<p>À quelle fréquence les entreprises expriment-elles leur intérêt pour une contribution open source ? Il est évident que toute aide apportée profite directement aux projets open source. Mais y a-t-il des avantages pour l’entreprise qui contribue ? Quels sont les modes de contribution qu’une entreprise peut envisager ? Ce sont des questions que nous entendons souvent. Explorons donc certaines des réponses évoquées dans cet épisode à travers un bref récapitulatif.</p>
<h3 id="contribuer-aux-projets-et-aux-communautes-open-source"><a class="heading-anchor" href="#contribuer-aux-projets-et-aux-communautes-open-source">Contribuer aux projets et aux communautés open source</a></h3>
<p>Chez Data Bene, nous avons déjà quelques clients intéressés par le développement de fonctionnalités ou d’améliorations pour l’écosystème PostgreSQL.</p>
<p>Ces entreprises souhaitent corriger des bugs et ajouter de nouvelles fonctionnalités qui complètent leurs cas d’utilisation et leurs piles technologiques dans PostgreSQL, Citus Data et les technologies associées pour accomplir deux choses :</p>
<ol class="list">
<li>Pour créer les fonctionnalités dont ils ont besoin, qui sont nativement intégrées au logiciel en amont et maintenues de manière transparente par la grande communauté open source, et</li>
<li>Pour garantir que d’autres personnes ayant un cas d’utilisation similaire puissent également tirer parti de ces avantages.</li>
</ol>
<p>Les temps changent ; la seule façon pour le logiciel source de rester pertinent, utile et bénéfique pour le public mondial qui l’utilise est de bénéficier de contributions mondiales, garantissant qu’il répond toujours aux besoins réels des utilisateurs d’année en année.</p>
<h3 id="pourquoi-soutenir-des-projets-open-source"><a class="heading-anchor" href="#pourquoi-soutenir-des-projets-open-source">Pourquoi soutenir des projets open source ?</a></h3>
<p>La dépendance vis-à-vis des fournisseurs est un problème majeur dans le secteur des logiciels et des services ; contribuer aux projets open source garantit que la technologie ouvertement développée peut continuer à l’être. L’utilisation de la technologie FOSS signifie que vous évitez d’investir dans une entreprise qui pourrait fermer le code ou en restreindre l’accès, donnant ainsi à l’utilisateur final la liberté de continuer à utiliser et à développer des outils essentiels qui font partie de sa pile technologique.</p>
<p>Ce type de logiciel est également soumis à un processus de développement très visible, ce qui signifie qu’il est beaucoup plus difficile d’intégrer dans le code sous-jacent des atteintes à la vie privée, des vulnérabilités de cybersécurité, etc.</p>
<p>De plus, les logiciels open source sont créés par des individus du monde entier ayant des perspectives et des parcours variés ; cela garantit qu’ils sont minutieusement testés, et intègrent un large éventail de fonctionnalités intégrées qui sont <em>réellement utiles</em> à de nombreux utilisateurs finaux. Cela permet à ce type de projets d’être couronnés de succès pendant de nombreuses années, aussi longtemps qu’il existe une communauté prête à les soutenir.</p>
<p><em>Exemple concret : PostgreSQL existe depuis plus de 35 ans de développement actif et figure toujours aujourd’hui en tête des enquêtes et des classements des développeurs comme étant la solution de base de données la plus appréciée, la plus utilisée et la plus populaire au monde !</em></p>
<h3 id="comment-les-entreprises-peuvent-elles-soutenir-au-mieux-les-projets-open-source"><a class="heading-anchor" href="#comment-les-entreprises-peuvent-elles-soutenir-au-mieux-les-projets-open-source">Comment les entreprises peuvent-elles soutenir au mieux les projets open source ?</a></h3>
<p>Il existe quelques moyens clés pour atteindre cet objectif final :</p>
<ol class="list">
<li><strong>Incluez les contributions de code au temps de travail de vos ingénieurs.</strong> Lorsque vous allouez du temps aux développeurs pour travailler sur le code en amont, vous vous assurez que la technologie que vous exploitez (pour fournir un support et/ou des services, pour alimenter votre produit ou sur laquelle repose votre infrastructure) bénéficie de performances améliorées, de fonctionnalités étendues, de problèmes résolus ou de corrections de bugs.</li>
<li><strong>Envisagez de développer des extensions.</strong> La création et la maintenance d’extensions permettent aux entreprises d’ajouter des fonctionnalités spécialisées ou de répondre à certains cas d’utilisation sans altérer la base de code principale. Dans le cas de PostgreSQL en particulier, cette extensibilité permet à Postgres de répondre aux besoins de différents secteurs, utilisateurs et entreprises, avec un écosystème polyvalent et solide. Ce type de système modulaire permet à PostgreSQL d’évoluer sans complexifier trop son noyau, ce qui rend le projet dans son ensemble plus facile à gérer et à mettre à jour.</li>
<li><strong>Sponsorisez, organisez et participez à des événements.</strong> En tant qu’entreprise, vous pouvez choisir de promouvoir ou d’initier des conférences technologiques, des groupes d’utilisateurs, des ateliers et bien plus encore pour sensibiliser et éduquer le grand public sur la technologie que vous souhaitez voir prospérer. Les événements sont un excellent moyen pour les utilisateurs et les développeurs de collaborer, de discuter des avancées et de partager les meilleures pratiques, ce qui renforce la communauté et améliore le produit en conséquence.</li>
</ol>
<h3 id="comment-data-bene-contribue"><a class="heading-anchor" href="#comment-data-bene-contribue">Comment Data Bene contribue</a></h3>
<p>Cédric Villemain, président de Data Bene, a développé <a href="https://codeberg.org/c2main/pgfincore" rel="noopener">pg_fincore</a> et travaille actuellement sur <a href="https://codeberg.org/data-bene/statsmgr" rel="noopener">StatsMgr</a>, pg_psi et d’autres composants conçus pour améliorer les capacités statistiques de Postgres.</p>
<p>Notre équipe est également responsable d’un certain nombre de contributions dans le cadre de projets tels que <a href="https://www.citusdata.com/blog/2025/02/06/distribute-postgresql-17-with-citus-13/" rel="noopener">Citus Data</a> et <a href="https://github.com/zammad/zammad/" rel="noopener">Zammad</a>.</p>
<p>Nous nous efforçons de sponsoriser, de présenter et de promouvoir des conférences et des groupes d’utilisateurs de la communauté PostgreSQL ou open source, tels que PostgreSQL Europe, pgDay Paris, AlpOSS, Capitole du Libre, et bien d’autres. Certains membres de notre équipe ont également initié ou font partie des comités d’organisation de divers événements tels que les groupes d’utilisateurs PostgreSQL de Barcelone et de Madrid et pgDay Lowlands. L’impact des événements sur le projet et la communauté dans son ensemble ne peut être sous-estimé, et il est important pour nous d’y contribuer de cette manière.</p>
<p>Enfin, nous aidons les clients à comprendre comment contribuer à PostgreSQL et à des projets open source similaires. Par le biais de formations, d’ateliers et de collaborations, nous les encourageons à apporter des contributions significatives qui correspondent à leurs objectifs et soutiennent la communauté dans son ensemble.</p>
<p><em>Si vous êtes un développeur souhaitant contribuer à l’écosystème open source et/ou PostgreSQL, ou aider les clients avec leurs besoins en R&amp;D, notre équipe s’agrandit : rendez-nous visite sur notre <a href="https://data-bene.io/en/jobs" rel="noopener">site web</a> pour voir les postes disponibles!</em></p>
<h3 id="regardez-lepisode-complet"><a class="heading-anchor" href="#regardez-lepisode-complet">Regardez l’épisode complet</a></h3>
<p>Vous souhaitez regarder la discussion dans son intégralité ? Elle est disponible sur YouTube (en anglais uniquement) :</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/BYvXQB9O71U?si=-irKIHXxwiPhBFQP" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h3 id="restez-a-lecoute-pour-plus-doutils-postgres"><a class="heading-anchor" href="#restez-a-lecoute-pour-plus-doutils-postgres">Restez à l’écoute pour plus d’outils Postgres</a></h3>
<p>A ce jour, nous avons terminé notre première série d’épisodes pour Postgres Café ! D’autres épisodes pourraient suivre, ou pas. Suivez-nous sur les réseaux sociaux (comme <a href="https://www.linkedin.com/company/91744288" rel="noopener">LinkedIn</a> ou <a href="https://fosstodon.org/@data_bene" rel="noopener">Mastodon</a>) pour être informé des prochaines sorties. (Voulez-vous en savoir plus sur cette série de podcasts ? Faites-le nous savoir !)</p>
<p><a href="https://www.youtube.com/playlist?list=PLf7KS0svgDP_zJmby3RMzzOVO45qLbruA" rel="noopener">Abonnez-vous à la playlist</a> ou consultez-le pour des interviews sur les extensions open source comme <a href="https://codeberg.org/Data-Bene/StatsMgr" rel="noopener">StatsMgr</a> pour une gestion efficace des statistiques de PostgreSQL, ou <a href="https://youtu.be/j1R3a0-jg6c" rel="noopener">pgstream</a>, un outil open source de capture de données modifiées (CDC) conçu spécifiquement pour PostgreSQL ou bien d’autres. PostgreSQL est l’une des bases de données les plus extensibles du marché avec un vaste écosystème d’extensions ; apprenez directement des experts en découvrant certaines des options disponibles.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Postgres Café : Déployer PostgreSQL distribué à grande échelle avec Citus Data</title>
      <link href="https://www.data-bene.io/fr/blog/postgres-cafe-deployer-postgresql-distribue-a-grande-echelle-avec-citus-data/" />
      <updated>2025-01-29T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/postgres-cafe-deployer-postgresql-distribue-a-grande-echelle-avec-citus-data/</id>
     <content type="html"><![CDATA[ <p>C’est l’heure du quatrième épisode de <a href="https://www.youtube.com/watch?v=WwaJd2c9whM" rel="noopener">Café Postgres</a>, un podcast de nos équipes de <a href="https://www.data-bene.io/en/" rel="noopener">Data Bene</a> et <a href="https://xata.io/" rel="noopener">Xata</a> où nous discutons de la contribution à PostgreSQL et du développement d’extensions. Dans ce dernier épisode, Sarah Conway et Gülçin Yıldırım Jelinek rencontrent Stéphane Carton pour parler de <a href="https://github.com/citusdata/citus" rel="noopener">Citus Data</a>, une extension entièrement open source de Microsoft qui permet de déployer PostgreSQL distribué à grande échelle.</p>
<h2 id="episode-4-citus-data"><a class="heading-anchor" href="#episode-4-citus-data">Épisode 4 : Citus Data</a></h2>
<p>La base de données Citus a connu 127 versions depuis le 24 mars 2016, date à laquelle elle est passée pour la première fois gratuite et open source pour son utilisation et ses contributions. Il s’agit d’un outil puissant qui fonctionne nativement avec PostgreSQL et s’intègre de manière transparente à tous les outils et extensions Postgres. Voici un résumé des points abordés dans cet épisode de podcast !</p>
<h3 id="repondre-aux-problematiques-devolutivite-de-performance-et-de-gestion-des-grands-jeux-de-donnees"><a class="heading-anchor" href="#repondre-aux-problematiques-devolutivite-de-performance-et-de-gestion-des-grands-jeux-de-donnees">Répondre aux problématiques d’évolutivité, de performance et de gestion des grands jeux de données</a></h3>
<p>Pourquoi Citus Data existe-t-il et quels problèmes résout-il ? Examinons cela par catégorie.</p>
<h4 id="developpement"><a class="heading-anchor" href="#developpement">Développement</a></h4>
<p>Citus est conçu pour résoudre le problème de la modélisation des données distribuées en fournissant des méthodes de cartographie de la charge de travail dans les modèles de données distribuées, telles que des tables de partitionnement basées sur des clés primaires (particulièrement utiles pour les microservices et les charges de travail à haut débit).</p>
<h4 id="evolutivite"><a class="heading-anchor" href="#evolutivite">Évolutivité</a></h4>
<p>En distribuant les données sur plusieurs nœuds, vous pouvez activer la mise à l’échelle horizontale des bases de données PostgreSQL.</p>
<p>Cela permet aux développeurs de combiner les capacités des processeurs, de mémoire, de stockage et des E/S de plusieurs machines pour gérer de grands ensembles de données et des charges de travail à trafic élevé. Il est possible d’ajouter facilement davantage de nœuds au cluster et de rééquilibrer les partitions au fur et à mesure que votre volume de données augmente.</p>
<h4 id="performance"><a class="heading-anchor" href="#performance">Performance</a></h4>
<p>Le moteur de requêtes distribué de Citus est utilisé pour maximiser l’efficacité, en parallélisant les requêtes et en regroupant l’exécution de plusieurs nœuds de travail.</p>
<p>Même lorsque des milliers, voire des millions d’instructions sont exécutées par seconde, l’ingestion de données est toujours optimisée via la récupération des bonnes partitions, la connexion aux nœuds appropriés et la parallélisation de certaines opérations. Tout cela garantit un débit élevé et une latence faible lors du traitement des données en temps réel.</p>
<h4 id="haute-disponibilite-et-redondance"><a class="heading-anchor" href="#haute-disponibilite-et-redondance">Haute disponibilité et redondance</a></h4>
<p>Grâce au modèle de données distribué, vous pouvez créer des copies redondantes des tables et des partitions sur plusieurs nœuds. Cela permet de garantir que la base de données reste résiliente et disponible même en cas de panne de nœuds, et maintenir ainsi une haute disponibilité.</p>
<h3 id="contribution-a-citus"><a class="heading-anchor" href="#contribution-a-citus">Contribution à Citus</a></h3>
<p>Chez Data Bene, notre objectif est de soutenir la dynamique du code source grâce au développement continu et aux contributions au code. Cédric Villemain, entre autres membres de notre équipe, évalue constamment de nouveaux ajouts de fonctionnalités ou autres améliorations qui peuvent faire une différence pour les utilisateurs.</p>
<p>Que vous fassiez partie d’une équipe DevOps qui cherche à créer une architecture distribuée pour vos instances PostgreSQL, ou que vous soyez un utilisateur final tel qu’un analyste commercial qui recherche des performances efficaces lors du traitement de grandes quantités de données, Citus Data peut être le meilleur choix.</p>
<p>Si vous avez des demandes ou des intérêts particuliers en matière de fonctionnalités, notre équipe de Data Bene vous aidera à contribuer directement à Citus Data ou pourra le faire en votre nom pour garantir la longévité du projet Citus et sa pertinence pour vos projets. Apprenez-en davantage sur la contribution à Citus Data en vous référant au dépôt officiel <a href="https://github.com/citusdata/citus/blob/main/CONTRIBUTING.md" rel="noopener">CONTRIBUTING.md</a>.</p>
<h3 id="regardez-lepisode-complet"><a class="heading-anchor" href="#regardez-lepisode-complet">Regardez l’épisode complet</a></h3>
<p>Vous envisagez de regarder la discussion complète ? Découvrez-le sur YouTube :</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/WueRn76nJ9Q?si=ulvzvfcr4Ux17tt0" title="Lecteur vidéo YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
<h3 id="decouvrez-dautres-outils-postgres"><a class="heading-anchor" href="#decouvrez-dautres-outils-postgres">Découvrez d’autres outils Postgres</a></h3>
<p>D’autres épisodes sont en cours de publication au Postgres Café ! <a href="https://www.youtube.com/playlist?list=PLf7KS0svgDP_zJmby3RMzzOVO45qLbruA" rel="noopener">Abonnez-vous à la playlist</a> pour plus d’interviews sur des outils open source comme <a href="https://codeberg.org/Data-Bene/StatsMgr" rel="noopener">StatsMgr</a> pour une gestion efficace des statistiques PostgreSQL, <a href="https://github.com/xataio/pgzx" rel="noopener">pgzx</a> pour la création d’extensions PostgreSQL à l’aide de Zig, etc. Laissez les experts vous présenter de nouvelles extensions à essayer pour optimiser vos déploiements Postgres.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Postgres Café : Développez vos capacités de surveillance avec StatsMgr</title>
      <link href="https://www.data-bene.io/fr/blog/postgres-cafe-developpez-vos-capacities-de-surveillance-avec-statsmgr/" />
      <updated>2025-01-07T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/postgres-cafe-developpez-vos-capacities-de-surveillance-avec-statsmgr/</id>
     <content type="html"><![CDATA[ <p>L’année 2025 a commencé et nous sommes ravis de publier le deuxième épisode de <a href="https://www.youtube.com/watch?v=WwaJd2c9whM" rel="noopener">Postgres Café</a>, une série de blogs et de vidéos de nos équipes chez <a href="https://www.data-bene.io/fr/" rel="noopener">Data Bene</a> et <a href="https://xata.io/" rel="noopener">Xata</a>, réalisée dans le but d’explorer le monde de l’open source et de découvrir ses liens avec l’extensibilité de PostgreSQL. Tout au long de cette série, nous discutons de différentes extensions et des outils qui facilitent la vie des développeurs lorsqu’ils travaillent avec PostgreSQL. Dans notre deuxième épisode, nous explorons une toute nouvelle extension PostgreSQL appelée <a href="https://codeberg.org/data-bene/statsmgr" rel="noopener">StatsMgr</a> qui exploite les processus en tâche de fond (background workers) et la mémoire partagée pour capturer, gérer et interroger diverses statistiques pour WAL, SLRU, IO, checkpointing, etc.</p>
<h2 id="episode-2-statsmgr"><a class="heading-anchor" href="#episode-2-statsmgr"><strong>Épisode 2: StatsMgr</strong></a></h2>
<p>Dans cet épisode nous présentons l’extension open source StatsMgr, récemment publiée, créée pour surveiller et suivre en continu les événements sur PostgreSQL et le système sous-jacent. Voici un aperçu de ce que cet épisode a couvert :</p>
<h3 id="traitement-personnalise-des-metriques"><a class="heading-anchor" href="#traitement-personnalise-des-metriques"><strong>Traitement personnalisé des métriques</strong></a></h3>
<p>À l’origine, l’idée était de fournir une interface simplifiée pour les métriques, tout en les enrichissant avec une grande variété de types disponibles. Cette fonctionnalité a ensuite été étendue pour résoudre des problèmes tels que :</p>
<ul class="list">
<li><strong>Rendre les statistiques disponibles</strong> pour la collecte à partir de systèmes externes, sans interruption même lorsque ces systèmes externes sont en panne.</li>
<li><strong>Fournir une vue immédiate des statistiques PostgreSQL</strong> avec suivi historique, y compris les vues et fonctions pg_stat.</li>
<li><strong>Augmenter et réduire la quantité d’enregistrements historiques</strong> en cas de besoin grâce à l’allocation de mémoire tampon dynamique.</li>
<li><strong>Déboguer des instances PostgreSQL</strong> avec analyse historique et sans redémarrages requis.</li>
</ul>
<p>Cette extension est aussi très bien pour gérer des situations telles que lorsque…</p>
<ul class="list">
<li><strong>…votre agent de surveillance est en panne</strong> ; l’utilisation de StatsMgr comme sauvegarde vous permet de vous assurer que vous ne perdrez pas de statistiques dans cet événement, car les événements sont capturés indépendamment et stockés pour être collectés ultérieurement par votre agent de surveillance.</li>
<li><strong>…vous avez des pics ou un comportement inhabituel sur votre système de production.</strong> Cette extension vous permet d’obtenir un aperçu de l’activité pour des informations de débogage utiles.</li>
</ul>
<h3 id="collection-etendue-et-historique-de-mesures"><a class="heading-anchor" href="#collection-etendue-et-historique-de-mesures"><strong>Collection étendue et historique de mesures</strong></a></h3>
<p>Actuellement, les types de statistiques pris en charge incluent :</p>
<ul class="list">
<li>WAL</li>
<li>SLRU</li>
<li>BGWriter</li>
<li>Checkpointer</li>
<li>Archiver</li>
<li>IO</li>
</ul>
<p>Chacun est enregistré auprès d’un gestionnaire qui vous permet de récupérer et de gérer ces statistiques, et est également accompagné de structures de mémoire partagée pour stocker des instantanés historiques.</p>
<p>Certaines des prochaines étapes du projet comprendront l’ajout de statistiques dynamiques telles que pg_stat_user_tables, entre autres.</p>
<p>Il reste encore beaucoup de choses à faire, des améliorations subtiles aux nouvelles fonctionnalités majeures. Il existe donc bien sûr de nombreuses opportunités de contribuer au projet, que vous soyez un nouveau venu ou un développeur PostgreSQL confirmé. Vous souhaitez participer à l’effort ? Consultez <a href="https://codeberg.org/Data-Bene/StatsMgr/src/branch/main/CONTRIBUTING.md" rel="noopener">CONTRIBUTING.md</a> dans le projet.</p>
<h3 id="regardez-lepisode-complet"><a class="heading-anchor" href="#regardez-lepisode-complet"><strong>Regardez l’épisode complet</strong></a></h3>
<p>Pour une exploration approfondie de StatsMgr et de ses capacités, regardez l’épisode complet ici :</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/UMzCLFwCPI8?si=_ZCEoWYtFW_UCKXm" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h3 id="restez-a-lecoute-pour-plus-doutils-postgres"><a class="heading-anchor" href="#restez-a-lecoute-pour-plus-doutils-postgres"><strong>Restez à l’écoute pour plus d’outils Postgres</strong></a></h3>
<p>Il y a encore beaucoup à venir sur Postgres Café. <a href="https://www.youtube.com/playlist?list=PLf7KS0svgDP_zJmby3RMzzOVO45qLbruA" rel="noopener">Abonnez-vous à la playlist</a> pour découvrir des épisodes qui présentent d’autres outils open source comme <a href="https://pgroll.com/" rel="noopener">pgroll</a> pour les migrations de schémas sans interruption de service, ou <a href="https://www.citusdata.com/" rel="noopener">Citus Data</a> une extension pour des bases PostgreSQL distribuées et évolutives, et bien plus encore. Restez en contact pour découvrir comment chaque outil peut rendre le travail avec Postgres plus fluide et plus efficace.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Transformations inattendues des types de données</title>
      <link href="https://www.data-bene.io/fr/blog/transformations-inattendues-de-types-de-donn%C3%A9es/" />
      <updated>2024-12-02T00:00:00Z</updated>
      <id>https://www.data-bene.io/fr/blog/transformations-inattendues-de-types-de-donn%C3%A9es/</id>
     <content type="html"><![CDATA[ <h2 id="les-types-de-donnees-de-votre-fonction-ont-change-et-vous-navez-pas-ete-informes"><a class="heading-anchor" href="#les-types-de-donnees-de-votre-fonction-ont-change-et-vous-navez-pas-ete-informes">Les types de données de votre fonction ont changé et vous n’avez pas été informés</a></h2>
<p>Cet article est le résultat d’une revue de code demandée par l’un de nos clients.</p>
<p>Notre client a exécuté la commande <code>pg_dump --schema-only</code> pour nous fournir<br>
les définitions des objets de niveau <code>database</code> ainsi que le code PLpgsql à auditer.<br>
Jusque là, tout allait bien.</p>
<p>J’ai commencé à lire le code et tout d’un coup je fus pris d’un doute, vous savez<br>
le méchant doute qui vous donne l’impression que votre château de cartes va s’écrouler.<br>
Voici la fonction que j’avais sous les yeux:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> xxx<span class="token punctuation">(</span> p_id <span class="token keyword">character</span><span class="token punctuation">,</span> p_info <span class="token keyword">character</span> <span class="token keyword">varying</span> <span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> <span class="token keyword">integer</span>
<span class="token keyword">LANGUAGE</span> plpgsql
<span class="token keyword">AS</span> $$
<span class="token keyword">DECLARE</span>
<span class="token keyword">BEGIN</span>
   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
   <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> t1
   <span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> t2 <span class="token keyword">WHERE</span> t2<span class="token punctuation">.</span>id <span class="token operator">=</span> p_id<span class="token punctuation">;</span>
   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">END</span><span class="token punctuation">;</span>
$$
<span class="token punctuation">;</span></code></pre>
<p>Peut-être que la première lecture de la fonction ne vous a pas choqué.<br>
Et si je vous disais que la définition de la table <code>t2</code> ressemble à ce qui suit:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> t2 <span class="token punctuation">(</span>
   id <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">130</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span>
   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
   <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span>id<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>En pratique <code>t2.id</code> est toujours une chaîne de 130 caractères et il y a 400<br>
millions de tuples dans cette table. Comme vous l’avez déjà probablement compris,<br>
il semble étonnant d’avoir <code>p_id CHARACTER</code> pour manipuler <code>id VARCHAR(130)</code>. Pour<br>
mémoire, <code>CHARACTER</code> est l’alias de <code>CHAR(1)</code>.</p>
<p>Notre client utilise cette fonction depuis plusieurs années et il n’a pas eu de<br>
problème avec ce code. Néanmoins, notre client m’a dit que la définition de cette<br>
fonction ne correspond pas à ce qu’il a écrit: c’était <code>p_id CHARACTER(130)</code> et<br>
non <code>CHARACTER</code>.</p>
<p>Mais que s’est-il donc passé ? Attaquons la pelotte de laine et voyons si Ariane<br>
nous est d’un grand secours.</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span> c <span class="token keyword">character</span><span class="token punctuation">,</span> d <span class="token keyword">character</span> <span class="token keyword">varying</span> <span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> void
<span class="token keyword">LANGUAGE</span> plpgsql
<span class="token keyword">AS</span> $$
<span class="token keyword">BEGIN</span>
  RAISE NOTICE <span class="token string">'c=%, d=%'</span><span class="token punctuation">,</span> c<span class="token punctuation">,</span>d<span class="token punctuation">;</span>
<span class="token keyword">END</span><span class="token punctuation">;</span>
$$<span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123465789'</span><span class="token punctuation">,</span> <span class="token string">'987654321'</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  c<span class="token operator">=</span><span class="token number">123465789</span><span class="token punctuation">,</span> d<span class="token operator">=</span><span class="token number">987654321</span>
 test 
<span class="token comment">------</span>
 
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span></code></pre>
<p>Voilà un résultat bien intéressant: la chaîne ‘123456789’ n’a pas été réduite à<br>
‘1’ (pas de CAST <code>CHAR(1)</code>). Augmentons le niveau de détails:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">EXPLAIN</span> <span class="token punctuation">(</span>COSTS <span class="token keyword">OFF</span><span class="token punctuation">,</span><span class="token keyword">ANALYZE</span><span class="token punctuation">,</span>VERBOSE<span class="token punctuation">)</span>
        <span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123465789'</span><span class="token punctuation">,</span> <span class="token string">'987654321'</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  c<span class="token operator">=</span><span class="token number">123465789</span><span class="token punctuation">,</span> d<span class="token operator">=</span><span class="token number">987654321</span>
                             QUERY <span class="token keyword">PLAN</span>                              
<span class="token comment">---------------------------------------------------------------------</span>
 Result <span class="token punctuation">(</span>actual <span class="token keyword">time</span><span class="token operator">=</span><span class="token number">0.040</span><span class="token punctuation">.</span><span class="token number">.0</span><span class="token number">.041</span> <span class="token keyword">rows</span><span class="token operator">=</span><span class="token number">1</span> loops<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">)</span>
   Output: test<span class="token punctuation">(</span><span class="token string">'123465789'</span>::bpchar<span class="token punctuation">,</span> <span class="token string">'987654321'</span>::<span class="token keyword">character</span> <span class="token keyword">varying</span><span class="token punctuation">)</span>
 Planning <span class="token keyword">Time</span>: <span class="token number">0.023</span> ms
 Execution <span class="token keyword">Time</span>: <span class="token number">0.053</span> ms
<span class="token punctuation">(</span><span class="token number">4</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>Nous observons un CAST vers <code>bpchar</code>. Pour mémoire, <code>BPCHAR</code> représente une<br>
chaîne pouvant contenir 10 485 760 caractères. Il est aussi un alias de<br>
<code>CHARACTER</code> ce qui explique partiellement le passage de <code>CHARACTER</code> à <code>BPCHAR</code>.</p>
<p>Explorons une autre facette du problème:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span>c <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>
<span class="token keyword">LANGUAGE</span> <span class="token keyword">sql</span>
<span class="token keyword">AS</span> $$
<span class="token keyword">select</span> c<span class="token punctuation">;</span>
$$<span class="token punctuation">;</span></code></pre>
<p>Nous avons changé le langage de la fonction pour savoir si le comportement observé<br>
est propre à PLpgsql. Les données en entrée et en sortie sont de type <code>CHAR(4)</code>.<br>
Comment cela va-t-il se comporter ?</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">SELECT</span> test<span class="token punctuation">(</span><span class="token string">'123456789'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   test    
<span class="token comment">-----------</span>
 <span class="token number">123456789</span>
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span>

<span class="token keyword">EXPLAIN</span> VERBOSE <span class="token keyword">SELECT</span> test<span class="token punctuation">(</span><span class="token string">'123456789'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                QUERY <span class="token keyword">PLAN</span>                 
<span class="token comment">-------------------------------------------</span>
 Result  <span class="token punctuation">(</span>cost<span class="token operator">=</span><span class="token number">0.00</span><span class="token punctuation">.</span><span class="token number">.0</span><span class="token number">.01</span> <span class="token keyword">rows</span><span class="token operator">=</span><span class="token number">1</span> width<span class="token operator">=</span><span class="token number">32</span><span class="token punctuation">)</span>
   Output: <span class="token string">'123456789'</span>::bpchar
<span class="token punctuation">(</span><span class="token number">2</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>La bonne nouvelle (si si) c’est que le comportement observé est le même dans<br>
les deux contextes. En revanche, alors que l’on s’attend à manipuler des données<br>
de type <code>CHAR(4)</code>, la fonction manipule des données de taille arbitraire (limitée<br>
à ~10M caractères) !!</p>
<p>Cependant, ne vous précipitez pas dans la mailing list de PostgreSQL pour vous plaindre !</p>
<p>En fait, ce comportement n’est pas un bug. La <a href="https://www.postgresql.org/docs/current/sql-createfunction.html" rel="noopener">documentation</a> affirme:</p>
<blockquote>
<p>“The full SQL type syntax is allowed for declaring a function’s arguments and return value. However, parenthesized type modifiers (e.g., the precision field for type numeric) are discarded by CREATE FUNCTION. Thus for example CREATE FUNCTION foo (varchar(10)) … is exactly the same as CREATE FUNCTION foo (varchar) …”</p>
</blockquote>
<p>Ceci explique que <code>CHARACTER(x)</code> devient <code>CHARACTER</code> transformé (par aliasing)<br>
en <code>BPCHAR</code> qui n’est pas <code>CHAR(1)</code> mais plutôt <code>VARCHAR(10485760)</code>. Le<br>
comportement est maintenant complétement expliqué.</p>
<p>Attendez une seconde ! L’intention était de traiter des données <code>CHAR(4)</code> pas<br>
de taille différente.</p>
<p>N’y a-t-il pas de solution ? Non, désolé… (à mois que…)</p>
<p>Plus loin dans la page de la documentation référencée ci-dessus, on peut lire<br>
que <code>argtype</code> et <code>rettype</code> peuvent être de type <code>base</code>, <code>composite</code>, <code>domain</code><br>
ou même du type d’une table/colonne.</p>
<p>L’astuce est de créer un type <code>composite</code> ou un <code>domain</code> a utiliser en tant que<br>
<code>argtype</code> et/ou <code>rettype</code>.</p>
<p>Voici quelques exemples:</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Works in simple case trick</span>
<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'12345789'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">-- Domain trick</span>
<span class="token keyword">CREATE</span> DOMAIN c4 <span class="token keyword">AS</span> <span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span>param c4<span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> c4
<span class="token keyword">AS</span> $$
<span class="token keyword">BEGIN</span>
  RAISE NOTICE <span class="token string">'param=%'</span><span class="token punctuation">,</span> param<span class="token punctuation">;</span>
  <span class="token keyword">RETURN</span> param<span class="token punctuation">;</span>
<span class="token keyword">END</span><span class="token punctuation">;</span>
$$ <span class="token keyword">LANGUAGE</span> plpgsql<span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
ERROR:  <span class="token keyword">value</span> too long <span class="token keyword">for</span> <span class="token keyword">type</span> <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  param<span class="token operator">=</span><span class="token number">1234</span>
 test 
<span class="token comment">------</span>
 <span class="token number">1234</span>
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span>::c4<span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  param<span class="token operator">=</span><span class="token number">1234</span>
 test 
<span class="token comment">------</span>
 <span class="token number">1234</span>
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> pg_typeof<span class="token punctuation">(</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  param<span class="token operator">=</span><span class="token number">1234</span>
 pg_typeof 
<span class="token comment">-----------</span>
 c4
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span></code></pre>
<p>Le résultat obtenu devrait vous satisfaire.</p>
<p>Vous n’êtes pas satisfait ?</p>
<p>Je vous propose une dernière astuce.</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Map a table structure</span>
<span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> qq <span class="token punctuation">(</span> c <span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span><span class="token operator">IN</span> c qq<span class="token punctuation">,</span> <span class="token keyword">OUT</span> d qq<span class="token punctuation">)</span>
<span class="token keyword">LANGUAGE</span> <span class="token keyword">sql</span>
<span class="token keyword">AS</span> $$
<span class="token keyword">SELECT</span> c<span class="token punctuation">;</span>
$$<span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> test<span class="token punctuation">(</span><span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
ERROR:  <span class="token keyword">value</span> too long <span class="token keyword">for</span> <span class="token keyword">type</span> <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">from</span> test<span class="token punctuation">(</span><span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'1234'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  c   
<span class="token comment">------</span>
 <span class="token number">1234</span></code></pre>
<p>Hmm, d’accord mais en quoi est-ce différent de l’utilisation d’un <code>domain</code> ?</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Easy Type Alteration</span>
<span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span> qq <span class="token keyword">ALTER</span> c <span class="token keyword">TYPE</span> <span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> test<span class="token punctuation">(</span> <span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
   c   
<span class="token comment">-------</span>
 <span class="token number">12345</span></code></pre>
<p>Essayer de modifier un <code>domain</code>, vous verrez comme c’est simple et pas impactant (…).</p>
<p>L’astuce basée sur la définition de table permet de la flexibilité:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span> qq <span class="token keyword">ADD</span> ee <span class="token keyword">int</span><span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
   test   
<span class="token comment">----------</span>
 <span class="token punctuation">(</span><span class="token number">12345</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> test<span class="token punctuation">(</span> <span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
   c   <span class="token operator">|</span> ee 
<span class="token comment">-------+----</span>
 <span class="token number">12345</span> <span class="token operator">|</span>  <span class="token number">4</span></code></pre>
<p>Nous espérons que vous avez apprécié cet article et que vous avez appris quelque chose de nouveau et d’intéressant.</p>
 ]]></content>
			<author>
				<name>Frédéric Delacourt</name>
			</author>
    </entry>
</feed>
