Skip to content
DynamoDB single-table ou Postgres ? Comment nous avons choisi, par workload, et où nous nous sommes trompés
← ← Retour aux Réflexions Development

DynamoDB single-table ou Postgres ? Comment nous avons choisi, par workload, et où nous nous sommes trompés

Le débat DynamoDB contre Postgres se mène généralement comme une religion. Un camp dit que les données relationnelles appartiennent à une base relationnelle et que la conception single-table est un casse-tête qu'on résout une fois et qu'on regrette pour toujours. L'autre camp dit que Postgres ne monte pas en charge sans gardien et que DynamoDB est le seul magasin qui vous laisse cesser de penser à la capacité. Les deux ont raison sur les cas qu'ils ont en tête et tort de croire qu'il existe une seule réponse.

Nous exploitons les deux, sur la même plateforme, pour un client américain. Six tables DynamoDB et un cluster Aurora Serverless v2 Postgres, choisis workload par workload. Voici la règle que nous utilisons, les quatre workloads qu'elle a produits, celui que nous avons mis dans le mauvais magasin et déplacé, et le coût de chaque côté.

La règle

Posez deux questions sur le workload, et la réponse tombe d'elle-même.

1. Connaissez-vous les schémas d'accès, et y en a-t-il moins d'une dizaine ? DynamoDB est un magasin clé-valeur avec des index secondaires. Vous concevez la table autour des requêtes. Si les requêtes sont connues et peu nombreuses, cette conception est un après-midi agréable et la table les servira à n'importe quelle échelle pour un coût fixe faible par requête. Si les requêtes sont inconnues, évolutives ou ad hoc (un administrateur qui a besoin de « toutes les commandes des clients du Texas qui ont acheté le produit X en mars »), chaque nouvelle question est un nouvel index ou un scan, et vous construirez une seconde copie des données quelque part de requêtable dans l'année.

2. Avez-vous besoin de transactions sur de nombreuses lignes, de jointures ou d'agrégats ? DynamoDB a des transactions, jusqu'à 100 éléments. Il n'a ni jointures ni GROUP BY. Si le workload est « sommer le chiffre d'affaires par produit par semaine », ou « mettre à jour la commande, le stock et le grand livre atomiquement », Postgres le fait en une instruction et DynamoDB le fait en code applicatif que vous écrirez subtilement faux au moins une fois.

Schémas d'accès connus et peu nombreux, pas de jointures ni d'agrégats : DynamoDB. Tout le reste : Postgres. En cas d'égalité, Postgres, parce que le coût de l'erreur est asymétrique : une table Postgres qui se révèle avoir un schéma clé-valeur chaud peut recevoir un index ou un cache ; une table DynamoDB qui se révèle avoir besoin de jointures a besoin d'une migration.

schémas d'accès connus,moins de ~10 ? oui jointures, agrégats outransactions de plus de 100 éléments ? non DynamoDB non oui Postgres · Aurora Serverless v2les égalités vont ici : une mauvaise supposition reçoit un index ; dans DynamoDB, une mauvaise supposition est une migration Deux questions par workload, pas une réponse par entreprise.

Les quatre workloads

Sessions et seaux de limitation de débit → DynamoDB. Un schéma d'accès chacun : lire par clé, écrire par clé, expirer par TTL. Des millions de petits éléments, un trafic en pics, aucun intérêt à les interroger jamais autrement que par la clé. C'est le workload DynamoDB du manuel et il coûte environ 4 $ par mois à notre volume, à la demande, sans capacité à laquelle penser. Les mettre dans Postgres reviendrait à une table qui représente 90 % du volume d'écriture pour 0 % de la valeur métier, et un job de vacuum pour l'empêcher de gonfler.

Catalogue produit et configuration par tenant → DynamoDB, single-table. Sept schémas d'accès, tous connus : produit par id, produits par tenant, produits par tenant et catégorie, config par tenant, quelques autres. Beaucoup de lectures, peu d'écritures, et la forme d'un produit est un document, pas un ensemble de lignes jointes. Une table avec une clé composite et deux GSI sert les sept. L'exercice de restauration a montré le piège de la perte des réglages, mais la table elle-même n'a jamais eu besoin d'un changement en dix-huit mois.

