Guida per l'uso di chiavi composite per identificare le righe


8

È buona norma (o avrebbe effetti negativi) utilizzare un set di 4 colonne per identificare una riga come unica (una è una chiave foriegn, le altre tre sono tipi di dati float)? Sto tentando di costruire una tabella che (con 4 chiavi collegate) descriva una voce unica nella tabella. Sono curioso di sapere se questo è un buon piano di attacco o se esiste un modo migliore.

A scopo visivo, immagina la tabella seguente. Abbiamo articoli di inventario organizzati come nella seguente tabella: ( [K]è simbolico della chiave primaria, le linee sono relazioni)

    Sheet_Class        Sheet_Type         Sheet_Size
    ===========        ==========         ==========
[K] Sheet_Class-.  [K] Sheet_Type--.  [K] Sheet_Size
                 '---- Sheet_Class  '---- Sheet_Type
                                          Length
                                          Width
                                          Thickness

I dati possono presentarsi nel modo seguente, ma per brevità ho escluso il passaggio sulle colonne collegate:

 Sheet_Class    Sheet_Type    Sheet_Size                        (Tables)
[Sheet_Class]  [Sheet_Type]  [Length], [Width], [Thickness]     (Column Values)
=============  ============  ==============================

Aluminum
               5052-H32
                             48, 96, 0.032
                             48, 96, 0.040
                             48, 96, 0.063

               6061-T6
                             60, 120,0.032
                             60, 120,0.040
                             60, 120,0.063

Steel
               1018-CRS
                             48, 96, 0.018
                             48, 96, 0.023
                             48, 96, 0.031

Così com'è (e ho mostrato nel mio "schema" sopra), uso una chiave primaria intera (auto-incremento) per le voci nella tabella Sheet_Size . Tuttavia, mi piacerebbe sapere se è meglio utilizzare una combinazione delle colonne Sheet_Type , Lunghezza , Larghezza e Spessore ? Dato che ogni voce in Sheet_Size dovrebbe condividere tutte queste qualità uniche e che un campo a incremento automatico non lo dimostrerebbe abbastanza bene, è questa la strada migliore da prendere?

Se non sto spiegando abbastanza bene la situazione, per favore fatemi sapere. Mi sto trovando nella necessità di dividere queste porzioni (Class vs Type vs. Actual stock size) di un materiale inventario per altri scopi logici, ma sono pronto per qualsiasi altro tipo di feedback.

Qualsiasi consiglio sarebbe apprezzato.

Aggiornamento (08-12-2011)

Dopo le risposte pubblicate, ho deciso di fare una combinazione di risposta di Mark & risposta di X-Zero . Ho deciso che è una buona idea porre un vincolo unico alle colonne di lunghezza, larghezza e spessore, ma mi piace anche l'idea di suddividere le dimensioni del materiale in file uniche e collegarle con una relazione.

Sfortunatamente non posso accettare entrambe le risposte, quindi accetterò X-Zeros per considerare (quello che sento) uno sguardo più critico al problema e offrire un adeguamento dello schema.

Grazie a tutti per le vostre risposte.

Risposte:


6

Dopo aver pensato a questo, rivederei leggermente la struttura del tuo tavolo.
Innanzitutto, modifica la tabella delle dimensioni del foglio:

Sheet_size
===========
Id
Length
Width
Thickness

In secondo luogo, creare una tabella di relazione formato foglio / tipo:

Sheet_size_type
================
Sheet_Type_Id
Sheet_Size_Id

