Maison base de données tutoriel mysql Comment gérer les lignes manquantes dans les UPSERT PostgreSQL avec des transactions simultanées ?

Comment gérer les lignes manquantes dans les UPSERT PostgreSQL avec des transactions simultanées ?

Jan 21, 2025 pm 06:27 PM

How to Handle Missing Rows in PostgreSQL UPSERTs with Concurrent Transactions?

Gestion des lignes de résultats manquantes dans l'opération PostgreSQL UPSERT

Dans PostgreSQL 9.5, l'utilisation conjointe de RETURNING et ON CONFLICT entraînait parfois des lignes manquantes lorsque des transactions simultanées mettaient à jour des cibles conflictuelles spécifiées.

Inconvénients de la réponse actuellement acceptée

La réponse actuellement acceptée est sujette à des problèmes lorsque des transactions simultanées mettent à jour plusieurs lignes dans la table cible. Bien qu'il évite les lignes manquantes, il introduit d'autres effets secondaires et pénalités de performances associés aux mises à jour vides.

Alternatives

Aucune charge d'écriture simultanée :

WITH input_rows(usr, contact, name) AS (
   VALUES
      (text 'foo1', text 'bar1', text 'bob1')  -- 第一行中的类型转换
    , ('foo2', 'bar2', 'bob2')
    -- 更多?
   )
, ins AS (
   INSERT INTO chats (usr, contact, name) 
   SELECT * FROM input_rows
   ON CONFLICT (usr, contact) DO NOTHING
   RETURNING id  --, usr, contact              -- 返回更多列?
   )
SELECT 'i' AS source                           -- 'i' 代表'插入'
     , id  --, usr, contact                    -- 返回更多列?
FROM   ins
UNION  ALL
SELECT 's' AS source                           -- 's' 代表'选择'
     , c.id  --, usr, contact                  -- 返回更多列?
FROM   input_rows
JOIN   chats c USING (usr, contact);           -- 唯一索引的列
Copier après la connexion

Avoir une charge d'écriture simultanée

Pour résoudre les conditions de concurrence pour plusieurs transactions simultanées :

WITH input_rows(usr, contact, name) AS ( ... )  -- 如上所示
, ins AS (
   INSERT INTO chats AS c (usr, contact, name) 
   SELECT * FROM input_rows
   ON     CONFLICT (usr, contact) DO NOTHING
   RETURNING id, usr, contact                   -- 我们需要唯一的列来进行后续连接
   )
, sel AS (
   SELECT 'i'::"char" AS source                 -- 'i' 代表'插入'
        , id, usr, contact
   FROM   ins
   UNION  ALL
   SELECT 's'::"char" AS source                 -- 's' 代表'选择'
        , c.id, usr, contact
   FROM   input_rows
   JOIN   chats c USING (usr, contact)
   )
, ups AS (                                      -- 罕见的极端情况
   INSERT INTO chats AS c (usr, contact, name)  -- 另一个UPSERT,不仅仅是UPDATE
   SELECT i.*
   FROM   input_rows i
   LEFT   JOIN sel   s USING (usr, contact)     -- 唯一索引的列
   WHERE  s.usr IS NULL                         -- 缺失!
   ON     CONFLICT (usr, contact) DO UPDATE     -- 我们第一次已经礼貌地请求了……
   SET    name = c.name                         -- ……这次我们用旧值覆盖
   RETURNING 'u'::"char" AS source              -- 'u' 代表更新
           , id  --, usr, contact               -- 返回更多列?
   )
SELECT source, id FROM sel
UNION  ALL
TABLE  ups;
Copier après la connexion

Points clés :

  • sel CTE renvoie les lignes insérées et les lignes sélectionnées, fournissant l'ensemble complet des résultats de sortie.
  • ups CTE gère les lignes manquantes et les met à jour avec les valeurs existantes.
  • Le jeu de résultats de sortie exclut toutes les lignes mises à jour par des transactions simultanées à moins qu'elles ne soient ups traitées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Réduisez l'utilisation de la mémoire MySQL dans Docker Réduisez l'utilisation de la mémoire MySQL dans Docker Mar 04, 2025 pm 03:52 PM

Réduisez l'utilisation de la mémoire MySQL dans Docker

Comment modifier une table dans MySQL en utilisant l'instruction ALTER TABLE? Comment modifier une table dans MySQL en utilisant l'instruction ALTER TABLE? Mar 19, 2025 pm 03:51 PM

Comment modifier une table dans MySQL en utilisant l'instruction ALTER TABLE?

Comment résoudre le problème de MySQL ne peut pas ouvrir la bibliothèque partagée Comment résoudre le problème de MySQL ne peut pas ouvrir la bibliothèque partagée Mar 04, 2025 pm 04:01 PM

Comment résoudre le problème de MySQL ne peut pas ouvrir la bibliothèque partagée

Qu'est-ce que Sqlite? Aperçu complet Qu'est-ce que Sqlite? Aperçu complet Mar 04, 2025 pm 03:55 PM

Qu'est-ce que Sqlite? Aperçu complet

Exécutez MySQL dans Linux (avec / sans conteneur Podman avec phpmyadmin) Exécutez MySQL dans Linux (avec / sans conteneur Podman avec phpmyadmin) Mar 04, 2025 pm 03:54 PM

Exécutez MySQL dans Linux (avec / sans conteneur Podman avec phpmyadmin)

Exécuter plusieurs versions MySQL sur macOS: un guide étape par étape Exécuter plusieurs versions MySQL sur macOS: un guide étape par étape Mar 04, 2025 pm 03:49 PM

Exécuter plusieurs versions MySQL sur macOS: un guide étape par étape

Comment sécuriser MySQL contre les vulnérabilités communes (injection SQL, attaques par force brute)? Comment sécuriser MySQL contre les vulnérabilités communes (injection SQL, attaques par force brute)? Mar 18, 2025 pm 12:00 PM

Comment sécuriser MySQL contre les vulnérabilités communes (injection SQL, attaques par force brute)?

Comment configurer le cryptage SSL / TLS pour les connexions MySQL? Comment configurer le cryptage SSL / TLS pour les connexions MySQL? Mar 18, 2025 pm 12:01 PM

Comment configurer le cryptage SSL / TLS pour les connexions MySQL?

See all articles