Ho riflettuto su questo già da alcuni giorni, facendo diagrammi, iniziato a programmare, ripristinato, ricominciato, non riesco ancora a decidere quale sia l'approccio migliore.
Il problema consiste nel condividere gruppi di elementi con altri utenti, dove possono ottenere / aggiungere / modificare / rimuovere, in tempo reale.
I miei articoli sono in particolare "articoli della lista" che fanno riferimento a "prodotti" che fanno riferimento a "categorie di prodotti". Tutte queste entità usano uuids. Quindi un elemento della lista ha un uuid, un prodotto ha un uuid, una categoria di prodotto ha un uuid. Nel database usano chiavi esterne e fanno riferimento alle dipendenze tramite uuids.
Quindi per condividere un elenco, che è un gruppo di voci di elenco, con altri utenti, ho ristretto le possibili soluzioni a questi 2:
-
Replica tutto per ciascun utente. In questo modo ogni utente ha i propri articoli, prodotti e categorie di prodotti. Le voci dell'elenco ottengono una relazione n: n con gli utenti, e ovviamente filtro le voci dell'elenco per l'utente che le richiede. Aggiungi / aggiorna / cancella deve essere eseguita sempre per le copie di tutti gli utenti, in una transazione. Quindi per esempio l'utente A ha "pane" con uuid "1". Elenco delle condivisioni con l'utente B, ora l'utente B ha anche "pane" ma con uuid "2". Se ho interrogato la lista senza filtrare per utente, conterrebbe 2 voci. "1" - "pane" e "2" - "pane". Problemi qui: 1. Ridondanza / spazio nel database. 2. Bisogno di usare semantico unico per identificare gli elementi che appartengono insieme (un gruppo di copie).
-
Fai in modo che gli utenti facciano riferimento alla stessa voce di elenco e alle stesse dipendenze. Ciò significa che quando una lista è condivisa, devo verificare se gli altri utenti hanno un prodotto o una categoria con lo stesso nome (non devono terminare con più prodotti con lo stesso nome dopo che qualcuno condivide gli elenchi con loro), sostituirlo con il prodotto o categoria dell'utente che condivide e crea tutti gli elementi dell'elenco e altri tipi di elementi che potrebbero fare riferimento a questo prodotto o categoria per fare ora riferimento al prodotto dell'utente in condivisione. Quando un utente interrompe la condivisione della lista con un altro utente, allora devo passare attraverso tutti gli elementi dall'utente rimosso e creare le proprie copie e di nuovo fare anche che tutto ciò che punta a loro punti ora alle nuove copie. Esempio di pane: l'utente A ha "1" - "pane", l'utente B ha "2" - "pane", una lista di azioni con B, questo fa sì che B rimuova "2" - "pane". Tutti gli oggetti che B può avere quel punto in "2" - "pane" ora devono essere aggiornati per puntare a "1" - "pane". Se A viene rimosso dalla lista, "pane" viene copiato per B con un nuovo uuid casuale e tutti i riferimenti di B a "1" - "pane" devono essere aggiornati per puntare a questa nuova copia.
Oltre a entrambi i punti arriva, che sto usando un'app con un proprio database come client che deve essere sincronizzato con il server (fondamentalmente rispecchia la struttura del server, gli stessi uuids ecc, ovviamente l'app mantiene lo stato di solo 1 utente).
Sto omettendo molti piccoli dettagli, come la domanda su cosa dovrebbe accadere quando un utente aggiorna un prodotto che non è in una lista (che è possibile) ecc. ma penso che questo non sia il nocciolo del problema e voglia mantieni la domanda semplice.
In questo momento sto privilegiando 1. 2 Ha una struttura più pulita nel database, e ha senso semanticamente poiché rappresenta ciò che sta accadendo nella realtà: più utenti condividono gli elementi (e i loro dipendenze).
Ma 2 mi fa rabbrividire un po 'con tutti i riferimenti di sostituzione e aggiornamento, specialmente perché devo farlo di nuovo nel client, e questo non viene fatto solo quando un elenco è condiviso o un utente rimosso da esso ma anche ogni volta che un utente aggiunge una lista alla lista (devi controllare - gli altri utenti hanno prodotto (etc) con lo stesso nome? se sì, rimuovilo, aggiorna i riferimenti), e dato che l'app è utilizzabile anche offline e quando arriva online dopo un po 'ha bisogno di fare una "grande sincronizzazione" nel qual caso forse altri utenti hanno sostituito alcuni riferimenti nel server nel frattempo e e ...
1 sembra più sicuro. Devo ancora scrivere molto codice e transazioni per assicurarmi che tutto sia aggiornato in modo coerente, ma devo farlo anche con 2. Se succede qualcosa di inaspettato penso che sia meno probabile che rovini le cose rispetto a 2.
Qualche idea su questo? È la prima volta che scrivo questo tipo di logica e ogni input è benvenuto.