MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment gérer les documents circulaires dans MongoDB/DynamoDB ?

Alors que NoSQL recommande généralement la la dénormalisation de modèles de données, il est préférable de ne pas avoir une liste illimitée dans une seule entrée de base de données. Pour modéliser ces données dans DynamoDB, vous devez utiliser un liste de contiguïté pour modéliser la relation plusieurs à plusieurs . Il n'y a pas de rentabilité façon de modéliser les données, que je connais, pour vous permettre d'obtenir toutes les données que vous voulez en un seul appel. Cependant, vous avez dit que la vitesse est le plus important (sans donner d'exigence de latence), je vais donc essayer de vous donner une idée de la vitesse à laquelle vous pouvez obtenir les données si elles sont stockées dans DynamoDB.

Vos schémas deviendraient quelque chose comme ceci :

Actor {
    ActorId, <-- This is the application/database id, not the actor's actual ID
    Name,
    Age,
    Bio
}

Film {
    FilmId, <-- This is the application/database id for the film
    Title,
    Description,
    ReleaseDate
}

ActedIn {
    ActorId,
    FilmId
}

Pour indiquer qu'un acteur a joué dans un film, il vous suffit d'effectuer une écriture (qui correspond toujours à des millisecondes à un chiffre en utilisant DynamoDB d'après mon expérience) pour ajouter un élément ActedIn à votre table.

Pour obtenir tous les films d'un acteur, vous devez interroger une fois pour obtenir tous les acteurs dans les relations, puis lire un lot pour obtenir tous les films. Les latences typiques pour une requête (d'après mon expérience) sont inférieures à 10 ms, en fonction de la vitesse du réseau et de la quantité de données envoyées sur le réseau. Étant donné que la relation ActedIn est un si petit objet, je pense que vous pouvez vous attendre à un cas moyen de 5 ms pour une requête, si votre requête provient de quelque chose qui s'exécute également dans un centre de données AWS (EC2, Lambda, etc.).

Obtenir un seul élément va prendre moins de 5 ms, et vous pouvez le faire en parallèle. Il existe également une API BatchGetItems, mais je n'ai pas de statistiques pour vous à ce sujet.

Alors, est-ce que ~10 ms est assez rapide pour vous ?

Sinon, vous pouvez utiliser DAX , qui ajoute une couche de mise en cache à DynamoDB et promet une latence de requête de <1 ms.

Quel est le moyen non maintenable et non rentable de le faire en un seul appel ?

Pour chaque relation ActedIn, stockez vos données comme ceci :

ActedIn {
    ActorId,
    ActorName,
    ActorAge,
    ActorBio,
    FilmId,
    FilmTitle,
    FilmDescription,
    FilmReleaseDate
}

Il vous suffit de faire une requête pour un acteur donné pour obtenir tous les détails de son film, et une seule requête pour obtenir tous les détails de l'acteur pour un film donné. Ne faites pas ça. Les données dupliquées signifient que chaque fois que vous devez mettre à jour les détails d'un acteur, vous devez les mettre à jour pour chaque film dans lequel il se trouvait, et de même pour les détails du film. Ce sera un cauchemar opérationnel.

Je ne suis pas convaincu ; il semble que NoSQL soit terrible pour cela.

Vous devez vous rappeler que NoSQL existe en plusieurs variétés (NoSQL =Not Only SQL), et donc même si une solution NoSQL ne fonctionne pas pour vous, vous ne devez pas l'exclure complètement. Si vous en avez absolument besoin en un seul appel, vous devriez envisager d'utiliser une base de données de graphes (qui est un autre type de base de données NoSQL).