Newsgroup: it.comp.software.database
Titolo: Normalizzazione vs prestazioni

Ciao a tutti.
Vorrei sapere le vostre opinioni sulla progettazione dei databases.
All'Universita', ho imparato a disegnare il DB seguendo le regole della
normalizzazione, ma lavorando su DB reali ho scoperto che spesso queste
regole non vengono rispettate, a favore delle prestazioni.
Mi spiego meglio facendo un esempio: supponiamo di avere una tabella Persone
(con chiave codicefiscale). Ho la necessita' di associare ad ogni persona un
attributo multivalore, ad esempio un elenco di articoli acquistati.
Per rispettare la prima forma normale, dovrei creare un ulteriore tabella
con campi codicefiscale, codicearticolo ed inserire un record per ogni
articolo acquistato dalla persona.
Invece, in casi particolari e' preferibile aggiungere un campo alla tabella
Persone dove inserire l'elenco degli articoli opportunamente concatenati. Ad
esempio, se il sistema prevede che l'azione di acquisto di un articolo (che
modifica l'attributo multivalore) e' rara, mentre l'azione di lettura degli
articoli acquistati e' piu' frequente. Inoltre se la tabella Persone
contiene un numero elevato di righe e quindi anche l'eventuale ulteriore
tabella conterrebbe un numero di righe cosi' elevato che la join avrebbe
delle prestazioni inferiori...
Voi come affrontate questo problema?
In conclusione, devo dimenticare tutto quello che ho studiato?
 DM(ag)
 
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 wrote in message
news:151Z5Z148Z94Y1...@usenet.libero.it...

Nel mondo reale, l'ansia da prestazioni  :-)  non paga.
Se sacrifichi la normalizzazione per qualcosa che va piu' veloce, nessuno ti
dira' grazie (anche perche' nessuno sapra' dire la differenza).
Se per disegnare il database denormalizzato ci metti piu' tempo per studiare
cose tipo campi multifunzione, nessuno ti paghera' le ore spese in piu', ne'
ti dira' grazie.
Se il pasticcio che hai fatto per ottenere piu' prestazioni provoca dei guai
(inconsistenze ecc.) sara' sicuramente colpa tua e tutti lo vedranno.
Per velocizzare un database e' piu' importante scegliere gli indici giusti.
Verra' anche il giorno in cui, in un problema concreto, occorrera', in via
eccezionale, sacrificare della normalizzazione in cambio di un sistema piu'
semplice (NON piu' prestante). Ed in genere, non e' la 1NF che ne va di
mezzo.
Ma finche' non hai l'esperienza per riconoscere il caso speciale, continua
tranquillamente a progettare db normalizzati.
AS

 regole non vengono rispettate, a favore delle prestazioni.
Normalizza, normalizza.
A lungo andare......paga :)
Alla prossima.
	MAX

 regole non vengono rispettate, a favore delle prestazioni.
Mi piacerebbe vedere una misura fisica dell'aumento delle prestazioni in
un caso reale denormalizzato, in termini di I/O (disco-memoria,
memoria-cpu, memoria-client).
Personalmente ho avuto, per lavoro e, ci tengo a dire, non per "merito"
mio, esperienze dell'esatto opposto di quello che dici (cioè prestazioni
peggiori). La denormalizzazione ha effetti negativi su molti aspetti dei
db; le prestazioni non stanno tra quelli e comunque sono uno degli
ultimi aspetti da considerare.
Bye :-)
-- 
Rudy
blog: 
http://rdbland.blogspot.com/
e-mail a 
email.it

 In conclusione, devo dimenticare tutto quello che ho studiato?
no, solo che dovrai continuare a studiare
(come dovrebbero tutti, solo che almeno hai
solide basi)
cya :OP


Grazie,


 id,codicemat,descr,categoria,prezzo,costo
Domanda (retorica): la struttura Tab {ID, attributo} è per caso il
prototipo di qualunque tabella?

 previsto in TUTTI i db relazionali.
