KEPLIN Docs

Relations et enums

Relier les tables entre elles — cardinalité, navigators, relations physiques et virtuelles — et fermer l'ensemble des valeurs d'un champ avec un enum.

Une table seule conserve une liste. Une application a besoin de plus : que les contacts sachent à quel compte ils appartiennent, que les opportunités sachent à qui elles sont, qu'un champ état n'accepte que les états qui existent.

Ce sont les deux pièces de cette page : les relations, qui relient les entités les unes aux autres, et les enums, qui ferment l'ensemble des valeurs possibles d'un champ.

Les relations

Dans le diagramme du modèle, chaque relation est une ligne entre deux entités, avec une étiquette qui donne le nom du chemin et la cardinalité — dans Gestion des Clients, conta · 1:N entre Contas et Contactos, et une autre identique entre Contas et Oportunidades.

Le modèle de l'app Gestion des Clients : les entités Contas, Contactos et Oportunidades, avec les deux relations dessinées entre elles.
Le modèle de l'app Gestion des Clients : les entités Contas, Contactos et Oportunidades, avec les deux relations dessinées entre elles.

Une relation a toujours deux côtés :

  • Le côté enfant (child), qui conserve la référence — la colonne conta_id de la table contactos.
  • Le côté parent (parent), qui est référencé — la colonne id de la table contas.

Créer une relation

Les relations se dessinent dans le diagramme, en reliant un champ à un autre :

  1. Passez la souris sur le champ du côté enfant — la ligne répond par l'aide Glissez vers un champ d'une autre table pour lier.
  2. Faites glisser depuis ce champ jusqu'au champ du côté parent (typiquement la clé primaire de l'autre entité) et lâchez.
  3. La boîte de dialogue Nouvelle relation s'ouvre, déjà avec les deux entités et les deux colonnes remplies — elles viennent du glisser-déposer et ne se modifient pas là.
  4. Remplissez le reste (voir plus bas) et confirmez avec Créer la relation.

La cardinalité

Le premier champ de la boîte de dialogue est la Cardinalité — combien de chaque côté :

Option Quand l'utiliser
Un-à-plusieurs (1:N) Un compte a plusieurs contacts. C'est le cas le plus courant.
Plusieurs-à-un (N:1) Le même, vu de l'autre côté.
Un-à-un (1:1) Un enregistrement pour un enregistrement — un compte et sa fiche fiscale.
Plusieurs-à-plusieurs (N:N) Beaucoup vers beaucoup — étiquettes sur des comptes, formateurs sur des cours. Nécessite une table de jonction.

Selon le choix, la boîte de dialogue affiche Child (porte la FK) et Parent (référencée) — ou, dans le cas N:N, Entité A et Entité B.

Les navigators

Les deux champs suivants sont les navigators — le cœur de la relation, et ce qui la rend utile en dehors du diagramme.

Un navigator est un champ virtuel qui n'existe pas dans la base de données : il sert à sauter d'un enregistrement vers les enregistrements liés et à ramener les colonnes de l'autre côté dans les APIs. Ce sont eux qui font qu'une requête de contacts renvoie, avec chaque contact, le nom du compte auquel il appartient — sans deuxième requête et sans code.

  • Navigator sur Contactos → Contas — le chemin de l'enfant vers le parent. Un nom au singulier : conta.
  • Navigator sur Contas → [Contactos] — le chemin du parent vers les enfants. Un nom au pluriel : contactos. Les crochets dans le libellé disent que ce côté renvoie une liste.

Laisser l'un des champs vide est une décision légitime : ce côté n'est simplement pas exposé. Si personne n'a besoin d'aller d'un compte vers ses contacts, vous ne créez pas le chemin.

Sur la carte de l'entité, les navigators apparaissent dans la section Navigation, avec le nom à gauche et la destination à droite — entre crochets quand c'est une liste.

L'entité Contactos avec la section Navigation : le navigator conta mène à l'enregistrement du compte auquel le contact appartient.
L'entité Contactos avec la section Navigation : le navigator conta mène à l'enregistrement du compte auquel le contact appartient.

Dica

Traitez les noms des navigators comme faisant partie de la langue de l'app : conta, contactos, linhas, responsavel. Ce sont eux que vous lirez dans les APIs, dans les datastores des écrans et dans le code des événements — et un fk_ct_2 mal choisi aujourd'hui, c'est de la confusion pour toujours.

