SQL-Datenbankstruktur für RESTful API

11

Ich erstelle eine RESTful-API. Ich habe Schwierigkeiten, mich für den besten Weg zu entscheiden, meine Datenbanktabellen um meine Ressourcen herum zu gestalten.

Anfangs dachte ich, eine Tabelle pro Ressource wäre ein guter Weg, aber jetzt mache ich mir Sorgen, dass dies zu exponentiell größeren Tabellen führen wird, je weiter Sie sich in der Ressourcenkette befinden.

Stellen Sie sich zum Beispiel vor, ich habe drei Ressourcen - Benutzer, Kunden, Vertrieb. Benutzer sind Abonnenten meiner API, Kunden sind die Kunden der Benutzer, und Verkäufe sind Käufe, die von jedem Kunden auf das Benutzerkonto getätigt werden.

Auf eine Verkaufsressource wird wie folgt zugegriffen

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

Wenn es also 10 Benutzer mit jeweils 10 Kunden gibt und für jeden Kunden 10 Verkäufe, wird die Tabellengröße umso größer, je weiter wir uns in der Ressourcenkette befinden.

Ich bin ziemlich sicher, dass SQL mit großen Tabellen umgehen kann, aber ich bin mir nicht sicher, wie Lesen und Schreiben die Dinge verlangsamen werden. Das obige Beispiel veranschaulicht es vielleicht nicht, aber meine API wird immer mehr Schreib- und Lesevorgänge haben, je weiter wir uns in der Ressourcenkette befinden. Ich habe daher das Szenario, in dem die größten Tabellen in meiner Datenbank öfter gelesen und geschrieben werden als kleinere Tabellen.

Es ist auch erforderlich, Tabellen zu verknüpfen, bevor Abfragen ausgeführt werden. Der Grund ist, dass ich jedem Benutzer erlaube, einen Client mit demselben Namen zu haben. Um zu vermeiden, dass falsche Clientdaten abgerufen werden, werden die Benutzertabelle und die Clienttabellen durch {userID} verbunden. Dies gilt auch für den Verkauf. Wird das Verbinden großer Tabellen und das Ausführen von Lese- und Schreibvorgängen die Dinge weiter verlangsamen?

Gaz_Edge
quelle

Antworten:

31

Ich habe Schwierigkeiten, mich für den besten Weg zu entscheiden, meine Datenbanktabellen um meine Ressourcen herum zu gestalten.

Tu es nicht.

Entwerfen Sie Ihre API nach RESTful- Prinzipien und Ihre Datenbank nach Normalisierungsprinzipien . Das eine muss nicht auf das andere einwirken.

Ihre Datenbank sollte keine SaleResourceTabelle enthalten , sondern eine Sale(oder Kauf- / Bestell-) Tabelle. Diese Tabelle enthält einen Primärschlüssel, der einen Verkauf und Fremdschlüssel für verwandte Benutzer- und Kundentabellen eindeutig identifiziert.

Ihre REST-API übersetzt eine Anforderung für die identifizierte Ressource GET /users/{userID}/clients/{clientID}/sales/{salesID}in die entsprechende Datenbankabfrage, ruft die Zeile ab, erstellt die Ressource, die einen Verkauf darstellt, und gibt sie an den Client zurück.

Beachten Sie, dass Sie derzeit scheinbar interne Datenbankkennungen (UserID / ClientId / SalesID) für die Außenwelt verfügbar machen. Dies mag in Ihrem Fall angemessen sein, <entity>IDfühlt sich jedoch in einer RESTful-API im Allgemeinen nicht gut an.

Mark Storey-Smith
quelle
Vielen Dank. Sie sagen also im Grunde, solange ich meine Datenbanken normalisiere und eine geeignete Indizierung usw. einrichte, sollte es keine Leistungsprobleme für das geben, was ich erreichen möchte
Gaz_Edge
3
Ja. Nichts, was Sie erwähnt haben, deutet darauf hin, dass eine Abweichung von einem normalisierten Schema erforderlich wäre.
Mark Storey-Smith
9

Relationale Datenbanken (daher SQL) sind wirklich gut darin, eine (oder mehrere) Zeilen aus einer großen Tabelle zu finden. Dafür sind Indizes da. Sie sind auch ziemlich gut im Umgang mit Joins. Du hast nicht wirklich eine Frage . Zwischen den Zeilen fragen Sie im Grunde, wie ein mandantenfähiges Datenbankdesign erstellt werden soll. Ich empfehle Ihnen, die mandantenfähige Datenarchitektur zu lesen, bevor Sie weitere Fragen stellen. Wählen Sie eines der Muster (separate Datenbank, separate Schemata für gemeinsam genutzte Datenbanken, gemeinsam genutztes Schema für gemeinsam genutzte Datenbanken), und wir können dann die Einzelheiten besprechen. Im Moment haben Sie sich nur das letzte Muster vorgestellt, aber die Vor- und Nachteile nicht berücksichtigt. Nachlesen.

Als Randnotiz: Sie brauchen nicht user/{userID}in der URI. Sie kennen den Mandanten (Benutzer-ID) aus den Authentifizierungsinformationen.

Remus Rusanu
quelle
danke- Ja, ich muss weiter nachlesen. Meine bisherigen Projekte hatten sehr wenig Datenbankarbeit. Ich werde die von Ihnen empfohlene Ressource lesen
Gaz_Edge
Ich denke, Shared-Shared ist der richtige Weg für mich. Meine "Benutzer" sind keine "Mieter". Sie benötigen keine isolierten Daten und benötigen niemals direkten Zugriff auf Datenbankverwaltungsfunktionen. Nach dem, was ich gelesen habe, würde dies bedeuten, dass Shared-Shared am besten ist. Was denkst du?
Gaz_Edge
2
geteilt ist das einfachste. Sie müssen das user_idals Schlüssel zu jeder Tabelle hinzufügen und left.user_id = right.user_idzu relevanten Verknüpfungen hinzufügen (normalerweise alle). Einige ORMs unterstützen das Löschen des Zugriffs. Und lassen Sie sich nicht täuschen, Ihre Benutzer sind Mieter, da Sie nicht möchten, dass Benutzer 'foo' die Verkäufe von Benutzer 'bar' sieht / ändert.
Remus Rusanu
Vielen Dank. Ich fange an zu sehen, dass Indizes der Schlüssel zum Erstellen meiner Datenbankstruktur sind.
Gaz_Edge
0

Um das bereits Gesagte zu ergänzen, möchten Sie möglicherweise eine Schnittstelle zwischen der eigentlichen API und Ihrer Datenbankebene erstellen. Es erleichtert das Hinzufügen von Caching- und Übersichtstabellen auf der ganzen Linie ...

Matt Koskela
quelle
1
Einige Links oder weitere Erklärungen wären hilfreich
Gaz_Edge
Sorry, kann noch keinen Kommentar abgeben ..
Matt Koskela