Struttura del database SQL per API RESTful


11

Sto creando un'API RESTful. Faccio fatica a decidere il modo migliore per progettare le mie tabelle di database in base alle mie risorse.

Inizialmente, ho pensato che una tabella per risorsa sarebbe una buona strada da percorrere, ma ora sono preoccupata che ciò si tradurrà in tabelle esponenzialmente più grandi più in basso nella catena di risorse si va.

Ad esempio, immagina di avere tre risorse: utenti, clienti, vendite. Gli utenti sono abbonati alla mia API, i clienti sono i clienti degli utenti e le vendite sono gli acquisti effettuati da ciascun cliente sull'account degli utenti.

Una risorsa di vendita è accessibile come segue

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

Quindi, se ci sono 10 utenti, ciascuno con 10 clienti e per ogni cliente ci sono 10 vendite, la dimensione della tabella aumenta con l'avanzare della catena di risorse.

Sono abbastanza sicuro che SQL sia in grado di far fronte a tabelle di grandi dimensioni, ma non sono sicuro di come rallenteranno le operazioni di lettura e scrittura. L'esempio sopra forse non lo illustra, ma la mia API avrà progressivamente più scritture e letture più in basso nella catena di risorse che andiamo. Ho quindi lo scenario in cui le tabelle più grandi nel mio database verranno lette e scritte più volte rispetto alle tabelle più piccole.

Sarà inoltre necessario unire le tabelle prima di eseguire le query. Il motivo è che consento a ciascun utente di avere un client con lo stesso nome. Per evitare di ottenere dati client errati, la tabella utenti e le tabelle client vengono unite da {userID}. Questo vale anche per le vendite. Unire tabelle di grandi dimensioni ed eseguire letture e scritture rallenta ulteriormente le cose?

Risposte:


31

Faccio fatica a decidere il modo migliore per progettare le mie tabelle di database in base alle mie risorse.

Non farlo.

Progetta la tua API secondo i principi RESTful , progetta il tuo database secondo i principi di normalizzazione . Uno non ha bisogno di avere un impatto sull'altro.

Il database non deve contenere una SaleResourcetabella, deve contenere una tabella Sale(o acquisto / ordine). Tale tabella includerà una chiave primaria che identifica in modo univoco una vendita e chiavi esterne per le relative tabelle utente e cliente.

API REST tradurrà una richiesta per la risorsa identificata dalla GET /users/{userID}/clients/{clientID}/sales/{salesID}query del database appropriata, recupererà la riga, costruirà la risorsa che rappresenta una vendita e la restituirà al client.

Ricorda che stai attualmente esponendo al mondo esterno quelli che sembrano essere identificatori di database interni (UserID / ClientId / SalesID). Può essere appropriato nel tuo caso, ma generalmente si <entity>IDsente in un'API RESTful.


Grazie. Quindi quello che stai sostanzialmente dicendo è che fintanto che normalizzo i miei database e installo l'indicizzazione appropriata, ecc., Non ci dovrebbero essere problemi di prestazioni per quello che voglio ottenere
Gaz_Edge,

3
Sì. Nulla di ciò che hai menzionato suggerisce che sarebbe necessario deviare da uno schema normalizzato.
Mark Storey-Smith,

9

I database relazionali (quindi SQL) sono davvero bravi a localizzare una (o poche) righe da una grande tabella. Ecco a cosa servono gli indici. Sono anche fantastici nel gestire i join. Non hai davvero una domanda . Tra le righe, in pratica stai chiedendo come fare una progettazione di database multi-tenant. Ti suggerisco di leggere Multi-Tenant Data Architecture prima di porre ulteriori domande. Scegli uno dei modelli (database separato, schemi separati di database condiviso, schema condiviso di database condiviso) e quindi discuteremo delle specifiche. In questo momento immagini solo l'ultimo schema, ma non hai considerato i pro ei contro. Documentarsi.

Come nota a margine: non è necessario user/{userID}nell'URI. Conosci l'inquilino (userID) dalle informazioni di autenticazione.


grazie- Sì, ho bisogno di leggere ulteriormente. Finora i miei progetti hanno avuto un lavoro di database molto limitato.
Leggerò

Penso che la condivisione sia la strada giusta per me. I miei "utenti" non sono "inquilini". Non richiedono dati isolati e non avranno mai bisogno dell'accesso diretto a nessuna funzione di gestione del database. Da quello che ho letto, ciò suggerirebbe che la condivisione condivisa è la cosa migliore? Cosa ne pensi?
Gaz_Edge,

2
condiviso è il più semplice. È necessario aggiungere la user_idchiave come in ogni tabella e aggiungere i left.user_id = right.user_idjoin pertinenti (in genere, tutti). Alcuni ORM supportano il blocco dell'accesso. E non lasciarti ingannare, i tuoi utenti sono tenant, dal momento che non vuoi che l'utente 'foo' veda / modifichi le vendite dell'utente 'bar'.
Remus Rusanu,

Grazie. Sto cominciando a vedere che gli indici sono fondamentali per creare la mia struttura di database.
Gaz_Edge,

0

Solo per aggiungere ciò che è già stato detto qui, potresti voler creare un'interfaccia tra l'API effettiva e il tuo livello di database. Semplifica l'aggiunta di cache e tabelle riepilogative più facilmente ...


1
alcuni link o ulteriori spiegazioni sarebbero utili
Gaz_Edge,

Siamo spiacenti, non posso ancora commentare ..
Matt Koskela,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.