La modélisation avancée des données est possible avec TypeDB, une base de données graphique qui permet d’hériter et de composer n’importe quel type de données.
TypeDB est extrêmement unique. Cette base de données vous permet d’utiliser la saisie complète pour décrire les données. Vous pouvez hériter et composer n’importe quel type de données, tout comme une classe dans un langage de programmation.
Autrefois écrit en Java, il est désormais extrêmement rapide et écrit en Rust. Il existe un studio hébergé dans le cloud où vous pouvez facilement commencer à simplifier la modélisation de relations complexes.
TL;DR
TypeDB est superbe. Sa courbe d’apprentissage est courte, principalement en raison du manque de bonne formation en IA, mais elle n’est pas aussi complexe que d’autres bases de données. Elle n’est pas aussi riche en fonctionnalités que certaines autres bases de données, mais elle peut exécuter une modélisation de données avancée qu’aucune autre base de données ne peut réaliser. Si vous avez besoin d’une modélisation de données complexe, il s’agit peut-être de la meilleure base de données graphique que vous puissiez obtenir.
Premiers pas avec TypeDB Studio
Tout d’abord, inscrivez-vous à TypeDB et créez un nouveau cluster.
Grappe
Vous pouvez obtenir un cluster gratuit ou payer pour un AWS ou Google Cloud complet.
Une fois que vous disposez d’un cluster, connectez-vous-y dans TypeDB Studio.
Base de données
TypeDB possède une base de données par défaut, mais vous pouvez en avoir plusieurs. Chaque base de données est autonome et ne peut pas communiquer avec les autres bases de données de votre cluster. Considérez-le comme un moyen de séparer vos données mais de ne payer que pour un seul cluster. Sous le capot, les préfixes gardent vos bases de données uniques.
Schéma
Avant de lire et d’écrire des requêtes ou des mutations, vous devez créer un schéma pour une sécurité totale des types. TypeDB est en effet basé sur des types. Sélectionner schema requête et conserver le mode pour auto vous n’avez donc pas besoin de valider manuellement les requêtes.
TypeQL
La base de données elle-même utilise un langage appelé TypeQL pour décrire et interroger les données.
Des choses
Chaque chose dans TypeDB est connu sous le nom de taper. Il utilise conceptuellement le modèle ER de :
⚠️ Le nom du type peut jamais être changé et est unique dans les trois types.
Définir
Nous pouvons créer des attributs, des entités et des relations tout en un define instruction, ou nous pouvons exécuter plusieurs requêtes.
define
attribute username,
value string;
attribute created-at,
value datetime-tz;
attribute name,
value string;
attribute complete,
value boolean;
relation creation,
relates created,
relates created-by,
owns created-at;
entity user
owns username,
owns created-at,
plays creation:created-by;
entity todo
owns name,
owns complete,
owns created-at,
plays creation:created;
🎮 Exécutez cette requête dans schema.
Attribut
Les attributs sont équivalents aux noms de champs dans d’autres bases de données, mais ils peuvent appartenir à n’importe quelle table (entité). Comme tous les types, ils sont uniques au monde.
define
attribute username,
value string;
Nous définissons notre attributes d’abord et leur type avec value. Les types possibles peuvent être :
- chaîne
- booléen
- entier / long / double / décimal
- date / dateheure / dateheure-tz
- durée
- structurer
📝 Notez les conventions de dénomination utilisées kebab-case au lieu de snake_case ou camelCase.
📝 Chaque requête ne peut avoir qu’une seule « clause de requête » comme undefine, define, matchetc. Cependant, vous pouvez exécuter plusieurs créations dans une seule clause.
📝 Pour les attributs, vous devez répéter le attribute mot-clé pour chaque champ.
Entité
Dans TypeDB, vous créez d’abord des champs (attributs), puis des tables (entités).
define
entity todo
owns name,
owns complete,
owns created-at;
Nous connectons nos attributs à une entité appelée user et todo. Nous ajoutons les champs avec le owns mot-clé.
📝 Notez l’attribut created-at peut être utilisé dans plusieurs entités.
Créer une relation
Considérez une relation comme un moyen de décrire des connexions. En SQL ou noSQL, on peut avoir todos.created_by et users.todos. Pour les bases de données graphiques, nous avons besoin de verbes.
relation creation,
relates created,
relates created-by,
owns created-at;
entity user
owns username,
owns created-at,
plays creation:created-by;
entity todo
owns name,
owns complete,
owns created-at,
plays creation:created;
Nous avons une relation appelée creation. Pensez à ceci une table de jonction avec des champs :
created– Qu’est-ce que la création ? Dans ce cas untodo.created-by– Qui l’a créé ? Dans ce cas unuser.created-at– Quand le lien, et non l’enregistrement, a-t-il été créé ?
Nous n’avons pas besoin de définir un type pour relatescar c’est une connexion. Le created-at L’attribut a déjà été défini. Nous devons connecter nos entités à la relation avec plays. Une tâche est created-by quelqu’un, et quelqu’un a created beaucoup de tous.
⚠️ Vous devez d’abord créer un lien depuis la relation. Dans d’autres bases de données, vous pouvez modéliser user.createdmais dans cette base de données, vous devez penser qu’une création a créé quelque chose, ce qui est une tâche à accomplir. Donc du todo point de vue, vous créez un lien created.
📝 Nous aurions pu utiliser user.todos au lieu de user.createdmais cela se limiterait alors à todos. Ici, nous pouvons utiliser la création pour n’importe quel type.
Supprimer un type
Vous pouvez supprimer un type (entité, attribut, relation) simplement en utilisant undefine. Peu importe de quel type il s’agit.
undefine
todo;
user;
creation;
complete;
created-at;
name;
username;
⚠️ Vous ne pouvez supprimer qu’une entité sans données.
🎮 N’hésitez pas à tester cette requête dans schemaassurez-vous simplement de recréer à nouveau les types pour tester les requêtes suivantes.
Mettre à jour un type
Pour ajouter des attributs à une relation ou une entité, exécutez simplement un nouveau define déclaration. Cependant, si vous devez modifier un attribut, utilisez redefine.
redefine
attribute complete
value boolean;
⚠️ Vous ne pouvez mettre à jour qu’un attribut sans données.
📝 Notez qu’il n’y a pas de virgule après le nom de l’attribut comme c’est le cas dans la déclaration.
Insérer un utilisateur
Pour modifier les données, il faut passer de la requête de schema à write.
Insérons deux utilisateurs.
insert
$u1 isa user,
has username "alice",
has created-at 2025-10-18T14:00:00Z;
insert
$u2 isa user,
has username "bob",
has created-at 2025-10-18T14:05:00Z;
Il faut d’abord créer une variable pour chaque enregistrement $u et le définir comme un user tapez avec isa. Chaque enregistrement sur insert sera lié à une variable.
Finished writes. Printing rows...
$u1 | isa user, iid 0x1e00030000000000000000
$u2 | isa user, iid 0x1e00030000000000000001
Finished. Total rows: 1
📝 Vous devrez insérer manuellement une date, car TypeDB est intentionnellement procédural et n’a actuellement pas de date. now() ou fonction équivalente.
📝 En fait, je ne sais pas pourquoi c’est écrit 1 pour le nombre total de lignes, bien que cela puisse compter l’insertion elle-même comme une seule ligne ?
📝 Notez le iid est créé automatiquement pour chaque entité.
Insérer un utilisateur avec une tâche
insert
$u isa user,
has username "alice",
has created-at 2025-10-18T17:00:00Z;
$t isa todo,
has name "Learn TypeDB",
has complete false,
has created-at 2025-10-18T17:00:00Z;
creation (
created: $t,
created-by: $u
),
has created-at 2025-10-18T17:00:00Z;
Nous connectons l’utilisateur au creation relation avec $t et $u.
📝 Avis creation a le sien created-at date, distincte des entités.
Finished write query compilation and validation...
Finished writes. Printing rows...
$t | isa todo, iid 0x1e00050000000000000000
$u | isa user, iid 0x1e00040000000000000003
Finished. Total rows: 1
Insérer une Todo pour un utilisateur
Le filtrage et la recherche utilisent le mot-clé match.
match
$u isa user, has username "bob";
insert
$t isa todo,
has name "Buy groceries",
has complete false,
has created-at 2025-10-18T16:00:00Z;
creation (
created: $t,
created-by: $u
),
has created-at 2025-10-18T16:00:00Z;
On insère le do exactement de la même manière, il suffit de trouver l’utilisateur $u au lieu d’en créer un. Heureusement, le langage de requête semble être cohérent entre les mots-clés.
Finished write query compilation and validation...
Finished writes. Printing rows...
$t | isa todo, iid 0x1e00050000000000000001
$u | isa user, iid 0x1e00040000000000000002
Finished. Total rows: 1
Obtenir tous les utilisateurs
Pour les lectures, pensez à passer en mode lecture.
Interrogons tous les utilisateurs que nous venons de créer. Nous recherchons avec matchl’entité et les noms d’attribut.
match
$u isa user,
has username $username,
has created-at $created_at;
📝 Avis owns est utilisé pour définir un attribut dans un schéma, tandis que has est utilisé pour y faire référence.
Finished read query compilation and validation...
Printing rows...
$created_at | isa created-at 2025-10-18T14:00:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000001
$username | isa username "alice"
$created_at | isa created-at 2025-10-18T17:00:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000003
$username | isa username "alice"
$created_at | isa created-at 2025-10-18T14:05:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000002
$username | isa username "bob"
Finished. Total rows: 3
📝 Nous pouvons voir correctement le total sur une recherche.
Obtenir un utilisateur par ID
Chaque type a un identifiant sous-jacent, ou iidappelé ID d’instance. Ceci est généré automatiquement sous le capot.
match
$u iid 0x1e00040000000000000002;
$u isa user,
has username $username,
has created-at $created_at;
📝Un iid n’est pas un type, vous devez donc déclarer son filtre séparément.
Printing rows...
$created_at | isa created-at 2025-10-18T14:05:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000002
$username | isa username "bob"
Finished. Total rows: 1
Obtenir un utilisateur où ID IN X
Vous pouvez utiliser des parenthèses pour les clauses OR.
match
{
$u iid 0x1e00040000000000000002;
} or {
$u iid 0x1e00040000000000000001;
};
$u isa user,
has username $username,
has created-at $created_at;
Obtenir un utilisateur par nom d’utilisateur
match
$u isa user,
has username 'bob',
has created-at $created_at;
Et nous avons le décollage !
Finished read query compilation and validation...
Printing rows...
$created_at | isa created-at 2025-10-18T14:00:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000001
$username | isa username "alice"
$created_at | isa created-at 2025-10-18T14:05:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000002
$username | isa username "bob"
Finished. Total rows: 2
Obtenir l’utilisateur où le nom d’utilisateur IN X
match
{
$u isa user,
has username "bob",
has created-at $created_at;
}
or
{
$u isa user,
has username "alice",
has created-at $created_at;
};
OU
match
$u isa user,
has username $username,
has created-at $created_at;
$username like "bob|alice";
Pour le même résultat :
Finished read query compilation and validation...
Printing rows...
$created_at | isa created-at 2025-10-18T14:00:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000001
$username | isa username "alice"
$created_at | isa created-at 2025-10-18T17:00:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000003
$username | isa username "alice"
$created_at | isa created-at 2025-10-18T09:00:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000004
$username | isa username "alice"
$created_at | isa created-at 2025-10-18T14:05:00.000000000+00:00
$u | isa user, iid 0x1e00040000000000000002
$username | isa username "bob"
Finished. Total rows: 4
Obtenez toutes les tâches
De la même manière qu’on pourrait le penser.
match
$t isa todo,
has name $todo_name,
has complete $complete,
has created-at $todo_created_at;
Vos résultats peuvent varier en fonction de ce que vous avez ajouté.
Finished read query compilation and validation...
Printing rows...
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000000
$todo_created_at | isa created-at 2025-10-18T17:00:00.000000000+00:00
$todo_name | isa name "Learn TypeDB"
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000001
$todo_created_at | isa created-at 2025-10-18T16:00:00.000000000+00:00
$todo_name | isa name "Buy groceries"
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000002
$todo_created_at | isa created-at 2025-10-18T09:30:00.000000000+00:00
$todo_name | isa name "Finish TypeDB schema"
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000003
$todo_created_at | isa created-at 2025-10-18T17:00:00.000000000+00:00
$todo_name | isa name "Learn TypeDB 2"
Finished. Total rows: 4
Obtenez des tâches avec le nom d’utilisateur
Nous souhaitons généralement afficher le créateur de la tâche. Nous utilisons links pour relier le point.
match
$u isa user,
has username $username;
$t isa todo,
has name $todo_name,
has complete $complete;
$c isa creation,
links ($u, $t);
Nous pouvons également raccourcir la requête sans links.
match
$u isa user,
has username $username;
$t isa todo,
has name $todo_name,
has complete $complete;
creation ($u, $t);
Et les deux donnent le même résultat :
Finished read query compilation and validation...
Printing rows...
$c | isa creation, iid 0x1f00000000000000000001
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000001
$todo_name | isa name "Buy groceries"
$u | isa user, iid 0x1e00040000000000000002
$username | isa username "bob"
$c | isa creation, iid 0x1f00000000000000000002
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000002
$todo_name | isa name "Finish TypeDB schema"
$u | isa user, iid 0x1e00040000000000000004
$username | isa username "alice"
$c | isa creation, iid 0x1f00000000000000000003
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000003
$todo_name | isa name "Learn TypeDB 2"
$u | isa user, iid 0x1e00040000000000000005
$username | isa username "alice"
Finished. Total rows: 3
📝 Cela filtrera les tâches qui n’ont PAS de nom d’utilisateur lié.
Obtenir des Todos par un nom d’utilisateur
Normalement, nous voulons que les tâches soient confiées à une certaine personne. Dans ce cas, nous modifions la requête précédente et remplaçons simplement $username avec le nom d’utilisateur que nous voulons.
match
$u isa user,
has username 'bob';
$t isa todo,
has name $todo_name,
has complete $complete;
$c isa creation,
links ($u, $t);
Si nous voulons imprimer spécifiquement le nom d’utilisateur et avoir le filtre :
match
$u isa user,
has username $username;
$username == "bob";
$t isa todo,
has name $todo_name,
has complete $complete;
$c isa creation,
links ($u, $t);
TypeQL ne prend pas en charge le renvoi des données de style JSON, mais vous pouvez obtenir les tâches.
Finished read query compilation and validation...
Printing rows...
$c | isa creation, iid 0x1f00000000000000000005
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000000
$todo_name | isa name "Learn TypeDB"
$u | isa user, iid 0x1e00040000000000000002
$username | isa username "bob"
$c | isa creation, iid 0x1f00000000000000000001
$complete | isa complete false
$t | isa todo, iid 0x1e00050000000000000001
$todo_name | isa name "Buy groceries"
$u | isa user, iid 0x1e00040000000000000002
$username | isa username "bob"
Finished. Total rows: 2
Connecter une tâche à un utilisateur
Vous pouvez lier des entités comme prévu en utilisant match et insert sur le rapport.
match
$u isa user,
has username "bob";
$t isa todo,
has name "Learn TypeDB";
insert
creation (created-by: $u, created: $t),
has created-at 2024-01-01T00:00:00Z;
Quels résultats :
Finished write query compilation and validation...
Finished writes. Printing rows...
$t | isa todo, iid 0x1e00050000000000000000
$u | isa user, iid 0x1e00040000000000000002
Finished. Total rows: 1
Supprimer un enregistrement
Enfin, nous devons pouvoir supprimer un enregistrement.
match
$u isa user,
has username 'bob';
delete $u;
match
$u isa user;
delete $u;
📝 Ce sera un succès même si le disque n’a jamais existé. Vous pouvez également supprimer des connexions de la même manière.
Clés et indexation
TypeDB a une indexation automatique et ne vous permet pas d’indexer manuellement quoi que ce soit. Vous pouvez cependant indexer les clés avec @key et @uniquela différence étant @key ajoute requis.
entity user
owns username @key,
owns created-at,
plays creation:created-by;
Modélisation complexe
Cela ne fait qu’effleurer la surface. TypeDB brille vraiment lorsque vous utilisez l’héritage. Tu peux:
define
entity user @abstract,
owns username @key;
entity profile
sub user,
owns bio;
attribute username
value string;
attribute bio
value string;
Le sub L’attribut vous permet d’utiliser l’héritage. Un profil est de type utilisateur. Vous pouvez utiliser @abstract pour en faire juste une instance et ne peut pas être interrogée. Cela serait utile si vos sous-types stockent les données.
Fonctions et nombre
Nous pouvons également créer des fonctions. Cette fonction compte les tâches. Les fonctions sont déclarées dans schema mode. Vous utilisez le fun variable, entrez un paramètre (uniquement les entités) et sélectionnez la valeur de retour.
define
fun count_todos($u: user) -> integer:
match
$t isa todo;
$c isa creation,
links ($u, $t);
return count($c);
Et tu peux l’appeler read mode:
match
$u isa user, has username "bob";
let $count = count_todos($u);
select $count;
📝 Avis select indique au match de renvoyer uniquement le $count variable.
Finished read query compilation and validation...
Printing rows...
$count | 2
Finished. Total rows: 1
Pensées finales
J’aime vraiment TypeDB. C’est extrêmement unique et expressif. Il peut vous faire gagner de l’espace en vous permettant de partager des modèles avec un héritage et des attributs qui peuvent être utilisés de toute façon.
Est-il censé être une base de données principale ?
Je ne le vois pas, mais ça va. Je soupçonne qu’ils ont évité les fonctionnalités mathématiques de base, les fonctions RLS et de date, car la base de données n’est pas censée être une base de données principale, mais une base de données spécialisée utilisée pour modéliser facilement des concepts de données complexes. Là encore, il n’en est qu’à ses balbutiements.
Difficulté
J’ai trouvé que la base de données avait une courbe d’apprentissage beaucoup plus élevée que celle SurréalisteDb ou EdgeDB (consultez ces articles de blog pour voir par vous-même), mais cela est principalement dû au manque de bonne documentation. J’apprends tout grâce à l’IA ces jours-ci, et la plupart des IA semblaient avoir été formées sur TypeDB 2, qui avait subi de nombreuses modifications avant la sortie de TypeDB 3. Le Demandez à l’IA la fonctionnalité dans le studio était bien meilleure, mais créait toujours des requêtes pour la plupart inutilisables.
Si vous souhaitez modéliser vos données avec l’héritage et les classes, et exécuter des requêtes graphiques complexes, TypeDB est la voie à suivre. Cela vaut vraiment la peine d’être vérifié en fonction de votre cas d’utilisation.
Source link

