Le tabelle di ricerca che enumerano le stringhe devono avere una chiave primaria intera?

2

Quando ho imparato i database relazionali, il prof ha detto che uno "quasi sempre" vuole un int artificiale come chiave primaria in una tabella, ma non ha specificato quali sono le eccezioni. A un certo punto ho smesso di usarli per le tabelle di giunzione e non ho mai avuto problemi.

Ora sto creando un database con molte tabelle di ricerca e mi chiedo se questo è un caso in cui lasciare le chiavi artificiali non renderebbe un design più pulito e una programmazione semplice.

Un esempio di giocattolo: supponiamo che questo sia un mockup dell'interfaccia utente che voglio raggiungere.

L'opzionediprogettazioneconIDartificialisarebbe(Tipoèunachiaveesterna):

LiteraryWorkTitleTypeWinnieThePooh1TheNightingaleandtheRose2Snowwhite2LiteraryWorkTypeIDTypeName1Novel2FairyTale

El'opzionesenzadiessiusailnomeditipostessocomechiave(dinuovo,iltipodicolonnaèdichiaratocorrettamentecomechiaveesterna):

LiteraryWorkTitleTypeWinnieThePoohNovelTheNightingaleandtheRoseFairyTaleSnowwhiteFairyTaleLiteraryWorkTypeTypeNameNovelFairyTale

Tendoadusarelasecondaopzione,perchéavreibisognodiunjoininmenoquandomostriidatisulloschermo.(Nonvoglioeliminarecompletamentelatabelladiricercaperchévoglioessereingradodilimitareivalorichegliutentipossonoimmettere,adesempioassegnandolorounelencoadiscesaassociatoallatabelladiricerca).L'unicosvantaggiochepossopensareèche,quandounostakeholderdice"ma voglio che la mia UI dica" storia ", non" fiaba "", dovrei aggiornare tutte le righe di dati nella tabella LiteraryWork . Posso vivere con questo, perché non mi aspetto che accada spesso nel mio caso.

Il primo progetto presenta altri vantaggi che mi mancano? Quale delle due opzioni è considerata la migliore pratica e perché?

Modifica2 A quanto ho capito, le risposte esistenti temono che sto cercando di rompere la normalizzazione, come in

LiteraryWork
Title                           Type        LiteraryWorkTypeIsFiction
Winnie The Pooh                 Novel       Yes
The Nightingale and the Rose    Fairy Tale  Yes
Snowwhite                       Fairy Tale  Yes

Per essere chiari: quanto sopra è non ciò che sto cercando di fare. Invece, se ci fossero davvero più informazioni relative a LiteraryWorkType e stavo usando gli ID stringa, lo registrerei in questo modo:

LiteraryWork
Title                           Type
Winnie The Pooh                 Novel 
The Nightingale and the Rose    Fairy Tale 
Snowwhite                       Fairy Tale 

LiteraryWorkType 
TypeName         IsFiction
Novel            Yes
Fairy Tale       Yes
Conference paper No

L'unica differenza con la struttura del database "tipico" sarebbe che l'ID è un nvarchar, non un intero. Che ha certamente i suoi svantaggi nella conservazione necessaria, come sottolineato, ma non vedo quale regola di normalizzazione si suppone faccia male.

Ma a parte questo esempio, non sto cercando di usare gli ID stringa quando effettivamente ci sono più informazioni da registrare su un oggetto LiteraryWorkType (in modo che LiteraryWorkType debba essere considerato un'entità a sé stante). Sto parlando di casi semplici come l'esempio del giocattolo che ho dato all'inizio: l'intera seconda tabella esiste solo perché SQL non ha il tipo "enum" e ogni record di dati in esso consiste di nient'altro che una singola parola, unica tra i record.

    
posta Rumi P. 25.03.2013 - 14:53
fonte

3 risposte

5

La ripetizione di una stringa di lunghezza variabile su più righe (sia dati che indici) è molto meno efficiente rispetto alla memorizzazione di un valore tinyint.

  • La stringa "Fiaba" richiede 12 byte almeno sulla maggior parte dei sistemi, inclusi 2 per la lunghezza.
  • Hai denormalizzato e aggiunto anomalia di modifica dei dati rischio
  • Hai quindi la distinzione tra maiuscole e minuscole e le regole di confronto da tenere in considerazione per i confronti

Modifica:

Il tuo problema principale è la dimensione del database e il gonfiore perché le righe sono più lunghe del necessario. Ciò significa meno righe per pagina e più memoria utilizzata per le query. Vedi questi per il motivo

Ho visto enormi database che non usano tabelle di ricerca (progettate da Hibernate ORM su MySQL) e ripetono lunghe stringhe. Secondo la mia stima, il database avrebbe potuto essere almeno il 60% più piccolo.

La normalizzazione non è un problema se stai usando la tabella di ricerca sulla chiave naturale. Che hai chiarito

    
risposta data 25.03.2013 - 15:11
fonte
5

Does the first design have any other advantages I am missing?

Vuoi dire oltre ad immagazzinare N meno byte per istanza? Le stringhe sono grandi. Le stringhe Unicode sono più grandi.

Peggio ancora, denormalizzando la struttura, ora devi cambiare il nome in N posti anziché 1 se hai un errore di battitura. O in un altro caso, quando vuoi esporre quei nomi in altre lingue.

In generale, i compromessi per questa denormalizzazione sono ben studiati.

    
risposta data 25.03.2013 - 14:58
fonte
2

Cosa succede quando i tuoi utenti vogliono assegnare più classificazioni a una storia? Cosa succede quando si desidera fornire traduzioni del tipo di libro ... o se si desidera consentire agli utenti di avere la propria biblioteca privata con le proprie classificazioni? Una volta raggiunto uno di questi scenari, in futuro ringrazierai passato (o oggi tu) per dare al tavolo una chiave unica.

Le chiavi di tabella non dovrebbero avere alcun significato all'interno del sistema, poiché le regole aziendali cambiano. Qualcosa che è "sempre" unico alla prima occhiata avrà casi limite mentre ti immergi più a fondo.

    
risposta data 25.03.2013 - 16:24
fonte

Leggi altre domande sui tag