Structure de base de données SQL pour l'API RESTful

11

Je crée une API RESTful. J'ai du mal à décider de la meilleure façon de concevoir mes tables de base de données autour de mes ressources.

Au départ, je pensais qu'une table par ressource serait une bonne façon de procéder, mais je crains maintenant que cela ne se traduise par des tables exponentiellement plus grandes au fur et à mesure de la chaîne de ressources.

Par exemple, imaginez que j'ai trois ressources: les utilisateurs, les clients et les ventes. Les utilisateurs sont abonnés à mon API, les clients sont les utilisateurs des clients et les ventes sont des achats effectués par chaque client sur le compte des utilisateurs.

Une ressource de vente est accessible comme suit

GET /users/{userID}/clients/{clientID}/sales/{salesID}

Donc, s'il y a 10 utilisateurs, chacun avec 10 clients, et pour chaque client il y a 10 ventes, la taille de la table augmente au fur et à mesure de la chaîne de ressources.

Je suis assez confiant que SQL peut gérer de grandes tables, mais je ne sais pas comment la lecture et l'écriture ralentiront les choses. L'exemple ci-dessus ne l'illustre peut-être pas, mais mon API aura progressivement plus d'écritures et de lectures au fur et à mesure de la chaîne de ressources. J'ai donc le scénario où les plus grandes tables de ma base de données seront lues et écrites plus souvent que les petites tables.

Il sera également nécessaire de joindre des tables avant d'exécuter des requêtes. La raison en est que j'autorise chaque utilisateur à avoir un client du même nom. Pour éviter d'obtenir des données client incorrectes, la table des utilisateurs et les tables des clients sont jointes par {userID}. C'est également le cas pour les ventes. Rejoindre de grandes tables et exécuter des lectures et des écritures ralentira-t-il encore les choses?

Gaz_Edge
la source

Réponses:

31

J'ai du mal à décider de la meilleure façon de concevoir mes tables de base de données autour de mes ressources.

Non.

Concevez votre API selon les principes RESTful , concevez votre base de données selon les principes de normalisation . L'un n'a pas besoin d'avoir un impact sur l'autre.

Votre base de données ne doit pas contenir de SaleResourcetable, elle doit contenir une table Sale(ou achat / commande). Cette table comprendra une clé primaire qui identifie de manière unique une vente et des clés étrangères aux tables utilisateur et client associées.

Votre API REST traduira une requête pour la ressource identifiée par GET /users/{userID}/clients/{clientID}/sales/{salesID}dans la requête de base de données appropriée, récupérera la ligne, construira la ressource qui représente une vente et la renverra au client.

N'oubliez pas que vous exposez actuellement ce qui semble être des identificateurs de base de données internes (UserID / ClientId / SalesID) au monde extérieur. Cela peut être approprié dans votre cas, mais se <entity>IDsent généralement dans une API RESTful.

Mark Storey-Smith
la source
Merci. Donc, ce que vous dites, c'est que tant que je normalise mes bases de données et que je configure une indexation appropriée, etc., il ne devrait y avoir aucun problème de performances pour ce que je veux réaliser
Gaz_Edge
3
Oui. Rien de ce que vous avez mentionné ne suggère de s'écarter d'un schéma normalisé serait nécessaire.
Mark Storey-Smith
9

Les bases de données relationnelles (d'où SQL) sont très efficaces pour localiser une (ou quelques) lignes d'une immense table. C'est à cela que servent les index. Ils sont également assez géniaux pour gérer les jointures. Vous n'avez pas vraiment de question . Entre les lignes, vous demandez essentiellement comment faire une conception de base de données multi-locataire. Je vous suggère de lire l' architecture de données multi-locataire avant de poser d'autres questions. Choisissez l'un des modèles (base de données distincte, schémas séparés de base de données partagée, schéma partagé de base de données partagée), puis nous allons discuter des spécificités. À l'heure actuelle, vous n'envisagez que le dernier modèle, mais ne considérez pas les avantages et les inconvénients. Lisez.

En remarque: vous n'avez pas besoin user/{userID}de l'URI. Vous connaissez le locataire (ID utilisateur) à partir des informations d'authentification.

Remus Rusanu
la source
merci- Ouais j'ai besoin de lire plus loin. Mes projets à ce jour ont eu très peu de travail de base de données. Je vais lire la ressource que vous avez recommandée
Gaz_Edge
Je pense que le partage partagé est la voie à suivre pour moi. Mes «utilisateurs» ne sont pas des «locataires». Ils ne nécessitent pas de données isolées et n'auront jamais besoin d'accéder directement à des fonctions de gestion de base de données. D'après ce que j'ai lu, cela suggérerait que le partage partagé est le meilleur? Qu'est-ce que tu penses?
Gaz_Edge
2
partagé est le plus simple. Vous devez ajouter le en user_idtant que clé à chaque table et ajouter left.user_id = right.user_idaux jointures pertinentes (généralement, toutes). Certains ORM prennent en charge la suppression de l'accès. Et ne vous y trompez pas, vos utilisateurs sont locataires, car vous ne voulez pas que l'utilisateur 'foo' voie / modifie les ventes de l'utilisateur 'bar'.
Remus Rusanu
Merci. Je commence à voir que les index sont essentiels pour créer ma structure de base de données.
Gaz_Edge
0

Juste pour ajouter à ce qui a déjà été dit ici - vous voudrez peut-être créer une interface entre l'API réelle et votre couche de base de données. Cela facilite l'ajout de cache et de tableaux récapitulatifs sur toute la ligne ...

Matt Koskela
la source
1
des liens ou des explications supplémentaires seraient utiles
Gaz_Edge
Désolé, je ne peux pas encore commenter ..
Matt Koskela