Déséquilibre de propriété, de parent et de référence
Aussi en 19 langues
English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Українська · Español (México) · Deutsch (Schweiz)

Module 2 sur 4 du chapitre Concevoir pour le volume, chapitre 7 du cours Data Architect. Chaque module est autonome. Précédent : Quand le volume change tout · Suivant : Quand le volume rencontre le modèle de partage
La question à laquelle répond ce module : que se passe-t-il quand trop d’enregistrements pointent vers une seule chose ?
Les problèmes de gros volumes de données ne tiennent pas toujours au fait d’avoir trop d’enregistrements. Parfois, ils tiennent au fait que trop d’enregistrements sont liés à la même chose : un propriétaire, un compte, un parent, une valeur de référence. Pensez à la circulation. Une ville peut compter des millions de voitures et fonctionner quand même. Les ennuis commencent quand tout le monde prend la même sortie d’autoroute à 17 h. Le total compte, et la concentration aussi. J’appelle ces concentrations des points chauds ; Salesforce les appelle déséquilibre de données (data skew). Il en existe plusieurs sortes, et une seule idée sous-jacente : trop d’activité qui converge vers un seul point du modèle.
Le déséquilibre parent-enfant
Section intitulée « Le déséquilibre parent-enfant »The easiest to picture. One account with 100 contacts: nothing unusual. A thousand: probably fine. Ten thousand: now I’m paying attention. My design rule is no more than about 10,000 children under one parent, and Salesforce’s guidance draws the same line: “a large number of child records (10,000 or more) with a single parent account” is a common cause of poor performance (Parent-Child Data Skew (s'ouvre dans un nouvel onglet)). Salesforce’s own example shows why. Put 300,000 contacts under one account. A user who can see one of those contacts gets implicit access to the account. When that user loses access to the contact, Salesforce has to check the other 299,999 contacts before it can decide whether to remove the user’s access to the account. Do that for many users at once, and it gets expensive. Salesforce also names one way to take part of that cost away: where your security requirements allow, set the child object to Controlled by Parent, so there are no parent implicit shares to maintain (same source). In practice, it’s the most common skew I see, and I’ve seen users notice visible lag at around 20,000 children under one parent. Where somebody feels it depends on what the system is doing. That’s why 10,000 is a design threshold, not a promise that record 10,001 breaks anything. The real question is: why are all these records pointing at the same parent? ⟲
Step 1 of 2: every line points at one account. That’s the hot spot. ⟲
Le compte « Non attribué », et les pools de comptes
Section intitulée « Le compte « Non attribué », et les pools de comptes »The classic case is contacts with no real account. Somebody decides every contact needs an account, so they create Unassigned Contacts and put every contact without an account there. Problem solved, until there are 300,000 contacts under it. We created an artificial hot spot because the model required us to put everything somewhere, and the relationship doesn’t even carry business meaning. It worked beautifully at 500 records. Then the Number of Zeros caught up with it. ⟲
What do you do when you’ve got a million contacts under it? I’ve seen child accounts by state, one unhandled-contacts account per state. I’ve seen an automatic version: whenever an account reaches 10,000, create another one. It can be a little awkward, but it spreads the load. ⟲
One answer is an account pool: Unassigned Contacts 001, 002, 003 and so on, with the children spread across them, each kept under the threshold. It works, and it’s Salesforce’s own advice: “Distribute child records so that no parent has more than 10,000 child records,” and for contacts without real accounts, “set up several dummy accounts and distribute the contacts among them” (Best Practices for Deployments with Large Data Volumes: General (s'ouvre dans un nouvel onglet), Winter ‘27). But those aren’t real accounts; they’re architecture artifacts. Users will ask who “Unassigned Contacts 017” is and why it’s in their search results. So when I use a pool, I hide the placeholder parents from normal business experiences as much as I can. It’s a recurring trade-off: sometimes scale forces a structure that exists for the platform, not the business. When it does, don’t pretend it’s business data. Name it, document it, hide it where appropriate. ⟲
Step 2 of 2: the same contacts, spread across a pool. Nothing moved but where they point. ⟲
Master-Detail at Volume
Section intitulée « Master-Detail at Volume »Contacts under an account are a lookup. Master-detail is a different decision, and it’s one you make in the data model, long before the records arrive. Here’s the question I ask in class: would an invoice ever have more than 10,000 line items? No, it never would. So an invoice and its lines can be master-detail all day long. Now ask the same question of every master-detail relationship you’re about to build: at the volume we expect, will one parent ever pass 10,000 children? ⟲
Salesforce draws the same line: “As a best practice, don’t exceed 10,000 child records for a master-detail relationship” (Considérations relatives aux relations entre les objets (s'ouvre dans un nouvel onglet)). Master-detail is the strongest relationship Salesforce gives you, and that’s exactly why the number matters. The detail record has no owner of its own; its access is controlled by the parent. Delete the parent, and every child goes with it. A child can’t move to another parent unless you allowed reparenting. Roll-up summaries on the parent have to keep up as the children change. And saving a child can lock the parent, which is why Salesforce’s loading advice is to group child records by their parent “to minimize locking conflicts” (Loading Data from the API (s'ouvre dans un nouvel onglet)). With ten children, none of that is noticeable. With a hundred thousand, every one of them is. ⟲
It’s also hard to undo. A master-detail relationship can only be converted to a lookup when the parent has no roll-up summary fields, and converting it changes the child’s sharing to Public Read/Write (same source). By the time volume tells you it was the wrong choice, the relationship may be holding up reports, sharing and automation. Count the children before you choose the relationship. ⟲
Steve Trucking has one of these decisions in its model. Each Retail Partner sends a Manifest (Manifest__c, a custom object) for each distribution center, for each working day. Manifest is custom, so master-detail to the partner’s account is allowed, and it’s tempting: the manifest would inherit the partner’s sharing, which is exactly the isolation we want. Now count. Our largest partner has nine or more DCs: nine manifests a working day, about 2,700 a year. Past 10,000 in under four years, under one parent, and every manifest revised on the day, so every revision would touch the partner’s account. That’s why the model makes Manifest a lookup and handles partner access through sharing. The invoice stays small; the manifests keep coming. ⟲
Step 1 of 2: master-detail, where the parent stays small. ⟲
Step 2 of 2: a lookup, where the children keep coming. ⟲
Watch Account with its contacts and opportunities too. It isn’t master-detail, but it behaves like a pseudo master-detail, with implicit sharing to the parent, which is why the 10,000 guidance shows up there as well. None of this means never use master-detail at scale. It means don’t choose a strongly coupled relationship and then act surprised that the records are strongly coupled. ⟲
Test knowledge. Know the 10,000-children guidance for master-detail, and what master-detail brings with it at volume: no owner on the detail (access controlled by the parent), cascade delete, no reparenting unless allowed, roll-up summaries, and parent locking when children are saved. Converting to a lookup needs no roll-up summaries on the master. ⟲
Le déséquilibre de propriété
Section intitulée « Le déséquilibre de propriété »Now the owner. I ask the room: who owns a million records? The admin? Is the admin sitting there creating a million records? Usually it’s the integration user or the data load user. The records come in, and nobody knows who to give them to. We create an integration user, it creates records, nobody thinks about ownership (“it’s just the integration user”), and a year later that user owns 2 million records. Salesforce calls it ownership data skew when one user owns more than 10,000 records of an object, and the classic example is all the unassigned leads parked on a dummy user (Ownership Data Skew (s'ouvre dans un nouvel onglet)). That doesn’t mean a user can never own more. It means understanding the consequences: ownership isn’t a Created By stamp. It drives the role hierarchy, sharing rules and recalculation: behind the scenes, Salesforce keeps share records for the owner’s records above them in the role hierarchy. Attach millions of records to one owner who sits deep in the sharing model, and changing anything about that owner gets expensive. ⟲
The guidance matches what I teach in class. If a few users must own a very large number of records, give them no role; if they need one, put them in a separate role at the top of the hierarchy and don’t move them, and keep them out of public groups used as sources for sharing rules (same source). One catch with the top role: that user inherits access to all the data owned by or shared with the users below them. You could spread the records across a bunch of users instead, but for an integration user or a data load user, that typically isn’t worth the trouble. ⟲
We’re isolating the hot spot from the structures that trigger recalculation. Imagine a user who owns 5 million records being moved in a reorganization. That isn’t moving a box on the org chart; Salesforce may have to re-evaluate access across 5 million records. At this scale, organizational changes become data operations. ⟲
Test knowledge. Know the skew thresholds and the fixes: ownership skew when one user owns more than 10,000 records of an object (no role, or a separate role at the top that doesn’t move, and out of public groups used by sharing rules); parent-child skew at about 10,000 children under one parent. ⟲
Qui doit posséder les enregistrements créés par des machines ?
Section intitulée « Qui doit posséder les enregistrements créés par des machines ? »Qui a créé un enregistrement et qui le possède, ce n’est pas la même question. Redrock envoie 500 000 livraisons par l’API, et l’utilisateur d’intégration les crée. Doit-il les posséder pour toujours ? Peut-être, mais pas seulement parce qu’il les a créées. Et maintenant, les agents créent aussi des enregistrements.
Ma position : cela dépend de l’importance de la propriété pour le partage. L’utilisateur d’intégration ou d’agent est un utilisateur valide et peut posséder des enregistrements. Si la propriété pilote l’accès dans cet objet (par la hiérarchie des rôles ou les règles de partage), attribuez les enregistrements au propriétaire que le métier exige : un vrai utilisateur, une file d’attente si l’objet le permet, ou un utilisateur propriétaire dédié. Si la propriété ne pilote pas l’accès, garder l’utilisateur d’agent ou d’intégration comme propriétaire peut être le meilleur choix, parce que la piste d’audit ramène directement à ce qui a créé l’enregistrement. Dans tous les cas, décidez ce que signifie Propriétaire pour cet objet, plutôt que de réattribuer mécaniquement chaque enregistrement créé par une machine parce que, d’habitude, ce sont des personnes qui possèdent les enregistrements. Et souvenez-vous que « Créé par » est toujours là : réattribuer la propriété ne fait pas perdre le fait que c’est l’intégration qui l’a créé. « Créé par » et Propriétaire répondent à des questions différentes. Faire répondre un seul champ aux deux, c’est comme ça qu’on obtient un mauvais modèle.
Le déséquilibre de référence
Section intitulée « Le déséquilibre de référence »A lookup can be a hot spot too: millions of records pointing at the same location, category, reference record or configuration record. Salesforce’s own training defines it: “Lookup skew happens when a very large number of records are associated with a single record in the lookup object” (Large Data Volumes: Design Your Data Model (s'ouvre dans un nouvel onglet)). The danger isn’t “lots of lookups.” It’s concentration combined with activity: if millions of active records reference one record, and transactions keep touching that relationship, operations start colliding over it. That’s record locking, which chapter 11 covers. For now, recognize the shape: many active records, one heavily referenced record, worth inspecting. ⟲
Tous les déséquilibres ne sont pas aussi dangereux
Section intitulée « Tous les déséquilibres ne sont pas aussi dangereux »Ne retenez pas par cœur « 10 000 = mauvais ». Cinquante mille enregistrements historiques pointant vers une valeur de référence qui ne change jamais, sans rôle dans le partage et presque sans activité concurrente, peuvent très bien aller. Vingt mille enregistrements actifs sous un parent qui change souvent, pilote le partage, alimente des récapitulatifs de cumul et est sollicité par plusieurs intégrations à la fois, c’est une tout autre histoire. Le volume a une forme, le déséquilibre aussi. Combien d’enregistrements convergent là ? À quelle fréquence changent-ils ? Le parent change-t-il ? La relation pilote-t-elle le partage ou le verrouillage ? Des intégrations mettent-elles à jour les enfants en même temps ? Déplacer le propriétaire ou le parent déclenche-t-il un recalcul ? Le chiffre me dit où regarder ; le comportement me dit à quel point m’inquiéter.
Steve Trucking : où sont les points chauds ?
Section intitulée « Steve Trucking : où sont les points chauds ? »À cinq ans, nous avons projeté environ 9 millions d’ordres d’exécution. Supposons que quelqu’un dise : « Faisons posséder chaque livraison par l’utilisateur d’intégration. » Neuf millions d’enregistrements, un seul propriétaire. La propriété compte-t-elle pour le partage des livraisons ? Si non, un propriétaire dédié à fort volume peut fonctionner, isolé de la hiérarchie des rôles et des groupes des règles de partage, comme ci-dessus. Si oui, un seul propriétaire d’intégration est le mauvais modèle métier : l’intégration crée l’enregistrement ; cela ne veut pas dire qu’elle doit le posséder.
Then the Retail Partner. Every work order carries its partner, deliberately, because partner isolation matters. But if one partner is 40% of the business, five years of deliveries is about 3.6 million work orders under one partner account. Does that make the relationship wrong? No. The business relationship is real, and I’m not going to invent 400 fake Redrock accounts because I don’t like the count. But I am going to look for a split the business would recognize. Each partner has real distribution centers, so a child account per DC under the partner spreads the work orders nine or more ways while every account still means something. Add archiving completed deliveries after the claims window, and the active children per parent stay low. ⟲
Voilà la différence entre les deux corrections. « Contacts non attribués » était déjà artificiel, donc le découper en pool ne fait perdre aucun sens. Redrock est un vrai partenaire ; le découper en Redrock 001, 002 et 003 corromprait le modèle. Le découper selon ses vrais centres de distribution, non. Les corrections pour le volume doivent quand même préserver le sens. Parfois, la réponse est une autre relation, une autre stratégie de partage, un autre schéma de requête, un autre modèle de stockage ou une autre politique d’archivage, jamais une fausse identité pour une entité métier réelle.
Inspect, not bad. Concentration matters, not the total. ⟲
Trouvez les points chauds sur le diagramme
Section intitulée « Trouvez les points chauds sur le diagramme »Voici un exercice que j’aime bien. Prenez le modèle de données et regardez les flèches, pas seulement les objets. Pour chaque relation, demandez : combien d’enregistrements peuvent s’accumuler de ce côté de la flèche ? Puis posez la même question pour le Propriétaire. Imaginez maintenant trois ans, cinq, dix. Où les enregistrements se concentrent-ils ? C’est souvent là que se cache le problème de demain.
Au-delà de l’examen : ce que l’IA change. Une personne peut créer 20 enregistrements par jour ; un agent pourrait en créer des milliers. Donnez à un agent son propre utilisateur, laissez-le posséder chaque enregistrement, et le déséquilibre de propriété apparaît bien plus vite qu’il ne l’a jamais fait avec des personnes. La propriété par un agent n’est pas une erreur, mais décidez ce que signifie Propriétaire pour les enregistrements créés par des agents avant que le volume ne fasse du comportement par défaut une partie de l’architecture.
Ce que l’architecte décide ici
Section intitulée « Ce que l’architecte décide ici »- Où les relations parent-enfant, de propriété ou de référence concentrent les enregistrements, et s’ils sont assez actifs pour devenir des points chauds.
- Si les enregistrements créés par des machines restent la propriété de l’utilisateur d’intégration ou d’agent, ou sont réattribués parce que la propriété pilote l’accès.
- Comment les propriétaires à fort volume sont isolés de la hiérarchie des rôles et des groupes des règles de partage.
- Quand un parent artificiel peut être mis en pool, et quand une relation réelle a plutôt besoin d’un découpage qui a du sens.
- Whether each master-detail relationship stays under about 10,000 children per parent at projected volume, or should be a lookup. ⟲
Un million d’enregistrements répartis entre des milliers de propriétaires et de parents se comporte très différemment d’un million d’enregistrements pointant vers un seul endroit. Cherchez les points chauds tôt : propriétaires, parents, relations de référence, partout où le Nombre de zéros converge. Le but n’est pas d’éliminer toute grosse relation ; certaines représentent correctement le métier. C’est de savoir où va la circulation avant d’ouvrir l’autoroute, parce qu’une fois que des millions d’enregistrements se dirigent vers la même sortie, changer la route devient beaucoup plus difficile.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Salesforce Developers, Best Practices for Deployments with Large Data Volumes, Loading Data from the API (s'ouvre dans un nouvel onglet) (Winter ‘27): group child records by parent to minimize locking conflicts, checked 2026-11-01. ⟲
- Salesforce Help, Considérations relatives aux relations entre les objets (s'ouvre dans un nouvel onglet): no more than 10,000 child records for a master-detail relationship; converting master-detail to lookup, checked 2026-11-01. ⟲
- Salesforce Developers, Designing Record Access for Enterprise Scale (Winter ‘27): Ownership Data Skew (s'ouvre dans un nouvel onglet) and Parent-Child Data Skew (s'ouvre dans un nouvel onglet), checked 2026-11-01. ⟲
- Salesforce Developers, Best Practices for Deployments with Large Data Volumes: General (s'ouvre dans un nouvel onglet) (Winter ‘27), the 10,000-record owner and parent guidance, checked 2026-11-01. ⟲
- Trailhead, Large Data Volumes: Design Your Data Model (s'ouvre dans un nouvel onglet): parent-child, ownership and lookup skew, checked 2026-11-01. ⟲
- Salesforce engineering blog, Managing Lookup Skew to Avoid Record Lock Exceptions (s'ouvre dans un nouvel onglet) (2013; older, but still the clearest explanation; checked 2026-11-01). ⟲
- SteveTechArc, Salesforce Documents by Release: these guides, once a year from Winter ‘16, each with an archived copy. ⟲
