{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Data Bene - Tag: 'Planete'",
  "language": "fr",
  "home_page_url": "https://www.data-bene.io/fr/",
  "feed_url": "https://www.data-bene.io/fr/blog/tag/planete/feed.json",
  "description": "Base de données relationnelles, open-source et adaptives.",
  "items": [{
      "id": "https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/",
      "url": "https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/",
      "title": "Le saviez-vous ? Les tables dans PostgreSQL sont limitées à 1600 colonnes",
      "content_html": "\n<html><head></head><body><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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#tout-dabord-la-documentation\" class=\"heading-anchor\">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\n#define MaxHeapAttributeNumber\t1600</code></pre><h2 id=\"atteindre-la-limite-de-maniere-classique\"><a href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#atteindre-la-limite-de-maniere-classique\" class=\"heading-anchor\">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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#jouer-avec-la-definition-de-la-table\" class=\"heading-anchor\">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>\n\n<span class=\"token keyword\">DO</span> $$\n<span class=\"token keyword\">DECLARE</span>\n    i <span class=\"token keyword\">int</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">BEGIN</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'DROP TABLE IF EXISTS tint_1601;'</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'CREATE TABLE tint_1601(i_1 int);'</span><span class=\"token punctuation\">;</span>\n    <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>\n        <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>\n    <span class=\"token keyword\">END</span> <span class=\"token keyword\">LOOP</span><span class=\"token punctuation\">;</span>\n<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\nERROR:  tables can have at most 1600 columns\nCONTEXT:  SQL statement \"ALTER TABLE tint_1600 ADD COLUMN i_1601 int;\"\nPL/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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#jouer-avec-le-contenu-dune-table\" class=\"heading-anchor\">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> $$\n<span class=\"token keyword\">DECLARE</span>\n    i <span class=\"token keyword\">int</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">BEGIN</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'DROP TABLE IF EXISTS tint_1600;'</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'CREATE TABLE tint_1600(i_1 int);'</span><span class=\"token punctuation\">;</span>\n    <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>\n        <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>\n    <span class=\"token keyword\">END</span> <span class=\"token keyword\">LOOP</span><span class=\"token punctuation\">;</span>\n<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> $$\n<span class=\"token keyword\">DECLARE</span>\n    s <span class=\"token keyword\">TEXT</span><span class=\"token punctuation\">;</span>\n    rows_inserted <span class=\"token keyword\">int</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">BEGIN</span>\n    s :<span class=\"token operator\">=</span> <span class=\"token function\">format</span><span class=\"token punctuation\">(</span>\n                 <span class=\"token string\">'INSERT INTO tint_1600 VALUES (1%s);'</span>\n               <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>\n               <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">EXECUTE</span> s<span class=\"token punctuation\">;</span>\n\n    GET DIAGNOSTICS rows_inserted <span class=\"token operator\">=</span> ROW_COUNT<span class=\"token punctuation\">;</span>\n    RAISE NOTICE <span class=\"token string\">'Rows inserted: %'</span><span class=\"token punctuation\">,</span> rows_inserted<span class=\"token punctuation\">;</span>\n<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\nDO</code></pre><p>Sans surprise, c’est encore un succès.</p><h3 id=\"trop-gros-pour-echouer\"><a href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#trop-gros-pour-echouer\" class=\"heading-anchor\">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>\n<span class=\"token keyword\">DO</span> $$\n<span class=\"token keyword\">DECLARE</span>\n    i <span class=\"token keyword\">int</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">BEGIN</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'DROP TABLE IF EXISTS tint_1600;'</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'CREATE TABLE tint_1600(i_1 int);'</span><span class=\"token punctuation\">;</span>\n    <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>\n        <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>\n    <span class=\"token keyword\">END</span> <span class=\"token keyword\">LOOP</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">END</span> $$<span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">-- Insert a tuple - 1 x int + 1599 x char(127)</span>\n<span class=\"token keyword\">DO</span> $$\n<span class=\"token keyword\">DECLARE</span>\n    s <span class=\"token keyword\">TEXT</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">BEGIN</span>\n    s :<span class=\"token operator\">=</span> <span class=\"token function\">format</span><span class=\"token punctuation\">(</span>\n                 <span class=\"token string\">'INSERT INTO tint_1600 VALUES (1%s);'</span>\n               <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>\n               <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">EXECUTE</span> s<span class=\"token punctuation\">;</span>\n<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>\n\nLe 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\">\nComme 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.\n\n## Quid des JOINs ?\n\nPour simplifier, testons avec une jointure automatique :\n\n```sql\nSELECT a.*,b.* FROM tint_1600 a, tint_1600 b;\nERROR:  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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#atteindre-la-limite-de-colonnes-de-maniere-inattendue\" class=\"heading-anchor\">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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#explorer-add-/-drop-column\" class=\"heading-anchor\">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>\n\n<span class=\"token keyword\">CREATE</span> <span class=\"token keyword\">TABLE</span>\n\n<span class=\"token operator\">=</span><span class=\"token comment\"># ALTER TABLE tadc_1600 ADD COLUMN i_2 int NOT NULL;</span>\n\n<span class=\"token keyword\">ALTER</span> <span class=\"token keyword\">TABLE</span>\n\n<span class=\"token operator\">=</span><span class=\"token comment\"># SELECT attname,attnum,attstorage,attnotnull,attisdropped</span>\n   <span class=\"token keyword\">FROM</span> pg_attribute\n   <span class=\"token keyword\">WHERE</span> attrelid<span class=\"token operator\">=</span><span class=\"token punctuation\">(</span>\n                   <span class=\"token keyword\">SELECT</span> oid\n                   <span class=\"token keyword\">FROM</span> pg_class\n                   <span class=\"token keyword\">WHERE</span> relname<span class=\"token operator\">=</span><span class=\"token string\">'tadc_1600'</span>\n                   <span class=\"token punctuation\">)</span>\n     <span class=\"token operator\">AND</span> attnum <span class=\"token operator\">&gt;</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>\n\n 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\n<span class=\"token comment\">---------+--------+------------+------------+--------------</span>\n 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\n 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\n<span class=\"token punctuation\">(</span><span class=\"token number\">2</span> <span class=\"token keyword\">rows</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token operator\">=</span><span class=\"token comment\"># ALTER TABLE tadc_1600 DROP COLUMN i_2;</span>\n\n<span class=\"token keyword\">ALTER</span> <span class=\"token keyword\">TABLE</span>\n\n<span class=\"token operator\">=</span><span class=\"token comment\"># SELECT attname,attnum,attstorage,attnotnull,attisdropped</span>\n   <span class=\"token keyword\">FROM</span> pg_attribute\n   <span class=\"token keyword\">WHERE</span> attrelid<span class=\"token operator\">=</span><span class=\"token punctuation\">(</span>\n                   <span class=\"token keyword\">SELECT</span> oid\n                   <span class=\"token keyword\">FROM</span> pg_class\n                   <span class=\"token keyword\">WHERE</span> relname<span class=\"token operator\">=</span><span class=\"token string\">'tadc_1600'</span>\n                   <span class=\"token punctuation\">)</span>\n     <span class=\"token operator\">AND</span> attnum <span class=\"token operator\">&gt;</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>\n\n           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\n<span class=\"token comment\">------------------------------+--------+------------+------------+--------------</span>\n 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\n <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\n<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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#iterer-sur-lajout/la-suppression-de-colonnes\" class=\"heading-anchor\">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>\n<span class=\"token keyword\">DO</span> $$\n<span class=\"token keyword\">DECLARE</span>\n    i <span class=\"token keyword\">int</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">BEGIN</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'DROP TABLE IF EXISTS tadc;'</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">EXECUTE</span> <span class=\"token string\">'CREATE TABLE tadc(i_1 int);'</span><span class=\"token punctuation\">;</span>\n    <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>\n        <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>\n        <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>\n    <span class=\"token keyword\">END</span> <span class=\"token keyword\">LOOP</span><span class=\"token punctuation\">;</span>\n<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\nCONTEXT:  SQL statement \"ALTER TABLE tadc ADD COLUMN i_1601 int;\"\nPL/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>\n   <span class=\"token keyword\">FROM</span> pg_attribute\n   <span class=\"token keyword\">WHERE</span> attrelid<span class=\"token operator\">=</span><span class=\"token punctuation\">(</span>\n                   <span class=\"token keyword\">SELECT</span> oid\n                   <span class=\"token keyword\">FROM</span> pg_class\n                   <span class=\"token keyword\">WHERE</span> relname<span class=\"token operator\">=</span><span class=\"token string\">'tadc'</span>\n                   <span class=\"token punctuation\">)</span>\n     <span class=\"token operator\">AND</span> attnum <span class=\"token operator\">&gt;</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>\n\n             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\n<span class=\"token comment\">---------------------------------+--------+------------+------------+--------------</span>\n 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\n <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\n <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\n <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\n <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\n\n <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\n <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\n<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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#le-chevalier-du-vacuum-devrait-sauver-la-princesse-postgresql-non\" class=\"heading-anchor\">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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#donc-le-dragon-a-mange-le-chevalier-que-fait-on\" class=\"heading-anchor\">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 href=\"https://www.data-bene.io/fr/blog/le-saviez-vous-les-tables-dans-postgresql-sont-limitees-a-1600-colonnes/#contactez-nous\" class=\"heading-anchor\">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></body></html>\n",
      "date_published": "2025-11-13T00:00:00Z"
    }
    
  ]
}
