Intermédiaire7 min de lecture

Quand NE PAS utiliser le single-table design dans DynamoDB

Le single-table design est le conseil par défaut pour DynamoDB, et il le mérite : un seul Query rend un parent et ses enfants, pas de jointures, pas de N+1.

Mais c'est un compromis — tu achètes de la vitesse de lecture avec un schéma rigide et opaque. Certaines charges ne peuvent pas se permettre ce prix, et leur imposer une seule table est son propre footgun.

Quand ne pas utiliser le single-table design dans DynamoDB ?

Évite le single-table design quand ta charge est de l'analytique OLAP lourde, du CRUD ordinaire sur quelques entités sans rapport entre elles, ou des entités qui scalent et échouent indépendamment. Dans ces cas, plusieurs tables sont plus lisibles, coûtent pareil et restent flexibles. Le single-table design ne l'emporte que quand les modes d'accès sont connus, liés et à fort volume.

  • Analytique lourde ? Pas de single-table. Les clés surchargées sont OLAP-hostiles — exporte vers un magasin colonnaire et requête là-bas.
  • CRUD ordinaire avec une poignée de modes d'accès ? Une table par entité est très bien, lisible, et ne te coûte rien en performance.
  • Des entités qui scalent ou échouent indépendamment ? Des tables séparées te laissent les ajuster, facturer et limiter leur rayon d'impact chacune de leur côté.
  • Le single-table l'emporte toujours quand tes modes sont connus, liés et à fort volume — c'est le cas pour lequel il a été conçu.

Sache ce que le single-table coûte vraiment

Le single-table design n'est pas gratuit ; il déplace juste le coût hors du chemin de lecture et sur tout le reste. Tu paies en lisibilité et en flexibilité.

Une table contenant cinq types d'entités derrière PK/SK est difficile à lire, difficile à prendre en main, et difficile à changer. Un nouveau mode d'accès peut signifier un backfill à travers chaque type d'item de la partition.

Donc la question n'est pas « le single-table est-il bon ? ». C'est « mes modes d'accès justifient-ils la rigidité ? » Quand non, atteins plusieurs tables.

Ne fais pas de single-table pour une charge analytique

DynamoDB est conçu pour l'OLTP — lectures petites, connues, point-et-plage. L'analytique est OLAP : GROUP BY, gros agrégats, découpage ad-hoc à travers tout le dataset. Les deux tirent dans des directions opposées.

Le single-table design rend l'OLAP pire, pas meilleur. Les clés surchargées et les types d'entités mêlés signifient qu'un job analytique doit d'abord démêler quel item est lequel avant de pouvoir sommer quoi que ce soit — l'opposé d'un scan colonnaire propre.

En venant de SQL, le réflexe est d'écrire l'agrégat contre la table en direct. Dans DynamoDB c'est un Scan complet — tu paies et tu lis chaque item, ce qui est le footgun du Scan à plein volume.

La solution n'est pas une clé plus maligne. C'est un magasin différent. Le conseil même d'AWS est d'exporter DynamoDB vers S3 et de faire l'analytique avec un moteur de requête comme Athena.

Garde l'OLTP et l'OLAP sur des moteurs séparés (AWS DynamoDB Developer Guide, S3DataExport.html).

Ne fais pas de single-table pour du CRUD simple

Si ton appli lit et écrit quelques entités sans rapport par leur propre id, et que tu as peut-être trois modes d'accès, le single-table ne t'achète rien.

Prends une table Tenants et une table ApiKeys pour un petit outil B2B :

Tenants
TenantIdNamePlanTier
TNT-8842Northwindpro
ApiKeys
KeyIdTenantIdScope
KEY-01H9...TNT-8842read-write

Chaque requête est un GetItem par id, ou un Query sur un GSI clé par TenantId. Il n'y a pas de fetch parent-et-enfants à optimiser, donc il n'y a rien à gagner pour une partition surchargée. Deux tables claires se lisent mieux qu'une seule trouble.

Le piège est de cargo-culter le single-table parce que c'est « best practice ». La best practice, c'est access-pattern-first. Si les modes sont triviaux, la forme simple est la bonne forme.

Sépare les tables qui scalent ou échouent indépendamment

Une seule table partage une surface de débit, un backup, un rayon d'impact. Quand deux entités ont des taux d'écriture ou des besoins de durabilité radicalement différents, ce destin partagé devient un handicap.

Imagine un système de suivi de flotte. Les véhicules changent rarement ; leur télémétrie déverse chaque seconde :

Vehicles (froid, faible taux d'écriture)
VehicleIdMakeModelRegion
VEH-204VolvoFH16eu-west
Telemetry (chaud, fort taux d'écriture, TTL)
DeviceTsVehicleIdSpeedKphFuel
2026-06-23T10:00:01ZVEH-204880.61

Deux tables te laissent provisionner la télémétrie pour un firehose, garder les véhicules minuscules et bon marché, poser un TTL sur la télémétrie seule, et empêcher une tempête d'écritures de télémétrie de throttler les lectures du catalogue de véhicules. Une seule table couple tout ça.

Selon le papier Amazon Dynamo de 2007, le partitionnement et la disponibilité sont des préoccupations de premier ordre — des tables indépendantes te donnent un contrôle indépendant sur les deux.

Cartographie la décision avant de t'engager

Fais passer la charge par une seule porte : les entités sont-elles liées, et les modes sont-ils connus et à fort volume ? Sinon, plusieurs tables.

Voici la décision sous forme de flux — commence en haut et suis la première branche qui correspond :

OuiNonNonOuiNonOuiNouvelle chargeAnalytique lourdeou OLAP ?Magasin séparé(export + Athena)Entités liées+ lues ensemble ?Plusieurs tables(CRUD simple)Modes connus,à fortvolume ?Plusieurs tables(rester flexible)Single-tabledesign

Seule la feuille en bas à droite mérite le single-table ; tout autre chemin est mieux servi par plus d'une table.

Single vs multiple, face à face

FacteurSingle-tablePlusieurs tables
Lectures liéesUn Query, pas de jointuresJointure côté client ou allers-retours en plus
LisibilitéClés surchargées opaquesUne entité par table, auto-documentée
Nouveau mode d'accèsSouvent un backfillAjouter une table ou un GSI en isolation
Analytique / OLAPHostile — démêler avant d'agrégerExporter quand même, mais plus propre par entité
Scaling indépendantDébit + rayon d'impact partagésAjuster, facturer, TTL et backup séparément
Idéal quandModes connus, liés, à fort volumeSans rapport, évolutif ou analytique

Pièges + étapes suivantes

L'erreur miroir est de sur-corriger — séparer des entités véritablement liées et à fort volume en table-par-entité et reconstruire des jointures à la SQL dans ton appli. C'est le piège N+1 que le single-table tue.

Choisis la forme que les modes d'accès demandent, pas le dogme.

Quand tu modélises des relations, appuie-toi sur le bon type d'index — voir GSI vs LSI avant d'en ajouter un.

Quand tu écris une requête contre un schéma multi-tables, esquisse d'abord le KeyConditionExpression dans le DynamoDB Expression Builder.

Comme ça tu attrapes une forme de Scan complet avant qu'elle n'atteigne la production.

Puis essaie DynoTable pour parcourir les deux formes sur tes propres tables et voir laquelle tes modes d'accès veulent vraiment.

Mis à jour