{"id":10505,"date":"2024-04-03T14:11:08","date_gmt":"2024-04-03T13:11:08","guid":{"rendered":"https:\/\/blog.capdata.fr\/?p=10505"},"modified":"2024-04-03T14:11:08","modified_gmt":"2024-04-03T13:11:08","slug":"pg_recursively_delete-simplifier-les-suppressions-recursives","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/","title":{"rendered":"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10505&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10505&#038;title=pg_recursively_delete%20%3A%20Simplifier%20les%20suppressions%20r%C3%A9cursives\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=pg_recursively_delete%20%3A%20Simplifier%20les%20suppressions%20r%C3%A9cursives&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10505\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p>Si vous avez \u00e9t\u00e9 amen\u00e9 au fil de votre carri\u00e8re \u00e0 manipuler de gros volumes de donn\u00e9es contenus dans plusieurs tables poss\u00e9dant des r\u00e9f\u00e9rences crois\u00e9es entre elles, d\u00e9pendantes d&#8217;autres tables, qui elles-m\u00eames d\u00e9pendent d&#8217;autres tables, vous savez \u00e0 quel point il peut \u00eatre compliqu\u00e9 de remonter l&#8217;int\u00e9gralit\u00e9 de l&#8217;arbre de d\u00e9pendance pour supprimer la moindre ligne. Cela peut \u00eatre long et fastidieux.<\/p>\n<p>Vous ne savez pas vraiment ce que vous supprimez, dans quelles tables, et quels impacts cela peut avoir sur votre base de donn\u00e9es. Si les d\u00e9pendances sont nombreuses, il est d&#8217;autant plus compliqu\u00e9 de tout retracer et d&#8217;\u00eatre s\u00fbr \u00e0 100 % de ce que votre DELETE va entra\u00eener.<\/p>\n<p>Dans cet article, je vais vous pr\u00e9senter rapidement un petit outil sous la forme d&#8217;une extension que je trouve pratique \u00e0 utiliser dans ce cas de figure. L&#8217;outil s&#8217;appelle pg_recursively_delete, et il permet de tracer avant d&#8217;ex\u00e9cuter l&#8217;ordre de suppression de votre ligne, et d&#8217;avoir une arborescence des diff\u00e9rentes donn\u00e9es que vous allez impacter.<\/p>\n<h2>Installation d&#8217;un moteur et de l&#8217;extension :<\/h2>\n<p>Pour cet article, j&#8217;ai choisi d&#8217;utiliser PostgreSQL en version 16 pour tester si l&#8217;extension fonctionnait toujours.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">root:~#sudo apt update &amp;amp;&amp;amp; sudo apt upgrade\r\nroot:~#sudo sh -c 'echo &quot;deb http:\/\/apt.postgresql.org\/pub\/repos\/apt $(lsb_release -cs)-pgdg main&quot; &amp;gt; \/etc\/apt\/sources.list.d\/pgdg.list'\r\nroot:~#wget --quiet -O - https:\/\/www.postgresql.org\/media\/keys\/ACCC4CF8.asc | sudo apt-key add -\r\nroot:~#sudo apt -y update\r\nroot:~#sudo apt -y install postgresql-16<\/pre>\n<p>Notre moteur de base de donn\u00e9es est install\u00e9, \u00e0 pr\u00e9sent il nous faut t\u00e9l\u00e9charger les sources de l&#8217;extension, et l&#8217;installer.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">root:~# git clone https:\/\/github.com\/trlorenz\/PG-recursively_delete.git\r\nCloning into 'PG-recursively_delete'...\r\nremote: Enumerating objects: 155, done.\r\nremote: Counting objects: 100% (95\/95), done.\r\nremote: Compressing objects: 100% (62\/62), done.\r\nremote: Total 155 (delta 41), reused 74 (delta 29), pack-reused 60\r\nReceiving objects: 100% (155\/155), 38.55 KiB | 3.21 MiB\/s, done.\r\nResolving deltas: 100% (70\/70), done.\r\nroot:~# cd PG-recursively_delete\/\r\nroot:~\/PG-recursively_delete# make\r\ncp sql\/recursively_delete.sql sql\/recursively_delete--0.1.5.sql\r\nroot:~\/PG-recursively_delete# sudo make install\r\n\/bin\/mkdir -p '\/usr\/share\/postgresql\/16\/extension'\r\n\/bin\/mkdir -p '\/usr\/share\/postgresql\/16\/extension'\r\n\/bin\/mkdir -p '\/usr\/share\/doc\/postgresql-doc-16\/extension'\r\n\/usr\/bin\/install -c -m 644 .\/\/recursively_delete.control '\/usr\/share\/postgresql\/16\/extension\/'\r\n\/usr\/bin\/install -c -m 644 .\/\/sql\/recursively_delete--0.1.5.sql  '\/usr\/share\/postgresql\/16\/extension\/'\r\n\/usr\/bin\/install -c -m 644 .\/\/doc\/changelog.md '\/usr\/share\/doc\/postgresql-doc-16\/extension\/'<\/pre>\n<h2>Mise en place de l&#8217;environnement<\/h2>\n<p>Pour illustrer le fonctionnement de l&#8217;extension, je vais utiliser la base de donn\u00e9es de d\u00e9monstration dvdrental. Nous allons donc la t\u00e9l\u00e9charger et la charger dans une toute nouvelle base de donn\u00e9es que nous aurons cr\u00e9\u00e9e sur notre instance fra\u00eechement cr\u00e9\u00e9e :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\"> postgres:~$ wget https:\/\/www.postgresqltutorial.com\/wp-content\/uploads\/2019\/05\/dvdrental.zip\r\n--2024-03-11 08:34:54--  https:\/\/www.postgresqltutorial.com\/wp-content\/uploads\/2019\/05\/dvdrental.zip\r\nResolving www.postgresqltutorial.com (www.postgresqltutorial.com)... 104.21.2.174, 172.67.129.129, 2606:4700:3037::6815:2ae, ...\r\nConnecting to www.postgresqltutorial.com (www.postgresqltutorial.com)|104.21.2.174|:443... connected.\r\nHTTP request sent, awaiting response... 200 OK\r\nLength: 550906 (538K) [application\/zip]\r\nSaving to: \u2018dvdrental.zip\u2019\r\n\r\ndvdrental.zip                                               100%[========================================================================================================================================&gt;] 537.99K  --.-KB\/s    in 0.01s\r\n\r\n2024-03-11 08:34:54 (46.0 MB\/s) - \u2018dvdrental.zip\u2019 saved [550906\/550906]  <\/pre>\n<p>Une fois t\u00e9l\u00e9charg\u00e9e, on la dezippe :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">postgres:~$ ls -l\r\ntotal 544\r\ndrwxr-xr-x 3 postgres postgres   4096 Mar 11 08:30 16\r\n-rw-rw-r-- 1 postgres postgres 550906 May 12  2019 dvdrental.zip\r\npostgres:~$ unzip dvdrental.zip\r\nArchive:  dvdrental.zip\r\n  inflating: dvdrental.tar\r\npostgres:~$ ls -l\r\ntotal 3316\r\ndrwxr-xr-x 3 postgres postgres    4096 Mar 11 08:30 16\r\n-rw-rw-r-- 1 postgres postgres 2835456 May 12  2019 dvdrental.tar\r\n-rw-rw-r-- 1 postgres postgres  550906 May 12  2019 dvdrental.zip<\/pre>\n<p>On cr\u00e9\u00e9 la base de donn\u00e9es pour accueillir nos donn\u00e9es, et on charge le fichier de sauvegarde :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">postgres:~$ psql\r\npsql (16.2 (Ubuntu 16.2-1.pgdg22.04+1))\r\nType &quot;help&quot; for help. <\/pre>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">postgres=# create database dvdrental;\r\nCREATE DATABASE\r\npostgres=# \\l\r\n                                                   List of databases\r\n   Name    |  Owner   | Encoding | Locale Provider | Collate |  Ctype  | ICU Locale | ICU Rules |   Access privileges\r\n-----------+----------+----------+-----------------+---------+---------+------------+-----------+-----------------------\r\n dvdrental | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           |\r\n postgres  | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           |\r\n template0 | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           | =c\/postgres          +\r\n           |          |          |                 |         |         |            |           | postgres=CTc\/postgres\r\n template1 | postgres | UTF8     | libc            | C.UTF-8 | C.UTF-8 |            |           | =c\/postgres          +\r\n           |          |          |                 |         |         |            |           | postgres=CTc\/postgres\r\n(4 rows)<\/pre>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">postgres:~$ pg_restore -U postgres -d dvdrental dvdrental.tar<\/pre>\n<p>Une fois que c&#8217;est fait, on peut se connecter pour v\u00e9rifier que tout a bien \u00e9t\u00e9 charg\u00e9 :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">postgres:~$ psql\r\npsql (16.2 (Ubuntu 16.2-1.pgdg22.04+1))\r\nType &quot;help&quot; for help.\r\n<\/pre>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">postgres=# \\c dvdrental\r\nYou are now connected to database &quot;dvdrental&quot; as user &quot;postgres&quot;.\r\ndvdrental=# \\dt\r\n             List of relations\r\n Schema |     Name      | Type  |  Owner\r\n--------+---------------+-------+----------\r\n public | actor         | table | postgres\r\n public | address       | table | postgres\r\n public | category      | table | postgres\r\n public | city          | table | postgres\r\n public | country       | table | postgres\r\n public | customer      | table | postgres\r\n public | film          | table | postgres\r\n public | film_actor    | table | postgres\r\n public | film_category | table | postgres\r\n public | inventory     | table | postgres\r\n public | language      | table | postgres\r\n public | payment       | table | postgres\r\n public | rental        | table | postgres\r\n public | staff         | table | postgres\r\n public | store         | table | postgres\r\n(15 rows)\r\n<\/pre>\n<h2>L&#8217;extension :<\/h2>\n<p>Pour tester l&#8217;extension, nous allons essayer de supprimer un client de la liste des clients.<br \/>\nLe sch\u00e9ma de la base de donn\u00e9es dvdrental est le suivant :<br \/>\n<a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/03\/dvd-rental-sample-database-diagram.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-10507\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/03\/dvd-rental-sample-database-diagram-238x300.png\" alt=\"\" width=\"336\" height=\"424\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/03\/dvd-rental-sample-database-diagram-238x300.png 238w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/03\/dvd-rental-sample-database-diagram.png 730w\" sizes=\"auto, (max-width: 336px) 100vw, 336px\" \/><\/a><\/p>\n<p>Si l&#8217;on observe attentivement le sch\u00e9ma ci-dessus, en voulant supprimer une donn\u00e9e de la table customer, cela devrait avoir un impact sur les tables rental et payment qui sont directement li\u00e9es \u00e0 la table customer. De plus, ces deux tables sont \u00e9galement li\u00e9es entre elles, ce qui signifie que supprimer une donn\u00e9e dans la table rental modifiera n\u00e9cessairement la table payment.<\/p>\n<p>Prenons l&#8217;exemple de la suppression du client num\u00e9ro 1. Si nous recherchons les d\u00e9pendances de ce client dans la table rental, nous obtenons 32 lignes associ\u00e9es au customer_id 1 :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\"> dvdrental=# select count(*) from rental where customer_id = 1;\r\n count\r\n-------\r\n    32\r\n(1 row)\r\n<\/pre>\n<p>Et si nous allons maintenant chercher toutes les occurrences de ce m\u00eame client dans la table des paiements, nous obtenons :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">dvdrental=# select count(*) from payment where customer_id = 1;\r\n count\r\n-------\r\n    30\r\n(1 row) <\/pre>\n<p>\u00c0 pr\u00e9sent, avec l&#8217;extension recursive_delete, nous allons chercher \u00e0 obtenir le sch\u00e9ma de suppression pour v\u00e9rifier si les r\u00e9sultats que nous avons trouv\u00e9s sont corrects :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">dvdrental=# create extension recursively_delete;\r\nCREATE EXTENSION\r\ndvdrental=# \\set VERBOSITY terse\r\ndvdrental=# select recursively_delete('customer', 1);\r\nINFO:  DAMAGE PREVIEW (recursively_delete v0.1.5)\r\nINFO:\r\nINFO:          1     customer\r\nINFO:         30 r   | payment.[&quot;customer_id&quot;]\r\nINFO:         32 r   | rental.[&quot;customer_id&quot;]\r\nINFO:          ~ n   | | payment.[&quot;rental_id&quot;]\r\nINFO:\r\n recursively_delete\r\n--------------------\r\n                  0\r\n(1 row) <\/pre>\n<p>La fonction de suppression de l&#8217;extension fonctionne avec les param\u00e8tres suivants :<\/p>\n<ul>\n<li>Le nom de la table en premier param\u00e8tre<\/li>\n<li>La clause WHERE du DELETE en second param\u00e8tre, qui peut \u00eatre de multiples types (des entiers, des cha\u00eenes de caract\u00e8res, des listes, des UUID&#8230;)<\/li>\n<li>Le mode de fonctionnement de l&#8217;extension, par d\u00e9faut \u00e0 false, qui indique au programme de ne pas effectuer les suppressions, mais simplement de dresser le sch\u00e9ma. Le passer \u00e0 true entra\u00eenerait les suppressions.<\/li>\n<\/ul>\n<p>Pour interpr\u00e9ter le sch\u00e9ma, voici la composition de chaque n\u0153ud :<\/p>\n<ol>\n<li>La premi\u00e8re colonne correspond au nombre de lignes<\/li>\n<li>Le type de contraintes qui expliquent l&#8217;implication de la table dans le sch\u00e9ma : &#8216;a&#8217;, &#8216;r&#8217;, &#8216;c&#8217;, &#8216;n&#8217;, ou &#8216;d&#8217; (&#8216;no action&#8217;, &#8216;restrict&#8217;, &#8216;cascade&#8217;, &#8216;set null&#8217;, ou &#8216;set default&#8217;)<\/li>\n<li>Un indicateur de si oui ou non le champ en question participe \u00e0 une r\u00e9f\u00e9rence circulaire.<\/li>\n<\/ol>\n<p>En examinant le r\u00e9sultat renvoy\u00e9 par notre extension, nous constatons que nous obtenons les m\u00eames r\u00e9sultats : 30 lignes pour payment et 32 lignes pour rental. Nous obtenons \u00e9galement une derni\u00e8re ligne qui nous indique que payment poss\u00e8de une r\u00e9f\u00e9rence \u00e0 rental dans sa structure, et qu&#8217;il va lui aussi proc\u00e9der \u00e0 des suppressions en fonction du rental_id. Cela pourrait \u00eatre par exemple le cas o\u00f9 une location effectu\u00e9e par un client serait pay\u00e9e par un autre.<\/p>\n<p>Pour effectuer la suppression, il suffit simplement de pr\u00e9ciser true en troisi\u00e8me param\u00e8tre.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">dvdrental=# select recursively_delete('customer', 1, true);\r\n recursively_delete\r\n--------------------\r\n                  1\r\n(1 row)\r\n<\/pre>\n<p>Et \u00e0 pr\u00e9sent, si nous consultons notre table customer, la ligne 1 a disparu, ainsi que toutes les lignes qui la concernent dans d&#8217;autres tables \u00e9galement.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\ndvdrental=# select count(*) from customer where customer_id = 1;\r\n count\r\n-------\r\n     0\r\n(1 row)\r\n\r\ndvdrental=# select count(*) from rental where customer_id = 1;\r\n count\r\n-------\r\n     0\r\n(1 row)\r\n\r\ndvdrental=# select count(*) from payment where customer_id = 1;\r\n count\r\n-------\r\n     0\r\n(1 row)\r\n<\/pre>\n<p>Nos lignes ont bel et bien disparu.<\/p>\n<p>Cette extension fonctionne \u00e9galement avec les cl\u00e9s primaires composites. Il suffit de pr\u00e9ciser entre crochets les deux valeurs de notre cl\u00e9 primaire, et le tour est jou\u00e9.<\/p>\n<p>Pour illustrer davantage le fonctionnement, je vais r\u00e9aliser une suppression sur la table film. Cette table poss\u00e8de quelques d\u00e9pendances.<br \/>\nDisons que nous souhaitons supprimer les 10 premiers films de notre liste, car ils ne sont plus lou\u00e9s \u00e9tant trop anciens (plus personne n&#8217;a de magn\u00e9toscope pour regarder de bonnes vieilles cassettes !).<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">dvdrental=# select recursively_delete('film', (SELECT array_agg(film_id) FROM film  WHERE film_id between 1 and 10));\r\nINFO:  DAMAGE PREVIEW (recursively_delete v0.1.5)\r\nINFO:\r\nINFO:         10     film\r\nINFO:         62 r   | film_actor.[&quot;film_id&quot;]\r\nINFO:         10 r   | film_category.[&quot;film_id&quot;]\r\nINFO:         52 r   | inventory.[&quot;film_id&quot;]\r\nINFO:        165 r   | | rental.[&quot;inventory_id&quot;]\r\nINFO:          ~ n   | | | payment.[&quot;rental_id&quot;]\r\nINFO:\r\n recursively_delete\r\n--------------------\r\n                  0\r\n(1 row)<\/pre>\n<p>Nous observons donc que notre suppression de 10 films (dans un array) entra\u00eene la suppression d&#8217;acteurs, de cat\u00e9gories, d&#8217;inventaires, et par extension, de locations et de paiements<\/p>\n<h2>Conclusion :<\/h2>\n<p>En conclusion, l&#8217;extension pg_recursively_delete offre une solution pratique pour supprimer r\u00e9cursivement des donn\u00e9es dans PostgreSQL, simplifiant ainsi les t\u00e2ches de maintenance et de nettoyage des bases de donn\u00e9es. Cependant, malgr\u00e9 ses avantages, cette extension pr\u00e9sente certaines limites en termes de performances.<\/p>\n<p>L&#8217;une des principales limitations r\u00e9side dans le fait que la suppression r\u00e9cursive peut entra\u00eener des op\u00e9rations co\u00fbteuses en termes de temps d&#8217;ex\u00e9cution, surtout lorsque les donn\u00e9es concern\u00e9es sont fortement imbriqu\u00e9es ou que la base de donn\u00e9es est volumineuse. Les performances peuvent \u00e9galement \u00eatre affect\u00e9es lorsque les tables impliqu\u00e9es dans la suppression ont des index complexes ou des contraintes de cl\u00e9s \u00e9trang\u00e8res.<\/p>\n<p>De plus, il est crucial de reconna\u00eetre les risques associ\u00e9s \u00e0 la suppression de donn\u00e9es ayant de nombreuses d\u00e9pendances dans une base de donn\u00e9es. La suppression inconsid\u00e9r\u00e9e de telles donn\u00e9es peut entra\u00eener des incoh\u00e9rences dans la base de donn\u00e9es, des erreurs d&#8217;int\u00e9grit\u00e9 r\u00e9f\u00e9rentielle et m\u00eame des pertes de donn\u00e9es importantes. Il est donc essentiel de proc\u00e9der avec prudence et de prendre en compte toutes les implications potentielles avant d&#8217;utiliser cette extension.<\/p>\n<p>En r\u00e9sum\u00e9, bien que l&#8217;extension pg_recursively_delete offre une fonctionnalit\u00e9 utile pour g\u00e9rer les op\u00e9rations de suppression r\u00e9cursive dans PostgreSQL, il est essentiel pour les utilisateurs de comprendre ses limites en termes de performances et les risques potentiels associ\u00e9s \u00e0 la suppression de donn\u00e9es avec de nombreuses d\u00e9pendances. Une utilisation judicieuse et une \u00e9valuation minutieuse des sc\u00e9narios d&#8217;utilisation sont indispensables pour garantir l&#8217;int\u00e9grit\u00e9 et la performance de la base de donn\u00e9es.<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10505&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10505&#038;title=pg_recursively_delete%20%3A%20Simplifier%20les%20suppressions%20r%C3%A9cursives\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=pg_recursively_delete%20%3A%20Simplifier%20les%20suppressions%20r%C3%A9cursives&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10505\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Si vous avez \u00e9t\u00e9 amen\u00e9 au fil de votre carri\u00e8re \u00e0 manipuler de gros volumes de donn\u00e9es contenus dans plusieurs tables poss\u00e9dant des r\u00e9f\u00e9rences crois\u00e9es entre elles, d\u00e9pendantes d&#8217;autres tables, qui elles-m\u00eames d\u00e9pendent d&#8217;autres tables, vous savez \u00e0 quel point&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":41,"featured_media":10513,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[266],"tags":[431],"class_list":["post-10505","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-postgresql","tag-postgresql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>pg_recursively_delete : Simplifier les suppressions r\u00e9cursives - Capdata TECH BLOG<\/title>\n<meta name=\"description\" content=\"Simplifier les suppressions r\u00e9cursives avec l&#039;extension postgreSQL pg_recursively_delete\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Simplifier les suppressions r\u00e9cursives avec l&#039;extension postgreSQL pg_recursively_delete\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2024-04-03T13:11:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/03\/delete-sql-datascientest-1024x512-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Sarah FAVEERE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sarah FAVEERE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\"},\"author\":{\"name\":\"Sarah FAVEERE\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2\"},\"headline\":\"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives\",\"datePublished\":\"2024-04-03T13:11:08+00:00\",\"dateModified\":\"2024-04-03T13:11:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\"},\"wordCount\":1924,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"keywords\":[\"PostgreSQL\"],\"articleSection\":[\"PostgreSQL\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\",\"name\":\"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2024-04-03T13:11:08+00:00\",\"dateModified\":\"2024-04-03T13:11:08+00:00\",\"description\":\"Simplifier les suppressions r\u00e9cursives avec l'extension postgreSQL pg_recursively_delete\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2\",\"name\":\"Sarah FAVEERE\",\"sameAs\":[\"http:\/\/blog.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/sfaveere\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives - Capdata TECH BLOG","description":"Simplifier les suppressions r\u00e9cursives avec l'extension postgreSQL pg_recursively_delete","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/","og_locale":"fr_FR","og_type":"article","og_title":"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives - Capdata TECH BLOG","og_description":"Simplifier les suppressions r\u00e9cursives avec l'extension postgreSQL pg_recursively_delete","og_url":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2024-04-03T13:11:08+00:00","og_image":[{"width":1024,"height":512,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/03\/delete-sql-datascientest-1024x512-1.png","type":"image\/png"}],"author":"Sarah FAVEERE","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"Sarah FAVEERE","Dur\u00e9e de lecture estim\u00e9e":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/"},"author":{"name":"Sarah FAVEERE","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2"},"headline":"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives","datePublished":"2024-04-03T13:11:08+00:00","dateModified":"2024-04-03T13:11:08+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/"},"wordCount":1924,"commentCount":0,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"keywords":["PostgreSQL"],"articleSection":["PostgreSQL"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/","url":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/","name":"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2024-04-03T13:11:08+00:00","dateModified":"2024-04-03T13:11:08+00:00","description":"Simplifier les suppressions r\u00e9cursives avec l'extension postgreSQL pg_recursively_delete","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/pg_recursively_delete-simplifier-les-suppressions-recursives\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"pg_recursively_delete : Simplifier les suppressions r\u00e9cursives"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2","name":"Sarah FAVEERE","sameAs":["http:\/\/blog.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/sfaveere\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/10505","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=10505"}],"version-history":[{"count":7,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/10505\/revisions"}],"predecessor-version":[{"id":10514,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/10505\/revisions\/10514"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/10513"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=10505"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=10505"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=10505"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}