È meglio strutturare una tabella SQL in modo che abbia una corrispondenza o non restituisca alcun risultato

StackOverflow https://stackoverflow.com/questions/23399

  •  09-06-2019
  •  | 
  •  

Domanda

Ho una domanda interessante sul design.Sto progettando il lato sicurezza del nostro progetto, per permetterci di avere diverse versioni del programma a costi diversi e anche per consentire agli utenti di tipo Manager di concedere o negare l'accesso a parti del programma ad altri utenti.Sarà basato sul Web e ospitato sui nostri server.

Sto utilizzando una semplice opzione Consenti o Nega per ciascuna "Risorsa" o schermata.

Avremo un gran numero di risorse e l'utente sarà in grado di impostare molti gruppi diversi in cui inserire gli utenti per controllare l'accesso.Ogni utente può appartenere ad un solo gruppo.

Ho in mente due approcci a questo ed ero curioso di sapere quale sarebbe stato migliore per il server SQL in termini di prestazioni.

Opzione ALa presenza di una voce nella tabella degli accessi significa che l'accesso è consentito.Ciò non richiederà una colonna nel database per memorizzare le informazioni.Se non vengono restituiti risultati, l'accesso viene negato.

Penso che ciò significherà una tabella più piccola, ma le query cercherebbero l'intera tabella per determinare che non esiste corrispondenza?

Opzione BNel database è inclusa una colonna di bit che controlla Consenti/Nega.Ciò significa che c'è sempre un risultato da trovare e crea una tabella più grande.

Pensieri?

È stato utile?

Soluzione

Se sarà solo Consenti/Nega, allora una semplice tabella di collegamento tra Utenti e Risorse funzionerebbe correttamente.Se è presente una voce codificata per la risorsa utente nella tabella di collegamento, consentire l'accesso.

UserResources
-------------
UserId FK->Users
ResourceId FK->Resources

e SQL sarebbe qualcosa di simile

if exists (select 1 from UserResources 
where UserId = @uid and ResourceId=@rid)
set @allow=1;

Con un indice cluster attivo (UserId e ResourceId), la query sarebbe incredibilmente veloce anche con milioni di record.

Altri suggerimenti

Io voterei per l'opzione B.Se scegli l'Opzione A e presupponi che se un utente esiste, può entrare, alla fine ti imbatterai nel problema che vorrai negare l'accesso a un utente, senza rimuovere il record dell'utente.

Ci saranno molti casi in cui vorrai bloccare un utente, ma non vorrai distruggere completamente il suo account.Uno di questi casi (non necessariamente collegato al tuo caso d'uso) è quando non riesci a pagare e ti tagliano l'account finché non inizi a pagare di nuovo.Non vogliono eliminare il record, perché vogliono comunque abilitarlo quando paghi di nuovo, invece di ricreare l'account da zero e perdere tutta la cronologia utente.

B.Consente di verificare molto meglio se i dati sono completi (ad esempio, quando si aggiunge una funzionalità consentita/negabile).

Inoltre, la dimensione della tabella dovrebbe essere presa in considerazione solo per le tabelle che sai conterranno molti record (come in oltre 100.000).Anche il tempo necessario per digitare la considerazione delle dimensioni della tabella in questa domanda costa già più dello spazio aggiuntivo sul disco rigido necessario.

Approccio A, ma includerei anche una negazione esplicita oltre alla negazione implicita.Vorrei creare alcuni casi d'uso per essere sicuro che la logica finale funzioni, ma ecco alcuni esempi.

User1 is in group1 and group2.  
User2 is in group1  
User3 is in group2 

Folder1 allows group1 and deny group2.  
User1 is denied.  
User2 is allowed.  
User3 is denied. 

Credo che il tuo approccio users1 sarebbe consentito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top