Quindi, creare i seguenti vincoli:

  1. La chiave primaria (e l'indice) di Sheet_sizedovrebbe essere la colonna id
  2. Dovrebbe esserci una sorta di chiave univoca (e indice) applicata alle dimensioni in Sheet_size. Considera, due fogli di dimensioni (48, 96, .5) e (96, 48, .5) sono uguali (vale a dire la direzione delle dimensioni è importante)? Questo tipo di problema può essere difficile da applicare se si utilizzano le colonne come parte della chiave primaria, ma diventa più gestibile quando si utilizzano vincoli e stored procedure.
  3. La chiave primaria (e l'indice) di Sheet_size_typedovrebbe usare entrambe le chiavi esterne, iniziando da quella con la cardinalità inferiore (probabilmente sheet_type, dato il tuo esempio). È possibile che si desideri un indice aggiuntivo nell'altra direzione, ma potrebbe non essere necessario.

Questa revisione consente di risparmiare spazio nel database (come rapporto tra il numero di tipi di foglio che utilizzano le stesse dimensioni) e non dovrebbe influire troppo sull'overhead.


Vi sono altre potenziali preoccupazioni sull'uguaglianza / unicità se si utilizza un floattipo di dati, poiché l'imprecisione potrebbe farti scattare inaspettatamente. Dovresti considerare se un tipo a virgola fissa, con una certa precisione, sarebbe più appropriato.


Avevo intenzione di limitare la lunghezza e la larghezza a un singolo (possibile due) punti decimali e lo spessore si sarebbe (al massimo) esteso a tre. Oltre a ciò, stiamo diventando troppo limitati (e lo stock stesso non arriva mai ai numeri descrittivi comunque). A parte questo, mi piace l'idea di dividere le dimensioni del foglio, ma il problema che sto affrontando sono le altre colonne coinvolte (che ho escluso). (serve più spazio, vedi il prossimo post)
Brad Christie,

Poiché si tratta di un elenco di stock inventariati, devo includere altre informazioni come Densità e Costo / lb (che è fortemente basato sul tipo (e lo spessore anche. Ad esempio, "Acciaio" / "1018" potrebbe essere $ 0,55 / lb a 0,018-0,125 "di spessore, ma diventa $ 0,65 / lb quando lo spessore supera 0,125". (E questo può anche differire tra una dimensione del foglio 48 "x96" x0.250 "di 1018 rispetto a 5052-H32). Nel tuo esempio, Avrei solo una voce per 48 "x96" x0.125 "(anche se suppongo che la tabella delle relazioni potrebbe avere queste metriche aggiuntive)
Brad Christie,

Se hai bisogno solo di un piccolo numero di cifre decimali, quindi sì, usa una precisione fissa. Sì, è qui che (in questo caso) inseriresti informazioni del genere (il costo è una dipendenza dal tipo e dalle dimensioni del foglio, ad esempio), anche se potresti voler generare tabelle aggiuntive a cui puoi fare riferimento. Puoi anche prendere in considerazione la possibilità di creare tipi di dati personalizzati (come la densità) in modo che le persone non provino a eseguire query sui dati in modi imprevisti.
Clockwork-Muse

6

Sembra una decisione chiave naturale vs surrogata , opinione su quale spazia da considerato e pratico a accademico , al confine con il dogma. A seconda del RDBMS, esistono considerazioni per il modello fisico che possono avere implicazioni significative in termini di prestazioni, ad esempio la scelta della chiave in cluster in SQL Server.

Personalmente, se ho una chiave candidata per singolo attributo, sono tentato di usarla. Tasti larghi e / o compositi, per impostazione predefinita sto aggiungendo un surrogato al modello. Nel tuo caso, voterei per la colonna identità su Sheet_Size come chiave cluster primaria e un vincolo univoco su tipo / lunghezza / larghezza / spessore.


Ma dato che ora hai una chiave "arbitraria" assegnata alla riga, in che modo univoco impone che le colonne (se combinate) non possano avere valori duplicati? Comprendo che l'attributo univoco si riferisce alla chiave. Stai dicendo Sheet_Size INT PRIMARY KEYe Length UNIQUE, Width UNIQUE, Thickness UNIQUE? Non capisco ancora come ciò prevenga i duplicati nella tabella (senza applicare la logica all'interfaccia di inserimento). (Forse mi manca qualcosa?)
Brad Christie,

Un vincolo unico per le tre colonne: ALTER TABLE dbo.Sheet_Size AGGIUNGI VINCITORE UC_LengthWidthThickness UNIQUE ([Lunghezza], [Larghezza], [Spessore])
Mark Storey-Smith

Grazie per il feedback. Sono d'accordo che un vincolo univoco sulle colonne sarebbe un'ottima soluzione, ma mi piace anche la raccomandazione di X-Zero di suddividere le dimensioni in una nuova tabella (collegata a una nuova tabella). Quindi, per combinare le idee, applicherò il vincolo unico alla tabella delle dimensioni "Stripped-down", rimuovendo al contempo le informazioni sulla densità e sui costi / libbre e inserendole nella tabella delle relazioni.
Brad Christie,

4

Ti reindirizzerò un po 'a questa risposta da una domanda precedente .

Citazione: "Per quanto riguarda il modo di progettare quella chiave primaria, ci sono due scuole di pensiero:

  • uno che rende il PK come una colonna separata, di solito auto-generata, come un GUID o e l'incremento automatico INT (nel tuo caso una colonna di identificativo univoco separata);
  • uno che rende il PK come colonna (o insieme di colonne) interno alla tabella (nel tuo caso sarebbe un nome utente o e-mail o SSN, qualunque cosa renda unico quell'utente) che identifichi in modo univoco un record.

A quale linea aderisci, è solo una questione di gusti. "

Gli effetti collaterali di qualsiasi soluzione scelta potrebbero essere:

  • l'uso di chiavi composte ovunque probabilmente:

    • aumentare lo spazio di archiviazione per tutte le tabelle coinvolte;
    • aumentare / complicare gli indici su FK usati spesso;
    • complica un po 'la scrittura di tutte le tue dichiarazioni di partecipazione
    • rendere felice il signor Joe Celko :-) (riferimenti sulle sue opinioni in merito a chiavi naturali o artificiali possono essere trovati qui e qui , e soprattutto ovunque gli sia stato chiesto del problema)
  • l'utilizzo di chiavi generate probabilmente:

    • semplifica i precedenti 3 passaggi
    • complicare la situazione della replica di una tabella con identità PK (riferimenti qui , qui o qui )

Personalmente preferisco le chiavi INT IDENTITY generate, ma ciò che fa per te dovrebbe andare bene.


2

La chiave composita ha perfettamente senso. L'implementazione di tale chiave garantisce che gli attributi aziendali non possano essere duplicati. Questa è una buona cosa perché la registrazione più volte degli stessi dati causerebbe ambiguità, dipendenze indesiderate e renderebbe più probabili errori dell'utente e dati errati.

La chiave auto-incrementante da sola non protegge l'integrità dei dati aziendali. Se la chiave auto-incrementante non ha scopi particolari (ad es. Come target di un riferimento di chiave esterna in un'altra tabella), può essere tranquillamente rilasciata.


... Tranne il rilascio dell'incremento automatico poiché la chiave esterna richiederebbe l'utilizzo di tutte le colonne della dimensione come parte della chiave esterna (ovvero, tutte e quattro le colonne , includendo il tipo). Non qualcosa che voglio come chiave esterna, punto - solo colonne singole, per favore. Sono d'accordo che è una buona idea mettere una chiave unica (e / o controllare il vincolo) sulle dimensioni (e digitare, a seconda del design della tabella).
Clockwork-Muse

@ X-Zero, ho fatto il punto sui riferimenti a chiave esterna nel mio secondo paragrafo. La domanda mentre la leggo è se implementare la chiave composita, non se anche avere un auto-incremento.
nvogel,
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.