La base de données de graphiques du futur: Surrealdb

Fixez les pneus sur SurrealDB. C’est comme SQL, NOSQL et une base de données de graphiques tout en un, avec une offre de nuages solide et une chance de quitter les jointures dans la poussière.
SurrealDB est impressionnant et polyvalent. Nous ne devons jamais avoir à faire face aux jointures, car ce n’est pas ainsi que nous lisons réellement les données. Se débarrasser d’un schéma rend le développement très rapidement. Surreal Cloud sera un excellent outil pour créer votre base de données en 2025 et au-delà.
Configuration du nuage surréaliste
Tout d’abord, connectez-vous à Nuage surréaliste et créer une instance de base de données.
Sélectionnez une région.
Et vous pouvez avoir exactement une instance gratuite.
Une fois que votre instance de base de données est créée et provisionnée, vous devez vous connecter.
Nous nous connecterons à la base de données avec surréaliste.
Nous avons besoin d’un espace de noms. Les espaces de noms sont magnifiques car ils vous permettent d’utiliser la même base de données pour plusieurs applications.
Et nous avons besoin d’une base de données pour stocker nos données. Avant de pouvoir créer des requêtes, nous avons besoin à la fois de l’espace de noms et de la base de données.
Requêtes
SurrealDB stocke chaque enregistrement comme un identifiant. Chaque enregistrement a un id
Field, c’est ainsi qu’il est référencé. 📝 Un ID est créé automatiquement avec le nom de la table et le :
préfixe.
Insérer un record
Nous pouvons create
un nouveau record, ou nous pouvons insert
Un enregistrement comme dans SQL traditionnel.
CREATE profiles SET
name = 'Jon',
created_at = time::now();
INSERT INTO profiles {
name: 'Bill',
created_at: time::now()
};
INSERT INTO profiles (name, created_at)
VALUES ('Tim', time::now());
Ces déclarations ont le même résultat.
Vous pouvez également créer un profil avec un nom d’utilisateur pour un ID.
create profiles:jon set created_at = time::now();
📝 Comme SQL, les commandes de requête ne sont pas sensibles à la casse.
Mettre à jour un enregistrement
UPDATE profiles:6bdt2zwtujsb1csf2i59
SET name = 'Bill';
UPDATE profiles
SET name = 'Phil'
WHERE id = profiles:vp40hcw66sx217qhzc5l;
Vous pouvez mettre à jour directement par l’ID.
Supprimer un record
DELETE profiles:vp40hcw66sx217qhzc5l;
Vous supprimez par l’ID.
REMOVE TABLE profiles;
Vous pouvez également supprimer toute la table.
Sélectionnez un enregistrement
SELECT * FROM profiles.
Le Surrealql est très similaire à SQL, moins les jointures. Les jointures sont atteintes par d’autres moyens.
Notre première application de notes
Voyons comment créer une application de notes.
Créer un utilisateur
CREATE users:jon SET
name="Jon Bon Jovi",
created_at = time::now();
Nous utiliserons le nom d’utilisateur comme ID.
📝 avis time::now()
gère l’objet de date actuel.
Insérer des notes
INSERT INTO notes [
{
title: "Grocery List",
content: "Buy milk, bread, and eggs.",
created_by: users:jon,
tags: [
(CREATE tags SET name = "personal"),
(CREATE tags SET name = "shopping")
]
},
{
title: "Work Meeting",
content: "Prepare slides for Monday's meeting.",
created_by: users:jon,
tags: [
(CREATE tags SET name = "work"),
(CREATE tags SET name = "urgent")
]
}
];
📌 Remarquez comment nous pouvons utiliser des instructions imbriquées pour créer des balises imbriquées.
📝 Nous pourrions économiser tags
Dans un tableau, mais ils ne seraient pas accessibles au niveau supérieur. Lorsque nous avons mis directement les données imbriquées dans un tableau, les données sont stockées comme une base de données NoSQL. Si nous définissons les balises en tant que requête, ce que nous pouvons, elle interrogera les balises au moment de la création. Nous voulons cette dynamique.
SELECT * FROM tags;
SELECT * FROM notes;
SELECT * FROM users;
Il est essentiel de pouvoir interroger facilement toutes les balises.
Interroger toutes les notes de l’utilisateur
Sans rejoindre, ce n’était pas aussi intuitif. Il y a des variables d’assistance comme $parent
pour aider.
SELECT *, (SELECT * FROM notes WHERE created_by = $parent.id) AS notes FROM users;
je DÉTESTER Joint, mais des requêtes imbriquées comme celle-ci peuvent être laides. Heureusement, il existe une nouvelle fonctionnalité dans une future version appelée Références.
Résultats
[ { created_at: d'2025-01-26T01:51:19.546Z', id: users:jon, name: 'Jon Bon Jovi', notes: [ { content: "Prepare slides for Monday's meeting.", created_by: users:jon, id: notes:jaljrarnbop94hs6lq3b, tags: [ [ { id: tags:zwtvzp2absdzfk6px3tr, name: 'work' } ], [ { id: tags:d47oioglv7s9548l9b7y, name: 'urgent' } ] ], title: 'Work Meeting' }, { content: 'Buy milk, bread, and eggs.', created_by: users:jon, id: notes:wlu8y3kamqyzxnz6ah4r, tags: [ [ { id: tags:snrpfzvabw131btgay5m, name: 'personal' } ], [ { id: tags:0tk6mr1eg2v1g17y4nji, name: 'shopping' } ] ], title: 'Grocery List' } ] } ]
Insérer différemment
CREATE users:jon SET
name = 'Jon Bon Jovi',
created_at = time::now(),
notes = [
(INSERT INTO notes {
title: "Grocery List",
content: "Buy milk, bread, and eggs.",
created_by: users:jon,
tags: [
(CREATE tags SET name = "personal"),
(CREATE tags SET name = "shopping")
]
}),
(INSERT INTO notes {
title: "Work Meeting",
content: "Prepare slides for Monday's meeting.",
created_by: users:jon,
tags: [
(CREATE tags SET name = "work"),
(CREATE tags SET name = "urgent")
]
})
];
J’aurais pu insérer les données initialement comme celle-ci, mais je créerais manuellement les nœuds dans chaque direction avec created_by
et notes[]
. Je veux que ce soit dynamique.
Notre deuxième application de notes
SurrealDB est également une base de données de graphiques. Considérons-le graphiquement et voyons si les requêtes dynamiques sont meilleures.
CREATE users:jon SET
name = 'Jon Bon Jovi',
created_at = time::now();
LET $notes = INSERT INTO notes [
{
title: "Grocery List",
content: "Buy milk, bread, and eggs."
},
{
title: "Work Meeting",
content: "Prepare slides for Monday's meeting."
}
];
FOR $note IN $notes {
RELATE users:jon->created->$note;
};
Laisser et boucler
Vous pouvez parcourir un tableau d’articles avec FOR
et IN
. Dans notre cas, nous retournons le INSERT
déclaration et la définir comme une variable avec LET
. La variable contient désormais le créé id
pour chaque note.
Se rapporter
RELATE @from_record_id->@table->@to_record_id
Nous créons une relation dans laquelle chaque utilisateur created
une note.
RELATE users:jon->created->$note;
📝 La pratique standard consiste à utiliser le passé.
SELECT *, ->created->notes.* AS notes FROM users;
SELECT *, <-created<-users.* AS created_by FROM notes;
Maintenant, nous pouvons obtenir des utilisateurs dynamiquement avec des notes ou des notes par les utilisateurs.
📌 Les deux directions fonctionnent en déclarant uniquement une direction. Nous changeons simplement entre ->
et <-
.
Supprimer une relation
Si nous voulions initialement définir de l’autre sens, nous devons supprimer les relations.
// all created relationships
DELETE users:jon->created;
// individually
DELETE users:jon->created->notes:2xeslis2isljelbsiehq
Relation inversée
Ensuite, nous allions redéclaterions notre insert d’origine avec le bord inverse.
...
FOR $note IN $notes {
RELATE $note->created_by->users:jon;
};
Et nos sélections seraient également inversées.
SELECT *, <-created_by<-notes.* AS notes FROM users;
SELECT *, ->created_by->users.* AS created_by FROM notes;
⚠️ Choisissez une direction ou l’autre lorsque vous définissez initialement RELATE
. SurrealDB vous permettra de traverser en sens inverse. Créant deux RELATE
Les déclarations pour la même relation seraient redondantes et vous gaspilleriez l’espace de base de données.
Tableau à célibataire
SELECT *, (->created_by->users)[0].* AS created_by FROM notes;
Parfois, nous pouvons retourner un tableau lorsque nous n’avons qu’un seul enregistrement. Nous ne pouvons sélectionner que le premier résultat et modifier la forme de notre résultat pour être un objet à la place, tout comme un tableau en js.
Résultats
-------- Query 1 (385.723µs) -------- [ { created_at: d'2025-01-26T15:04:14.661Z', id: users:jon, name: 'Jon Bon Jovi', notes: [ { content: 'Buy milk, bread, and eggs.', id: notes:56l2cw48oodjvnmy6b30, title: 'Grocery List' }, { content: "Prepare slides for Monday's meeting.", id: notes:ntuhp5danslcihrgotm0, title: 'Work Meeting' } ] } ] -------- Query 2 (349.703µs) -------- [ { content: 'Buy milk, bread, and eggs.', created_by: { created_at: d'2025-01-26T15:04:14.661Z', id: users:jon, name: 'Jon Bon Jovi' }, id: notes:56l2cw48oodjvnmy6b30, title: 'Grocery List' }, { content: "Prepare slides for Monday's meeting.", created_by: { created_at: d'2025-01-26T15:04:14.661Z', id: users:jon, name: 'Jon Bon Jovi' }, id: notes:ntuhp5danslcihrgotm0, title: 'Work Meeting' } ]
Balises
// users with notes
SELECT *, (SELECT *, ->has_tag->tags.* AS tags FROM <-created_by<-notes) AS notes FROM users;
// OR
SELECT *, <-created_by<-notes.{title, content, tags: ->has_tag->tags.*} AS notes FROM users;
// notes with users
SELECT *, (->created_by->users)[0].* as created_by, ->has_tag->tags.* as tags from notes;
Et nous devons également obtenir nos balises dans les deux directions.
Résultats
-------- Query 1 (680.018µs) -------- [ { created_at: d'2025-01-26T16:38:49.420Z', id: users:jon, name: 'Jon Bon Jovi', notes: [ { content: 'Buy milk, bread, and eggs.', id: notes:vi8zarmcqvqva2y0vfkv, tags: [ { id: tags:personal }, { id: tags:shopping } ], title: 'Grocery List' }, { content: "Prepare slides for Monday's meeting.", id: notes:la6nzl7xc25r8lk8vv8n, tags: [ { id: tags:work }, { id: tags:urgent } ], title: 'Work Meeting' } ] } ] -------- Query 2 (505.966µs) -------- [ { content: "Prepare slides for Monday's meeting.", created_by: { created_at: d'2025-01-26T16:38:49.420Z', id: users:jon, name: 'Jon Bon Jovi' }, id: notes:la6nzl7xc25r8lk8vv8n, tags: [ { id: tags:work }, { id: tags:urgent } ], title: 'Work Meeting' }, { content: 'Buy milk, bread, and eggs.', created_by: { created_at: d'2025-01-26T16:38:49.420Z', id: users:jon, name: 'Jon Bon Jovi' }, id: notes:vi8zarmcqvqva2y0vfkv, tags: [ { id: tags:personal }, { id: tags:shopping } ], title: 'Grocery List' } ]
Compte
count(SELECT 1 FROM notes);
// OR WITH GROUP BY
SELECT count() from notes GROUP BY count LIMIT 1;
// RETURNING OBJECT
(SELECT count() from notes GROUP BY count LIMIT 1)[0];
// RETURNS
{
count: 2
}
Le comptage est assez simple. Enveloppez simplement votre requête dans un count()
fonction. Si nous ne sélectionnons rien, nous voulons utiliser 1
Au lieu des champs, nous voulons retourner.
Schéma
Nous pouvons voir notre schéma des tables que nous avons créées. SurrealDB est une base de données multi-types. C’est noSQL
, SQL
et un graph
base de données tout en un. Un schéma n’est pas nécessaire mais utile à mesure que nos applications évoluent.
Contrainte
Un schéma n’est qu’une contrainte sur nos données. Nous pouvons également ajouter cela à SurrealDB. Lorsque nous créons une table, nous pouvons utiliser le SCHEMAFULL
mot-clé et définissez nos champs individuellement.
DEFINE TABLE profiles SCHEMAFULL;
DEFINE FIELD name ON profiles TYPE string;
DEFINE FIELD created_by ON profiles TYPE string;
Manuscrit
// Create a record with a specific ID
const person = await db.create<Person>(new RecordId('person', 'tobie'), {
name: 'Tobie',
settings: {
active: true,
marketing: true,
},
});
SurrealDB a un magnifique package de typeScript. Bien que les types ne soient pas générés automatiquement comme les autres ORM ou les bases de données, cela est à prévoir car nous avons affaire à plusieurs types de bases de données, schémas et à utiliser un schéma.
Réflexions finales
J’ai vraiment aimé travailler avec SurrealQL. La base de données est un adolescent, mais pas un bébé. Il y avait quelques fonctionnalités que j’ai demandées qui ont été récemment publiées dans la version bêta et pas encore disponible sur le cloud. La courbe d’apprentissage était légèrement plus élevée que je l’espérais parce que les documents manquaient suffisamment d’exemples simples et simples. Cependant, lorsque j’ai posé des questions sur Discord, ils ont généralement reçu une réponse dans l’heure. La communauté et le personnel sont très utiles.
SurrealDB est puissant et peut répondre à tous vos besoins de requête.
Je le recommande vivement.
Source link