2009-02-07 21 views
7

Mi sono chiesto quali sono le migliori pratiche o ramificazioni nell'impostazione del PK in una tabella M2M in SQL Server. Per esempio:Best practice per PK in SQL Server

Ho 2 tabelle

  • Utenti
  • ruoli

sto facendo una nuova tabella

  • UserRole

che dispone di 2 campi ID ruolo & UserID

ora devo

  1. creare un UserRoleID come il PK e fare UserID e ID ruolo delle FKS
    • rendono l'UserID PK AND ID ruolo e impostarle come FKS
    • qualcos'altro

Mi piacerebbe conoscere i problemi di prestazioni con ciascuna opzione e quali sono le migliori pratiche consigliate.

risposta

10

La procedura standard per questi casi prevede due indici. Il PK univoco è costituito dai due campi compositi, con il campo con la cardinalità maggiore prima, cioè UserID; e il secondo indice con solo il campo secondario (cioè RoleID).

Quindi, il cluster su cui è probabile che sia coinvolto in più set di risultati multirecord (ovvero se si esegue una query per più ruoli per utente o più utenti per ruolo).

+0

Grazie per non aver consigliato una chiave surrogata inutile! +1 –

1

Dipende se ci si aspetta di appendere qualsiasi altro significato al fatto che un utente specifico abbia un ruolo specifico. Altrimenti, basta creare un PK cluster per estendersi tra i due campi.

Aggiungi FK per entrambi e aggiungi un indice al secondo campo. Presta attenzione a quale ordine devono essere visualizzati i campi. È più probabile che tu stia recuperando un insieme di ruoli a cui un utente appartiene o il set di utenti in un ruolo specifico?

0

Dipende da come li si utilizza. Il più delle volte faccio la chiave primaria come UserId e RoleId per assicurarmi che siano unici. Significa che lo stesso utente non può avere lo stesso ruolo.

Ora è qui che entra in gioco "dipende". Se si intende collegare la tabella UserRole a un'altra tabella, è qui che creo la chiave primaria UserRoleId. E rendere UserId e RoleId in un vincolo univoco.

Il motivo per questo non è quello di avere sulla tabella che fa riferimento a UserRole sia un UserId sia un RoleId quando non è necessario perché si sta collegando a UserRoleId e non alla tabella User e alla tabella dei ruoli rispettivamente.

+0

Quindi preferiresti unire due tabelle ogni volta che vuoi ottenere qualche informazione utile invece di aggiungere 4 byte aggiuntivi a un'altra riga della tabella? –

+0

@ TomH. Ho capito il tuo punto, ma quando cambi? Se hai una tabella m: m: m inseriresti tutte e tre le colonne in ogni bambino. Che ne dici di 4 o 5? Alla fine i tuoi join diventano superbamente brutti ed è per questo che evitiamo la chiave naturale e vogliamo le chiavi surrogate per rendere i join singole colonne –

2

Dichiarare il PK come (UserID, RoleID).(Nota: l'ordine è importante)

Dichiarare UserID come FK con il riferimento alla tabella Utenti. Dichiarare RoleID come FK con il riferimento alla tabella dei ruoli.

Con un po 'di fortuna, il DBMS ti fornirà un indice composito su (UserID, RoleID) in questo ordine.

Con un po 'di fortuna questo accelera i join tra utenti e ruoli. Un buon DBMS ti darà un join di unione per un join senza restrizioni oltre alla condizione di join. Anche un join a tre vie dovrebbe essere abbastanza veloce, assumendo che il numero di ruoli sia piccolo.

Quando si accede a UserRoles e ai ruoli, senza unirsi agli utenti, è possibile che sia deludentemente lento. Quanto spesso lo fai e quanto è importante la velocità in questo caso? Se è importante, puoi creare un indice solo su RoleID.

0

Evitare il PK composito e inserire un indice univoco sui due FK (sembra appropriato in questo caso). Non è un problema in questo caso, ma essere coerenti. Dover ricordare di affrontare i molteplici campi su cui partecipare quando si scrivono domande è un dolore. Se la tua chiave composita deve essere composta da datetime, char o altri tipi di campi, le prestazioni subiscono un colpo.

+0

L'inclusione di altre colonne in un indice è una buona cosa. Può significare che una query può essere risolta solo con l'indice e può evitare le ricerche della tabella tutte insieme. Credo che le persone MSSS chiamino quelle "query coperte". –