Hintergrund:
Ich entwerfe eine Serveranwendung und erstelle separate DLLs für verschiedene Subsysteme. Nehmen wir zur Vereinfachung an, ich habe zwei Subsysteme: 1) Users
2)Projects
Die öffentliche Benutzeroberfläche der Benutzer hat eine Methode wie:
IEnumerable<User> GetUser(int id);
Die öffentliche Oberfläche von Projects verfügt über eine Methode wie:
IEnumerable<User> GetProjectUsers(int projectId);
Wenn wir beispielsweise die Benutzer für ein bestimmtes Projekt anzeigen müssen, können wir aufrufen, GetProjectUsers
und dies gibt Objekte mit ausreichenden Informationen zurück, um sie in einem Datagrid oder ähnlichem anzuzeigen.
Problem: Im
Idealfall sollte das Projects
Subsystem nicht auch Benutzerinformationen und nur die IDs der an einem Projekt beteiligten Benutzer speichern. Um das zu bedienen GetProjectUsers
, muss es GetUser
das Users
System für jede Benutzer-ID aufrufen, die in seiner eigenen Datenbank gespeichert ist. Dies erfordert jedoch viele separate GetUser
Aufrufe, was viele separate SQL-Abfragen innerhalb des User
Subsystems verursacht. Ich habe dies nicht wirklich getestet, aber dieses gesprächige Design wirkt sich auf die Skalierbarkeit des Systems aus.
Wenn ich die Trennung der Subsysteme beiseite lege, könnte ich alle Informationen in einem einzigen Schema speichern, auf das beide Systeme zugreifen können, und Projects
einfach JOIN
alle Projektbenutzer in einer einzigen Abfrage abrufen. Projects
müsste auch wissen, wie man User
Objekte aus den Abfrageergebnissen generiert . Dies bricht jedoch die Trennung, die viele Vorteile hat.
Frage:
Kann jemand einen Weg vorschlagen, um die Trennung beizubehalten und gleichzeitig all diese einzelnen GetUser
Anrufe zu vermeiden GetProjectUsers
?
Ich hatte beispielsweise die Idee, dass Benutzer externen Systemen die Möglichkeit geben sollten, Benutzer mit einem Label-Wert-Paar zu "markieren" und Benutzer mit einem bestimmten Wert anzufordern, z.
void AddUserTag(int userId, string tag, string value);
IEnumerable<User> GetUsersByTag(string tag, string value);
Dann könnte das Projektsystem jeden Benutzer markieren, wenn er dem Projekt hinzugefügt wird:
AddUserTag(userId,"project id", myProjectId.ToString());
und während GetProjectUsers könnten alle Projektbenutzer in einem einzigen Aufruf angefordert werden:
var projectUsers = usersService.GetUsersByTag("project id", myProjectId.ToString());
Der Teil, bei dem ich mir nicht sicher bin, ist: Ja, Benutzer sind projektunabhängig, aber die Informationen zur Projektmitgliedschaft werden im Benutzersystem gespeichert, nicht in Projekten. Ich fühle mich einfach nicht natürlich, also versuche ich festzustellen, ob es hier einen großen Nachteil gibt, den ich vermisse.
quelle
GetUser
Anstatt die Datenbank abzufragen , wird im Cache gesucht . Dies bedeutet, dass es eigentlich egal ist, wie oft Sie aufrufenGetUser
, da Daten aus dem Speicher anstelle der Datenbank geladen werden (es sei denn, der Cache wurde ungültig gemacht).select
Abfragen pro Tag gibt, sollten Sie das Caching verwenden. Wenn Sie jedoch Milliarden von Entitäten zu einer Datenbank hinzufügen, aber nur einige Tausend vonselect
s mit sehr selektivenwhere
s erhalten, ist das Caching möglicherweise nicht so nützlich.