Stai dicendo che le chiavi delle relazioni dovrebbero essere solo id generati da contatori? Io avrei detto l'esatto
contrario: le chiavi dovrebbero essere attributi con un senso ben preciso nel "mondo reale" che stiamo cercando di
rappresentare. Se intendi con database relazionale un "software che gestisce un database relazionale", hai ragione: non
c'è nessuna differenza ad usare un id o un altro; per un database relazionale, inteso dal punto di vista logico, c'è
molta differenza: un id generato non ha nessun senso, un codice fiscale sì.
La mia impressione è che utilizzare solo id di questo tipo per collegare le tabelle sia un po' come usare  dei
"puntatori" all'interno del database, cosa che Codd voleva assolutamente evitare quando ha definito le basi dei database
relazionali. Voi che ne pensate?

 relazionali. Voi che ne pensate?
Lo credo anch'io; in particolare trovo che tali ID imitino i
puntatori dei network database, in cui le relazioni venivano
formate "puntando" alle righe.

 molta differenza: un id generato non ha nessun senso, un codice
fiscale sì.
Ma un codice fiscale HA GIA' un SUO significato e SUE regole,
che non sono determinate da te : e' questo che ne fa la differenza
con un id. Se le regole cambiano tu che fai?
Quindi :
1) se uno un numero, gli indici saranno decenti e performanti
2) se uso un numero non sbagliero' a scegliere la chiave,
sprecando 4 o 8 byte, ma sa' piu' del tema "programmo in c o
in c++" : pero' se replico una stringa da 16 char su 2 o<n>
tabelle e' qui che "butto" lo spazio
3) perdo in leggibilita' dei record, che pero' sono in un db
relazionale
che mi permette appunto di renderli leggibili al volo con una relazione
IHMO:
sono un po perplesso dall'idea di usare una stringa per una releazione,
quando hai 5 milioni di record o forse solo 300mila, secondo me gli
indici sono pietosi rispetto ad una controparte numerica indicizzata.
cya

 indicizzata.
Hash index... ed il sistema fa tutto quello che a mano faresti tu,
in automatico, col vantaggio di non dover pasticciare lo schema.
La tecnica si è evoluta: vogliamo smetterla di credere di fare
meglio di quanto farebbe un motore dbms moderno?

 indici sono pietosi rispetto ad una controparte numerica indicizzata.
Queste mi sembrano tutte considerazioni che riguardano il modello fisico dei dati e possono eventualmente essere risolte
utilizzando i  tipi giusti di indice e di tabella (sempre senza intaccare il modello logico)
Il tutto ovviamente IMHO: accetto qualsiasi osservazione.
Ciao
Zac

il buon henderson sostiene che la normalizzazione è cosa buona è giusta, ma
anche i dati ridondanti possono esserlo. io ad esempio su un grosso
database ho tutti i dati normalizzati per bene, ma anche _diciamo_
staticizzati. 
quello che mi serve a volte è solo una lettura veloce, quindi evito le join.
quando invece mi serve fare delle ricerche approfondite utilizzo le tabelle
esterne.
certo c'è un grosso casino per tenere i dati sincronizzati, ma per quanto mi
riguarda alla fine è una cosa che paga.
se ti interessa, leggi "how to build scalable web sites" di Cal Henderson
(lead engineer di flickr)
-- 
non stare in buco

 Zac
yep m2 :O)
nel senso che sono sempre considerazioni personali:
passo il tempo tra db che hanno a malapena implementato
sql 92, con sintassi "personali" appena si tratta di avere
relazioni su delete e quant'altro, quindi non amo ipotizzare
che una struttura regga solo perche' <teoricamente> i dati
sono univoci etc : negli archivi dei comuni trovi cose come
7 indirizzi per un unico civico reale, doppi codici fiscali,
cap fantomatici :O)
cya