Commandes, paiements, grand livre → Postgres. C'est le workload où la seconde question dit non. Une commande touche la commande, ses lignes, la réservation de stock et l'écriture au grand livre dans une seule transaction ; la finance veut le chiffre d'affaires par produit par région par semaine ; le support veut « chaque commande de ce client avec un remboursement dans les 90 derniers jours ». Jointures, agrégats, questions ad hoc, et une forte préférence pour les invariants que donnent les clés étrangères et les contraintes. Aurora Serverless v2 à 0,5 ACU minimum, passé en revue séparément.

Journal d'événements pour l'index de recherche → DynamoDB avec Streams. Ajout seul, lu uniquement par le consommateur du stream, expiration après 30 jours. Schéma connu, pas de jointures, et Streams donne le flux de changements gratuitement.

Celui que nous avons raté

Les profils clients ont commencé dans DynamoDB. Les schémas d'accès semblaient connus : profil par id, profil par email, profils par tenant. Trois schémas, une forme de document, adéquation évidente.

Puis le produit a grandi. Le support voulait les clients par date d'inscription. Le marketing voulait les clients qui n'avaient pas commandé depuis 60 jours, ce qui est une jointure avec les commandes. La finance voulait la valeur vie client, un agrégat. Chaque demande est devenue soit un nouveau GSI (nous en avons ajouté trois), soit un scan avec filtre qui prenait des minutes et coûtait de vrais euros, soit un export nocturne vers Postgres qui était périmé au matin. À la quatrième demande, nous avions deux copies des données clients, dont l'une toujours légèrement fausse.

Nous avons déplacé les profils vers Postgres. La migration a pris une semaine : double écriture pendant quelques jours, backfill, bascule des lectures, suppression des écritures DynamoDB, suppression de la table un mois plus tard. Les trois GSI ont disparu. L'export nocturne a disparu. Chaque question posée sur les clients depuis a été une requête, pas un projet.

La leçon est dans la première question. « Schémas d'accès connus » veut dire connus pour la durée de vie des données, pas connus aujourd'hui. Les profils sont l'entité que tout le monde dans l'entreprise finit par vouloir découper autrement. Les sessions, non. Le magasin doit suivre ça.

Où vit chaque workload workloadmagasinpourquoi$/mois sessions · seaux de limitationDynamoDB1 schéma, TTL, pics~4 catalogue · config tenantDynamoDB single-table7 schémas, 2 GSI, surtout des lectures~6 commandes · paiements · grand livrePostgrestransactions, jointures, agrégats~45 journal d'événements de rechercheDynamoDB + Streamsajout seul, flux de changements gratuit~3 profils clientsDynamoDB → Postgres3 GSI + export nocturne = mauvais magasindéplacé « Schémas d'accès connus » veut dire connus pour la vie des données, pas aujourd'hui.

Ce que coûte chaque côté, honnêtement

DynamoDB (4 tables) Aurora Serverless v2 Postgres
Facture mensuelle ~13 $ à la demande ~45 $ au plancher de 0,5 ACU, plus sous charge
Planification de capacité Aucune Fixer les ACU min et max ; le plancher est la facture
Changements de schéma Gratuits pour les attributs ; un nouveau schéma d'accès est un nouveau GSI, avec backfill ALTER TABLE, migrations, parfois un verrou à anticiper
Sauvegardes PITR activé, la restauration perd les réglages PITR activé, la restauration est un nouveau cluster
Questions ad hoc Scan, ou export ailleurs Une requête
Surprises opérationnelles en 18 mois Une : partition chaude sur une clé de tenant mal choisie, corrigée avec un suffixe Une : une longue transaction a tenu un verrou pendant une migration
Ce que vous ne pouvez pas faire Jointures, agrégats, requêtes imprévues Cesser complètement d'y penser

Le côté DynamoDB est moins cher et plus calme pour ce qu'il sait faire. Le côté Postgres coûte plus et répond à plus. Aucun des chiffres n'est l'argument ; le workload l'est.

La version courte

Par workload, deux questions : les schémas d'accès sont-ils connus et peu nombreux, pour la durée de vie des données ; et faut-il des jointures, des agrégats ou des transactions larges. Oui et non veut dire DynamoDB. Tout le reste veut dire Postgres. Attendez-vous à en rater un, et attendez-vous à ce que le raté soit l'entité que tout le monde dans l'entreprise finit par vouloir découper autrement.

Si vous choisissez un magasin pour une nouvelle plateforme, ou si vous avez une table DynamoDB avec son quatrième GSI et un export nocturne, nous pouvons vous aider à trier les workloads. C'est une séance au tableau blanc, pas une religion.