Contexte:
Je conçois une application serveur et crée des DLL distinctes pour différents sous-systèmes. Pour simplifier les choses, disons que j'ai deux sous-systèmes: 1) Users
2)Projects
L'interface publique des utilisateurs a une méthode comme:
IEnumerable<User> GetUser(int id);
Et l'interface publique de Projects a une méthode comme:
IEnumerable<User> GetProjectUsers(int projectId);
Ainsi, par exemple, lorsque nous devons afficher les utilisateurs pour un certain projet, nous pouvons appeler GetProjectUsers
et cela donnera des objets avec suffisamment d'informations pour les afficher dans une grille de données ou similaire.
Problème:
Idéalement, le Projects
sous - système ne devrait pas également stocker les informations utilisateur et il devrait simplement stocker les identifiants des utilisateurs participant à un projet. Afin de servir le GetProjectUsers
, il doit appeler GetUser
le Users
système pour chaque identifiant utilisateur stocké dans sa propre base de données. Cependant, cela nécessite un grand nombre d' GetUser
appels séparés , ce qui entraîne de nombreuses requêtes SQL séparées à l'intérieur du User
sous - système. Je n'ai pas vraiment testé cela, mais avoir cette conception bavarde affectera l'évolutivité du système.
Si je mets de côté la séparation des sous-systèmes, je pourrais stocker toutes les informations dans un seul schéma accessible par les deux systèmes et Projects
pourrait simplement faire un JOIN
pour obtenir tous les utilisateurs du projet dans une seule requête. Projects
aurait également besoin de savoir comment générer des User
objets à partir des résultats de la requête. Mais cela rompt la séparation qui présente de nombreux avantages.
Question:
Quelqu'un peut-il suggérer un moyen de maintenir la séparation tout en évitant tous ces GetUser
appels individuels pendant GetProjectUsers
?
Par exemple, je pensais que les utilisateurs pouvaient donner aux systèmes externes la possibilité de «baliser» les utilisateurs avec une paire étiquette-valeur et de demander aux utilisateurs avec une certaine valeur, par exemple:
void AddUserTag(int userId, string tag, string value);
IEnumerable<User> GetUsersByTag(string tag, string value);
Ensuite, le système Projets pourrait marquer chaque utilisateur au fur et à mesure qu'il est ajouté au projet:
AddUserTag(userId,"project id", myProjectId.ToString());
et pendant GetProjectUsers, il pourrait demander à tous les utilisateurs du projet en un seul appel:
var projectUsers = usersService.GetUsersByTag("project id", myProjectId.ToString());
La partie dont je ne suis pas sûr est la suivante: oui, les utilisateurs sont indépendants des projets, mais en réalité, les informations sur l'appartenance au projet sont stockées dans le système des utilisateurs, pas dans les projets. Je ne me sens tout simplement pas naturel, alors j'essaie de déterminer s'il y a un gros inconvénient ici qui me manque.
la source
GetUser
au lieu d'interroger la base de données, il cherchera dans le cache. Cela signifie que peu importe le nombre de fois que vous appellerezGetUser
, car il chargera les données de la mémoire au lieu de la base de données (sauf si le cache a été invalidé).select
requêtes par jour, vous feriez mieux d'utiliser la mise en cache. D'un autre côté, si vous ajoutez des milliards d'entités à une base de données mais que vous n'obtenez que quelques milliers deselect
s avec des s très sélectifswhere
, la mise en cache peut ne pas être très utile.