--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 
per farti un'idea cerca il paper "Scaling Fast and Cheap - How we Built
Flickr" Cal Henderson


 
Alla fine dice "Normalization is for Sissies" ovviamente è una provocazione,
ma spiega il perché e come farlo.
ciao


 cap fantomatici :O)
Effettivamente i casi concreti portano a scontrarsi con motori di database obsoleti o pieni di difetti, oppure con
strutture dati non ideali perché ereditate da altri o non modificabili a causa di diversi vincoli indipendenti dalla
nostra volontà (a volte un bel 'drop database' ci starebbe bene...).
Sono d'accordo che in questi casi sarà necessario trovare soluzioni che potrebbero andare contro i principi teorici...
tuttavia penso che dovrebbe essere "l'ultima spiaggia": se si conosce la soluzione "teoricamente corretta", se non è
applicabile a causa dei problemi suddetti, se si conoscono i problemi a cui si può andare incontro "violando" la
teoria... allora conviene adottare una soluzione di compromesso documentandone chiaramente i motivi. (questo ultimo
pensiero non è mio, anche se lo condivido: proviene dall'introduzione di "Database in depth" di C. J. Date, un libro che
mi è piaciuto molto e che consiglio a chiunque si interessi di database: è illuminante)
Ciao
Zac

 con chiave primaria {nome, cognome, data_di_nascita}
...e sei sicuro che una chiave primaria così costituita sia valida? E se
ci sono due soggetti con uguale nome, cognome e data nascita?
Magari nello stesso comune?
Ok, il tuo esempio era semplice e non aveva lo scopo di dire qual'è la
miglior chiave per una tabella, ma mi chiedo se nel caso che ho
descritto (identico nome, cognome, data e comune di nascita), l'avere
una chiave primaria "reale" come il codice fiscale sia una cosa buona...
L'amministrazione fiscale potrebbe metterci anni prima di accorgersi del
doppione e dare a uno dei due un codice fiscale differente... non
sarebbe certo la prima volta.
-- 
David Martin

 
Esistono, esistono. :) :)
Non posso fare nomi, cognomi e comuni per la privacy.
Cmq uno sono io :)
Ciao.
	MAX

 sarebbe certo la prima volta.
Riscrivo il problema per essere sicuro di aver capito bene:
Ho una relazione che rappresenta un'anagrafica di persone, diciamo i clienti della mia azienda:
cliente {codice_fiscale, nome, cognome, data_di_nascita, comune_di_nascita, indirizzo, ...}
con chiave primaria (codice_fiscale)
e vorrei poter rappresentare il fatto che due clienti (distinti nella realtà) hanno lo stesso nome, cognome,
data_di_nascita e comune_di_nascita ed inoltre hanno anche lo stesso codice fiscale, a causa di un errore della pubblica
amministrazione (io mi chiederei se veramente voglio fare la fatica di prevedere anche un caso 'patologico' come
questo... ma assumiamo di si)
A questo punto una possibile soluzoine è non usare il codice fiscale come chiave primaria ma di sfruttare un id numerico
generato automaticamente:
cliente {id_cliente, codice_fiscale, nome, cognome, data_di_nascita, comune_di_nascita, indirizzo, ...}
con chiave primaria (id_cliente)
Questo risolve il problema specifico permettendomi di inserire i due clienti distinti, ma chi mi assicura che io domani
non mi dimentichi che una persona era già cliente e la inserisca nuovamente (stesso nome, cognome... nuovo id_cliente)?
Come potrò distinguere i duplicati "reali" da quelli introdotti per errore?
Un'altra soluzione, a mio parere migliore, è aggiungere alla chiave un ulteriore attributo "reale" che possa distinguere
tutti i clienti: il comune di residenza, il numero di telefono..., il nome della madre, il colore dei capelli... :)
...ci sarà pure qualcosa che li distingue!
Questa ovviamente è la mia opinione: qualcuno probabilmente avrà idee migliori e forse più esperienza di me... la
discussione è aperta
Ciao

 Sbagliare un numero è molto più facile.
