[{"data":1,"prerenderedAt":163},["ShallowReactive",2],{"seo-verification":3,"blog-migrer-sql-server-vers-postgresql-vps-fr":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-migrer-sql-server-vers-postgresql-vps-fr",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":30,"intro":33,"sections":34,"ctaTitle":128,"ctaBody":129,"ctaButton":130,"ctaUrl":131,"relatedPosts":132},467,"migrer-sql-server-vers-postgresql-vps",{"fr":10,"en":12,"ar":13,"es":14},"migrating-sql-server-2016-to-postgresql-on-a-vps","هجرة-sql-server-2016-إلى-postgresql-على-vps","migrar-sql-server-2016-a-postgresql-en-un-vps","Migrer SQL Server 2016 vers PostgreSQL sur VPS","SQL Server 2016 est en fin de support depuis juillet 2026. Guide technique pour migrer vers PostgreSQL sur VPS : types, T-SQL, pgloader, bascule.",12,0,false,"2026-10-18T00:00:00+00:00","2026-10-18T21:57:56+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},6,"Bases de données","bases-de-donnees","bg-teal-500\u002F10 text-teal-400","database",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fmigrer-sql-server-vers-postgresql-vps-poster.svg","Le 14 juillet 2026, Microsoft a mis fin au support étendu de SQL Server 2016. Plus aucun patch de sécurité ne sera publié pour cette version. Deux options s'offrent aux équipes encore sur cette base : payer une mise à niveau vers SQL Server 2022 ou migrer vers une alternative open source. PostgreSQL 16 est aujourd'hui une base de données relationnelle mature, performante, et sans coût de licence. Cette migration n'est pas triviale — le dialecte T-SQL de Microsoft n'est pas du SQL standard, et les types de données diffèrent sur plusieurs points importants. Ce guide détaille les incompatibilités à connaître, la correspondance des types, et un plan de bascule structuré pour éviter les pertes de données et les régressions applicatives.",[35,39,50,53,89,92,112,115,118,122,125],{"type":36,"title":37,"body":38},"h2","SQL Server 2016 : fin de support étendu le 14 juillet 2026","La politique de cycle de vie Microsoft prévoit dix ans de support pour chaque version de SQL Server : cinq ans de support standard, puis cinq ans de support étendu. Pour SQL Server 2016, la date de fin de support étendu est le 14 juillet 2026. Passée cette date, Microsoft ne publie plus de mises à jour de sécurité, de correctifs critiques, ni de mises à jour techniques pour cette version. Une instance SQL Server 2016 exposée sur un réseau après cette date accumule des vulnérabilités non corrigées. Les obligations réglementaires — PCI-DSS, RGPD, ISO 27001 — exigent en général que les composants d'infrastructure reçoivent les correctifs de sécurité disponibles. Rester sur SQL Server 2016 après juillet 2026 constitue donc un écart documentable lors d'un audit.",{"type":40,"title":41,"items":42},"ul","Pourquoi choisir PostgreSQL plutôt que la mise à jour SQL Server ou Azure SQL",[43,44,45,46,47,48,49],"Coût de licence nul : PostgreSQL est sous licence PostgreSQL (permissive, similaire BSD), sans CAL, sans édition Enterprise à payer séparément.","Contrôle total de l'infrastructure : sur un VPS dédié, vous gérez les versions, les extensions, les paramètres de mémoire et les sauvegardes sans dépendre d'un fournisseur cloud.","SQL Server 2022 corrige la dette de version mais maintient les coûts de licence et lie l'organisation à l'écosystème Microsoft.","Azure SQL Managed Instance simplifie la migration mais introduit un coût mensuel récurrent, une dépendance à Azure, et des contraintes réseau supplémentaires.","PostgreSQL supporte les mêmes fonctionnalités avancées : fenêtres analytiques, CTE récursives, JSON natif, partitionnement de table, réplication logique.","L'écosystème d'outillage est large : pgAdmin, DBeaver, Metabase, PostgREST, et la plupart des ORM (Entity Framework, Hibernate, SQLAlchemy, ActiveRecord) supportent PostgreSQL.","Les distributions Linux majeures packagent PostgreSQL avec des mises à jour de sécurité régulières incluses dans le contrat de maintenance de la distribution.",{"type":36,"title":51,"body":52},"Audit préliminaire : ce qui migre bien, ce qui demande du travail","Avant d'écrire la moindre commande de migration, un audit du schéma existant est indispensable. Les éléments qui migrent sans friction sont les tables simples avec des types standard, les contraintes `PRIMARY KEY`, `FOREIGN KEY`, `UNIQUE` et `NOT NULL`, les index B-tree classiques, les vues sans syntaxe T-SQL propriétaire, et les séquences. Les éléments qui demandent un travail explicite sont les procédures stockées et les fonctions T-SQL (syntaxe incompatible, à réécrire en PL\u002FpgSQL ou à supprimer), les triggers qui utilisent les tables virtuelles `INSERTED` et `DELETED` (équivalent PostgreSQL : `NEW` et `OLD`), les colonnes `ROWVERSION` \u002F `TIMESTAMP` utilisées pour la détection de concurrence optimiste, les colonnes calculées (`COMPUTED COLUMNS`), les hint de verrouillage (`WITH (NOLOCK)`, `WITH (UPDLOCK)`), et les tables temporaires globales (`##temp`). Un inventaire SQL Server peut être obtenu par requête sur `INFORMATION_SCHEMA` et sur les vues système `sys.objects`, `sys.procedures`, `sys.triggers`.",{"type":54,"title":55,"rows":56,"headers":85},"comparison","Correspondance des types SQL Server → PostgreSQL",[57,61,65,69,73,77,81],[58,59,60],"DATETIME2","TIMESTAMPTZ","Stocker les timestamps avec fuseau horaire ; DATETIME2 est sans timezone, prévoir la convention UTC explicitement",[62,63,64],"UNIQUEIDENTIFIER","UUID","PostgreSQL supporte nativement le type UUID ; extension `uuid-ossp` ou `gen_random_uuid()` pour la génération",[66,67,68],"NVARCHAR(MAX) \u002F NTEXT","TEXT","PostgreSQL stocke toutes les chaînes en UTF-8 ; pas de distinction NVARCHAR\u002FVARCHAR ni de limite MAX séparée",[70,71,72],"BIT","BOOLEAN","Les valeurs `0`\u002F`1` deviennent `false`\u002F`true` ; attention aux colonnes BIT utilisées comme entiers dans les calculs",[74,75,76],"MONEY \u002F SMALLMONEY","NUMERIC(19,4)","MONEY SQL Server est un entier mis à l'échelle, NUMERIC est exact ; comportement identique pour les calculs financiers",[78,79,80],"INT IDENTITY(1,1)","SERIAL ou GENERATED ALWAYS AS IDENTITY","SERIAL est un raccourci vers une séquence ; GENERATED ALWAYS AS IDENTITY est le standard SQL:2003, préférable pour les nouvelles tables",[82,83,84],"ROWVERSION \u002F TIMESTAMP","bytea + trigger ou xmin","Pas d'équivalent direct ; la colonne système `xmin` permet la détection de concurrence optimiste dans la plupart des cas",[86,87,88],"Type SQL Server","Type PostgreSQL","Remarque",{"type":36,"title":90,"body":91},"Incompatibilités T-SQL courantes et leurs équivalents PostgreSQL","Plusieurs constructions T-SQL courantes n'ont pas d'équivalent direct en SQL standard et nécessitent une réécriture.\n\n`TOP N` sans `ORDER BY` : SQL Server accepte `SELECT TOP 10 * FROM t` sans clause d'ordre. PostgreSQL requiert `LIMIT 10` ; si un ordre défini est important, ajouter `ORDER BY` explicitement.\n\n`ISNULL(expr, valeur)` : la fonction T-SQL `ISNULL` a pour équivalent standard `COALESCE(expr, valeur)`. Le comportement est identique pour les cas courants.\n\n`GETDATE()` et `GETUTCDATE()` : ces fonctions deviennent respectivement `NOW()` (timestamp avec timezone de la session) et `NOW() AT TIME ZONE 'UTC'` ou `CURRENT_TIMESTAMP`.\n\n`DATEDIFF` et `DATEADD` : PostgreSQL utilise l'arithmétique d'intervalles : `date + INTERVAL '7 days'`, `date2 - date1` retourne un `INTERVAL`.\n\n`HINT WITH (NOLOCK)` : ce hint demande une lecture sans verrou partagé (lectures non répétables). PostgreSQL ne supporte pas ce hint ; le niveau d'isolation `READ COMMITTED` (défaut) couvre la plupart des cas d'usage. Pour les rapports analytiques qui tolèrent des données légèrement obsolètes, une réplique en lecture est la solution structurelle.\n\n`PRINT` dans les procédures : utiliser `RAISE NOTICE 'message'` en PL\u002FpgSQL.\n\n`GO` comme séparateur de batch : ce séparateur n'existe pas en PostgreSQL. Les scripts SQL doivent être restructurés en transactions ou en blocs `DO $$...$$` séparés.",{"type":93,"title":94,"steps":95},"steps","Plan de migration en 8 étapes",[96,98,100,102,104,106,108,110],{"body":97},"Inventaire et audit du schéma : exporter la liste de toutes les tables, colonnes avec types, index, contraintes, procédures stockées, fonctions, triggers et vues. Identifier et prioriser les objets qui nécessitent une réécriture manuelle.",{"body":99},"Mise en place du VPS PostgreSQL cible : installer PostgreSQL 16 sur le VPS, configurer `postgresql.conf` (mémoire partagée, connexions, WAL), créer l'utilisateur applicatif avec le minimum de privilèges, activer TLS pour les connexions distantes.",{"body":101},"Conversion du schéma avec pgloader ou manuellement : `pgloader mssql:\u002F\u002Fuser:pass@host\u002Fdb postgresql:\u002F\u002Fuser:pass@vps\u002Fdb` migre le schéma et les données en une commande. Pour les schémas complexes, exporter le DDL SQL Server et l'adapter manuellement, en appliquant la table de correspondance des types.",{"body":103},"Validation du schéma migré : vérifier le nombre de tables, le compte de lignes par table, l'intégrité référentielle (`FOREIGN KEY`), et les index. Comparer les types réels avec les types attendus via `information_schema.columns`.",{"body":105},"Réécriture des procédures stockées et triggers : chaque objet T-SQL doit être réécrit en PL\u002FpgSQL ou déplacé dans la couche applicative. Tester chaque procédure indépendamment avec des jeux de données représentatifs.",{"body":107},"Adaptation du code applicatif : rechercher dans le code source toutes les chaînes SQL littérales et les requêtes paramétrées qui utilisent des constructions T-SQL propriétaires. Mettre à jour le driver de connexion (passer de `mssql` à `pg`, `psycopg2`, `npgsql`, ou le driver approprié à la stack).",{"body":109},"Tests de charge et de non-régression : exécuter la suite de tests de régression complète contre la base PostgreSQL de staging. Utiliser `pgbench` pour valider les performances sous charge. Comparer les plans d'exécution des requêtes critiques (`EXPLAIN ANALYZE`) entre SQL Server et PostgreSQL.",{"body":111},"Bascule en fenêtre de maintenance : planifier une fenêtre (nuit ou week-end), mettre l'application en mode maintenance, exécuter une migration différentielle finale (données insérées depuis la migration initiale), pointer le DSN applicatif vers PostgreSQL, valider les fonctions critiques, et lever la maintenance. Conserver SQL Server en lecture seule pendant 48 heures pour permettre un rollback rapide si nécessaire.",{"type":36,"title":113,"body":114},"Configurer PostgreSQL 16 sur un VPS pour la production","Une installation PostgreSQL par défaut n'est pas calibrée pour la production. Les paramètres suivants dans `postgresql.conf` sont un point de départ pour un VPS avec 4 Go de RAM.\n\n`shared_buffers` : fixer à 25 % de la RAM disponible, soit `1GB` pour 4 Go. Ce paramètre détermine la mémoire allouée au cache interne de PostgreSQL.\n\n`effective_cache_size` : fixer à 75 % de la RAM totale, soit `3GB`. Ce paramètre informe le planificateur de requêtes de la mémoire disponible pour le cache du système d'exploitation.\n\n`work_mem` : `16MB` à `64MB` selon la complexité des requêtes de tri. Ce paramètre s'applique par opération de tri et par connexion ; une valeur trop élevée sur une instance avec de nombreuses connexions simultanées épuise la mémoire.\n\n`maintenance_work_mem` : `256MB` pour les opérations de maintenance (`VACUUM`, `CREATE INDEX`).\n\n`max_connections` : `100` est suffisant pour la plupart des applications qui utilisent un pool de connexions. Si l'application ouvre une connexion par requête sans pool, utiliser PgBouncer en amont.\n\nPour `pg_hba.conf`, restreindre les connexions distantes à l'adresse IP du serveur applicatif et exiger TLS : `hostssl all appuser 10.0.0.5\u002F32 scram-sha-256`.\n\nActiver TLS en générant un certificat (Let's Encrypt ou certificat interne) et en configurant `ssl = on`, `ssl_cert_file` et `ssl_key_file` dans `postgresql.conf`.",{"type":36,"title":116,"body":117},"Piège des procédures stockées et des triggers T-SQL","Les procédures stockées T-SQL sont le principal point de friction d'une migration SQL Server vers PostgreSQL. T-SQL est un dialecte propriétaire avec des structures de contrôle, une gestion des curseurs, et une gestion des erreurs (blocs `TRY...CATCH`) qui n'ont pas d'équivalent direct en PL\u002FpgSQL.\n\nLes curseurs FAST_FORWARD de SQL Server deviennent des curseurs `FOR` en PL\u002FpgSQL, mais les performances sont similaires et l'usage des curseurs doit dans tous les cas être questionné : une requête ensembliste remplace presque toujours un curseur de manière plus efficace.\n\nLe bloc `TRY...CATCH` devient `BEGIN...EXCEPTION WHEN OTHERS THEN` en PL\u002FpgSQL.\n\nLes tables temporaires locales (`#temp`) correspondent aux tables temporaires de session PostgreSQL créées avec `CREATE TEMPORARY TABLE`. Les tables temporaires globales (`##temp`) n'ont pas d'équivalent direct — elles doivent être remplacées par des tables permanentes avec une gestion explicite du cycle de vie, ou par des tables dans un schéma dédié avec des politiques de nettoyage.\n\nLes triggers qui référencent `INSERTED` et `DELETED` (tables virtuelles SQL Server) doivent être réécrits pour utiliser `NEW` et `OLD` en PostgreSQL. La structure de déclenchement est aussi différente : PostgreSQL distingue les triggers `BEFORE` et `AFTER`, et les triggers `FOR EACH ROW` des triggers `FOR EACH STATEMENT`.\n\nUne approche pragmatique consiste à déplacer la logique des procédures stockées dans la couche applicative lors de la migration, ce qui simplifie les tests et réduit le couplage entre l'application et la base de données.",{"type":119,"title":120,"body":121},"tip","Test de charge avant bascule : pgbench et comparaison des plans de requêtes","Avant de basculer en production, valider les performances avec `pgbench`. Initialiser une base de test représentative : `pgbench -i -s 50 nom_base` crée un schéma de benchmark avec 5 millions de lignes. Lancer une simulation de charge : `pgbench -c 20 -j 4 -T 60 nom_base` simule 20 connexions parallèles pendant 60 secondes et rapporte les transactions par seconde. Pour les requêtes critiques de l'application, comparer les plans d'exécution entre SQL Server (`SET STATISTICS IO ON; SELECT ...`) et PostgreSQL (`EXPLAIN (ANALYZE, BUFFERS) SELECT ...`). Les points d'attention sont les scans de table complets inattendus (index non migré ou statistiques non calculées — lancer `ANALYZE` après la migration), et les jointures `NESTED LOOP` sur de grands volumes qui bénéficieraient d'un `HASH JOIN`. Mettre à jour les statistiques après la migration initiale avec `ANALYZE nom_table` ou `VACUUM ANALYZE` pour l'ensemble de la base.",{"type":36,"title":123,"body":124},"Dépannage — erreurs courantes lors d'une migration SQL Server vers PostgreSQL","Plusieurs catégories d'erreurs reviennent systématiquement lors des premières migrations.\n\n`ERROR: column is of type uuid but expression is of type character varying` : une colonne `UNIQUEIDENTIFIER` migrée en `UUID` reçoit une chaîne formatée comme un UUID mais sans cast explicite. Soit adapter la requête applicative pour envoyer un vrai type UUID, soit ajouter un cast implicite dans PostgreSQL (`CREATE CAST`), soit migrer la colonne en `TEXT` si la sémantique UUID n'est pas exploitée.\n\n`ERROR: operator does not exist: boolean = integer` : une colonne `BIT` migrée en `BOOLEAN` est comparée à `0` ou `1`. Remplacer `col = 1` par `col = true` ou simplement `col` dans les clauses `WHERE`.\n\n`ERROR: function isnull(character varying, text) does not exist` : remplacer toutes les occurrences de `ISNULL` par `COALESCE`.\n\n`ERROR: syntax error at or near \"TOP\"` : la syntaxe `SELECT TOP N` n'existe pas en PostgreSQL. Remplacer par `SELECT ... LIMIT N`.\n\nDépassements silencieux sur les colonnes `MONEY` → `NUMERIC` : vérifier que les valeurs extrêmes de la table source tiennent dans la précision cible `NUMERIC(19,4)`. SQL Server `MONEY` a une plage de ±922 337 203 685 477,5807 ; `NUMERIC(19,4)` couvre ±999 999 999 999 999,9999, ce qui est suffisant dans la quasi-totalité des cas.\n\nPertes de données sur les colonnes `DATETIME` sans timezone : SQL Server `DATETIME` et `DATETIME2` ne stockent pas le fuseau horaire. Si la base de données était alimentée par des applications dans plusieurs fuseaux, les timestamps migrés en `TIMESTAMPTZ` sans conversion préalable seront interprétés comme UTC. Définir une convention (UTC ou heure locale) et appliquer un `AT TIME ZONE` lors de la migration si nécessaire.",{"type":36,"title":126,"body":127},"Vérifier la migration et remettre les utilisateurs","Après la bascule, une checklist de vérification structurée réduit le risque de remettre les utilisateurs sur une base incomplète.\n\nVérifier le compte de lignes pour toutes les tables critiques : une requête sur `information_schema.tables` avec un `COUNT(*)` par table, comparée aux chiffres relevés sur SQL Server avant la migration.\n\nVérifier l'intégrité référentielle : `SELECT * FROM pg_constraint WHERE contype = 'f'` liste toutes les contraintes de clé étrangère ; tenter une insertion qui violerait une contrainte pour confirmer qu'elle est active.\n\nVérifier les index : `SELECT indexname, indexdef FROM pg_indexes WHERE schemaname = 'public'` liste tous les index créés. Comparer avec la liste des index SQL Server.\n\nTester les fonctions critiques de l'application : parcours d'achat, authentification, rapports, exports — au minimum les parcours qui touchent aux tables les plus volumineuses et aux requêtes les plus complexes.\n\nSurveiller les logs PostgreSQL pendant les premières 24 heures : `tail -f \u002Fvar\u002Flog\u002Fpostgresql\u002Fpostgresql-*.log`. Les erreurs de type `character varying` vs `uuid`, les timeouts de connexion, ou les plans de requête sous-optimaux se manifestent généralement dans les premières heures de trafic réel.\n\nConserver SQL Server en lecture seule pendant 48 heures avec un accès restreint à l'équipe technique. Le rollback consiste à pointer le DSN applicatif vers SQL Server et à rejouer les données écrites dans PostgreSQL pendant la fenêtre de bascule.","VPS prêts pour PostgreSQL 16","VPS ServOrbit configurés pour PostgreSQL 16 : SSD NVMe, snapshot quotidien, accès root complet. Déployez votre base migrée sans contrainte de licence.","Voir les VPS ServOrbit","\u002Fsolutions\u002Fprofessionnels",[133,148],{"id":134,"slug":135,"slugs":136,"title":140,"excerpt":141,"readTime":142,"views":18,"isPinned":19,"publishedAt":143,"updatedAt":21,"category":144,"categories":145,"featuredImage":30,"bgImage":31,"posterImage":147,"relatedSolution":30},464,"mysql-8-0-eol-migration-vps",{"fr":135,"en":137,"ar":138,"es":139},"mysql-8-0-end-of-life-migration-vps","mysql-8-0-انتهاء-الدعم-ترقية-vps","mysql-8-0-fin-de-soporte-migracion-vps","Migration MySQL 8.0 vers 8.4 LTS sur VPS : guide complet","MySQL 8.0 EOL le 30 avril 2026 : plus aucun patch de sécurité. Migrez vers MySQL 8.4 LTS — breaking changes, prérequis, upgrade in-place et quand choisir MariaDB 11.x.",10,"2026-10-17T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[146],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fmysql-8-0-eol-migration-vps-poster.svg",{"id":149,"slug":150,"slugs":151,"title":155,"excerpt":156,"readTime":157,"views":18,"isPinned":19,"publishedAt":158,"updatedAt":21,"category":159,"categories":160,"featuredImage":30,"bgImage":31,"posterImage":162,"relatedSolution":30},461,"postgresql-migrer-cloud-vers-self-hosted-vps",{"fr":150,"en":152,"ar":153,"es":154},"migrate-postgresql-from-rds-cloud-sql-supabase-to-vps","نقل-postgresql-من-rds-و-cloud-sql-و-supabase-إلى-vps","migrar-postgresql-de-rds-cloud-sql-o-supabase-a-un-vps","Migrer PostgreSQL depuis RDS, Cloud SQL ou un BaaS vers un VPS","Migration PostgreSQL depuis RDS, Cloud SQL et Supabase vers un VPS self-hosted : commandes exactes, pièges propres à chaque source et bascule sans downtime.",13,"2026-10-16T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[161],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fpostgresql-migrer-cloud-vers-self-hosted-vps-poster.svg",1792361026407]