Physique ou virtuelle

Le champ Type de relation décide si la relation est aussi écrite dans la base de données :

Option Ce qu'elle fait
Virtuelle — uniquement dans le modèle de la plateforme La relation existe pour la plateforme : navigators, APIs, écrans. La base de données n'est pas touchée.
Physique — crée la FK dans la base de données En plus du modèle, la clé étrangère est créée dans le moteur : c'est désormais le moteur lui-même qui refuse un conta_id qui n'existe pas.

La relation physique est plus sûre — l'intégrité cesse de dépendre de celui qui écrit. La virtuelle est ce qui reste quand on ne peut pas (ou ne veut pas) toucher au schéma de la base de données : bases de données de tiers, tables partagées avec d'autres systèmes, données historiques qui ne passeraient pas la vérification.

À la suppression du parent

À la suppression du parent (ON DELETE) dit ce qui arrive aux enfants quand l'enregistrement parent est supprimé :

Option Ce qui se passe
Rien (bloque s'il y a des enfants) La suppression échoue tant qu'il reste des enfants.
Restrict — bloque immédiatement La même chose, vérifiée tout de suite.
Cascade — supprime les enfants Supprimer le compte supprime ses contacts et ses opportunités.
Set NULL — détache les enfants Les enfants se retrouvent sans parent (la colonne devient vide). Exige que la colonne accepte le vide.

Dans une relation physique, cette règle est appliquée par le moteur. Dans une relation virtuelle, elle est enregistrée dans le modèle et prend effet si un jour la relation est matérialisée.

Atenção

Cascade est pratique et irréversible : supprimer un compte emporte contacts, opportunités et tout ce qui y est accroché. Sur des données métier, l'usage est de préférer Rien et de traiter la suppression comme un processus — on ne supprime que ce dont plus rien ne dépend.

Plusieurs-à-plusieurs

Avec Plusieurs-à-plusieurs (N:N), la boîte de dialogue demande trois choses de plus, parce qu'une relation de ce genre a besoin d'une table au milieu (la table de jonction), avec une référence pour chaque côté :

Champ Ce que c'est
Table de jonction La table qui relie les deux — par exemple conta_etiqueta.
Colonne → A (child) La colonne de la jonction qui pointe vers la première entité.
Colonne → B (parent) La colonne de la jonction qui pointe vers la seconde.

La table de jonction doit exister avant : créez-la comme n'importe quelle autre (voir Tables et champs).

Les relations qui arrivent toutes faites

À l'import d'une table dans le modèle, les clés étrangères qui existent déjà dans la base de données entrent toutes seules comme relations, avec des navigators proposés à partir des noms des tables. C'est ainsi que Gestion des Clients est née avec ses deux relations — il suffit de vérifier si les noms des navigators sont ceux que vous voulez lire dans le reste de l'app.

Retirer une relation

Cliquez sur la ligne de la relation dans le diagramme et confirmez. La question est explicite : Retirer cette relation du modèle ? — et la réponse aussi : la relation sort du modèle de la plateforme et une FK physique déjà créée dans la base de données N'EST PAS retirée. Si vous vouliez vraiment défaire la clé étrangère dans le moteur, cela se fait dans la base de données.

À quoi elles servent, ensuite

Une fois la relation faite, elle apparaît partout :

  • Dans les APIs, sous forme de champs imbriqués : une requête de contacts peut renvoyer conta { nome, cidade }.
  • Dans les datastores des écrans, pour monter un maître-détail — la table de contacts filtrée par l'id du compte chargé (voir Datastores et données).
  • Dans l'intégrité des données, quand la relation est physique.

Les enums

Un enum est un ensemble fermé de valeurs pour un champ : l'estado d'un compte est Active, Suspendue ou Perdue, et rien d'autre. Au lieu de laisser le champ accepter du texte libre — et de finir avec « active », « Active », « ACTIVE » et « actif » dans la même colonne — on déclare l'ensemble une fois.

Créer un enum

L'enum naît sur la colonne, au moment où vous lui donnez son type :

  1. Dans la boîte de dialogue Nouvelle table (ou dans Modifier la structure), sélectionnez la colonne.
  2. Dans Type, choisissez enum.
  3. Le cadre Éléments de l'enum apparaît. Cliquez sur Ajouter un élément pour chaque valeur.
  4. Remplissez les trois colonnes de chaque élément :
Colonne Ce que c'est
Valeur La valeur enregistrée. Lettres, chiffres et _, commençant par une lettre — par convention en majuscules : ATIVO, EM_ANALISE.
Libellé Le texte que les gens voient : Actif, En analyse.
Couleur Une couleur facultative, utilisée par les widgets qui peignent des états (le Kanban, les règles de formatage).

Une colonne de type enum ouvre les Éléments de l'enum — chaque élément avec valeur, libellé et couleur.
Une colonne de type enum ouvre les Éléments de l'enum — chaque élément avec valeur, libellé et couleur.

Chaque colonne énumérée a son enum, et son nom dérive de la table et de la colonne — la colonne tipo de la table actividades donne l'enum ActividadesTipo.

Nota

Dans la base de données, une colonne enum est conservée dans un champ structuré — le cadre lui-même le signale : Dans la BD, c'est un champ JSON (1 ou N valeurs). C'est cela qui permet au même champ de servir pour un choix unique aujourd'hui et pour un choix multiple demain, sans changer le schéma.

Modifier un enum

Rouvrez Modifier la structure sur la table, sélectionnez la colonne et touchez aux Éléments de l'enum : ajouter, changer le libellé, changer la couleur, retirer avec le ×. Confirmez avec Appliquer les modifications.

Changer le libellé ou la couleur est sans risque — ce n'est que de la présentation. Changer ou retirer une valeur ne l'est pas : les enregistrements qui portaient déjà l'ancienne valeur se retrouvent avec une valeur que l'enum ne connaît plus.

Le type `enum` dans la liste des types de colonne, à côté des types normaux.
Le type `enum` dans la liste des types de colonne, à côté des types normaux.

Où les enums apparaissent

Un champ énuméré cesse d'être du texte libre dans toute la plateforme :

Ce qui change
Dans le diagramme Le champ apparaît en italique, avec le nom de l'enum à la place du type.
Dans les APIs Le champ prend un type à valeurs fixes, et l'API refuse toute valeur hors de la liste.
Dans le widget Liste Dans Source des options, on choisit Enum du modèle puis le Champ enum — les options et les libellés viennent du modèle, et il n'y a pas de listes à tenir à jour à deux endroits.
Dans le Kanban Dans Source des colonnes, l'option Enum crée une colonne par valeur de l'enum, avec les couleurs.
Dans les règles de formatage Les conditions comparent avec les valeurs de l'enum.

Dica

Chaque fois qu'un champ a un ensemble connu de valeurs — état, type, priorité, canal — faites-en un enum plutôt qu'un champ de texte. Vous gagnez les libellés traduisibles, les couleurs, les bons filtres et un Kanban gratuit.

Pourquoi ne… ?

  • Pourquoi n'arrivé-je pas à glisser d'un champ vers l'autre ? Le glisser-déposer commence sur la ligne du champ du côté enfant et se termine sur la ligne du champ du côté parent. Si vous faites glisser la carte entière, vous la déplacez dans le diagramme — attrapez la ligne du champ.
  • Pourquoi l'API ne renvoie-t-elle pas les données de la table liée ? Il manque le navigator de ce côté. Un navigator vide est un côté qui n'a pas été exposé, exprès — recréez la relation avec le nom rempli.
  • Pourquoi la création de la relation physique a-t-elle échoué ? Une clé étrangère n'est acceptée que si les données déjà présentes la respectent. S'il y a des enfants qui pointent vers des parents qui n'existent pas, le moteur refuse — nettoyez d'abord les orphelins, ou créez la relation en virtuelle.
  • Pourquoi est-ce que je vois toujours la relation après l'avoir retirée ? Vous l'avez retirée du modèle ; la clé étrangère dans la base de données est toujours là et c'est elle que la réimportation ramène.
  • Pourquoi mon champ enum affiche-t-il la valeur au lieu du libellé ? Le widget n'est pas relié à l'enum du modèle — au lieu d'une liste fixe, choisissez Enum du modèle et pointez le Champ enum.