IMHO, non è facile sbagliare un numero, se il numero è un
auto-incrementale o qualcosa di simile, gestito e generato dal rdbms e
non deciso dall'utente...
-- 
David Martin

 comune di nascita?
http://www.agenziaentrate.it/ilwwcm/connect/Nsi/Servizi/Codice+fiscale+-+Tessera+Sanitaria/Codice+fiscale/NSI+Informazioni+sulla+codificazione+delle+persone+fisiche

 provocazione, ma spiega il perché e come farlo.
"La normalizzazione è per le checche", davvero illuminante.
Questa affermazione ad un qualsiasi dba di media esperienza suona
come "La matematica è per i fessi"; non mi sembra granché come
invito all'approfondimento.
Continuo ad essere dell'opinione che certe affermazioni descrivono
più che altro la persona che le pronuncia...

 non deciso dall'utente...
Manca la fase dell'interazione con l'utente.
Prova pensare alla digitazione a video di un impiegato ad uno
sportello, magari con una lunga fila dietro che impreca.
Sbagli una cifra del CF -> l'algoritmo check digit se ne accorge senza
neppure leggere le righe (lato client)
Sbagli un ID autoincrementale -> prenderai *sicuramente* un'altra
persona!

The man with two watches wrote:

grazie per la traduzione. continuo a rimanere dell'opinione che se tizio ha
scritto 
flickr.com
 può permettersi di dire quasi quello che vuole e
ovviamente, sa il fatto suo. (in rete troverai il suo curriculum)
ah, ovviamente -come ho specificato sopra- viene giustificato ampiamente il
motivo per  cui lo dice.
solo che non hai avuto voglia di andare a leggere/capire
ciao ciao


 solo che non hai avuto voglia di andare a leggere/capire
Esatto!

 
Ti sei risposto da solo.
Ciao.
	MAX

 e definitivo" ed inoltre ha un significato riconosciuto da tutti.
Se cosi' fosse, mi sai spiegare perche' io ho 2 codici fiscali?
Quanto al fatto che sia definitivo, definiresti i cap un'informazione
definitiva? se si perche' sono stati cambiati? ora saranno definitivi
per quanto tempo?
Il codice fiscale, rimarra tale per sempre? una applicativo che lo
usa in una amministrazione pubblica, potrebbe mai usare un codice
fiscale al posto di un id per tutte le relazioni?
---
http://punto-informatico.it/p.aspx?id=1760127&r=PI
ciao, a. 


Sono d'accordo con te.
IMHO una cosa è normalizzare e cercare di avere dei dati che rispecchino
la realtà delle entità che descrivono, altra cosa è esagerare e spingere
su concetti che sono palesemente traballanti, come quelle che hai segnalato.
-- 
David Martin

 segnalato.
i codici parlanti mi sembrano pericolosi in genere, molto pericolosi se si 
applicano a grandi numeri, voglia di farsi del male se li si usa come 
chiavi.
imho, ciao, a.

 usa come chiavi.
Una precisazione sulle chiavi parlanti (sottotipo di chiave artificiale):
per il data modeler, il codice fiscale è un attributo da importare nel
database, e non da creare a partire dalle altre colonne. In altre
parole, anche se a prima vista sembrerebbe il contrario, le colonne
"Nome", "Cognome" etc NON sono in dipendenza funzionale col CF o con
sue parti.
L'algoritmo di creazione del CF riguarda SOLO la procedura di
EMISSIONE del CF, di cui l'ente preposto se ne assume la responsabilità.
Una volta che è stato emesso alla persona, il database DEVE registrarlo
così com'è, anche se errato!
Se l'intento era quello di creare una chiave parlante, e si sbaglia
ad emetterla, lo scopo in quanto chiave parlante è fallito ma
permane quello di pk, ossia quello di IDENTIFICARE LA PERSONA; solo
quest'ultimo caso è quello che ci interessa come data modeler; la
prima parte sono regole del layer soprastante che il db DEVE
limitarsi solo a registrare.