Newsgroup: it.comp.software.database
Titolo: Attributi imprevedibili - valori multipli

Un ciao a tutti.
Sto sviluppando un sito di commercio elettronico dove il catalogo è
abbastanza mutevole e variegato.
Non ci sono prodotti dello stesso tipo, quindi una tabella del genere
non va bene:
prodotto (id, nome, attributo1, attributo2, prezzo, qtà)
La risposta sarebbe facile: fai tre tabelle così:
prodotto (id, nome, prezzo, qtà)
attibuto_valore (id, nome_attributo, VALORE)
prodotto_attributo_valore (prodotto, attributo_valore)
Una cosa del genere certamente permette di aggiungere nuovi attributi
(e i relativi valori) non previsti inizialmente.
Però, siccome diversi attributi possono avere diversi tipi di valori
(ad esempio: tipo stringa per l'attributo "colore", tipo integer per
l'attributo "taglia") toccherebbe dare alla colonna "valore" (quella
sopra in maiuscolo) della tabella "attributo_valore" il tipo varchar (o
simili, insomma testo!), con le ovvie ricadute in termini di velocità
di ricerca, di efficienza degli indici, ecc.
Domandona:
esiste una soluzione che permetta di rendere il db totalmente dinamico
(flessibile o come vi pare) in maniera che possano coesistere ora ed in
futuro prodotti totalmente diversi tra loro, con attributi totalmente
diversi tra loro, senza utilizzare per il campo "valore" il troppo
generico e poco efficiente tipo "stringa di caratteri".
Grazie e........ affrettatevi, sono come al solito in ritardo!

 
IMHO un DB dimanico non puo' esistere.
Vi prego di smentirmi perche' e' un argomento interessante :)
Pero' se magari ci specificassi cosa intendi vendere, magari una 
soluzione la troviamo.
Alla prossima.
	MAX

 Grazie e........ affrettatevi, sono come al solito in ritardo!
Ciao

 della tabella?
Suggerisci di aggiungere un campo "tipo" alla tabella
"attributo_valore" che indichi che tipo di dato sia memorizzato nel
campo "valore"?
E' così? E cosa ne faresti? Non vedo come possa aiutare.
La colonna "valore" non rimarrebbe lo stesso un varchar, su cui poter
effettuare solo delle interrogazioni di tipo testuale?

 
http://www.postgresql.org/files/documentation/books/aw_pgsql/node221.html
Sito di commercio elettronico, mysql.

 soluzione la troviamo.
Il problema da risolvere sta proprio qui: non sapere in anticipo cosa
si venderà.

 (e i relativi valori) non previsti inizialmente.
Pensa a quale query devi generare con "una cosa del genere" quando vuoi
l'elenco di prodotti in base a più di un attributo, es. una ricerca per
colore, dimensioni, peso, lotto...
È bello avere un database, ma alla fine bisogna poterci estrarre i dati!
Bye
-- 
Rudy
blog: 
http://rdbland.blogspot.com/
e-mail a 
email.it

 È bello avere un database, ma alla fine bisogna poterci estrarre i dati!
"una cosa del genere" la trovi in osCommerce.

 "una cosa del genere" la trovi in osCommerce.
Beh allora funziona? non funziona? va bene osCommerce? è veloce o lento?


 Beh allora funziona? non funziona? va bene osCommerce? è veloce o lento?
Credo vada abbastanza bene per un db che non sia quello di ebay o di
kelkoo.
Comunque ti prego di rileggere il quesito iniziale e i successivi
interventi.
Se hai voglia di darmi una mano e darla a chi è nella mia stessa
situazione, affianca alla tua critica una soluzione alternativa.
Grazie.

 situazione, affianca alla tua critica una soluzione alternativa.
Io volevo escludere la "risposta facile", che per me non è per nulla
scontata, anzi ti porterebbe a qualcosa di ingestibile.
A mio modo di vedere, un database è già "completamente dinamico", in
quanto mi permette di alterare a mio piacimento gli attributi degli
oggetti che inserisco.
In linea di principio, se vendo 300 tipi di oggetti _diversi_ tra loro,
avrò 300 tabelle diverse.
Se un oggetto cambia i suoi attributi, modificherò la sua tabella.


 Se un oggetto cambia i suoi attributi, modificherò la sua tabella.
Comporterebbe una "tabella delle tabelle" da consultare nel caso di
ricerche su tutto il catalogo o di elencazione dei vari tipi di
prodotto.
E il gestore del sito dovrebbe scegliere di volta in volta il tipo di
dati, tra quelli disponibili nel dbms, da assegnare ad ogni nuova
colonna.
Scongiuravo questa soluzione.
Devo rifletterci.
Grazie.

 
Azz, cominciamo bene :) :)
Comunque, da wikipedia:
La funzionalità di un database dipende in modo essenziale dalla sua 
progettazione: la corretta individuazione degli scopi del database e 
quindi delle tabelle, da definire attraverso i loro campi e le relazioni 
che le legano, permette poi una estrazione dei dati più veloce e, in 
generale, una gestione più efficiente.
Sempre IMHO non puoi progettare un DB senza sapere il suo scopo.
Almeno a grandi linee *devi* sapere cosa memorizzare.
Ciao.
	MAX

 colonna.
Sicuro. Scegliere tipi di dati sbagliati porta a una lunga serie di
problemi.


 Almeno a grandi linee *devi* sapere cosa memorizzare.
"L'applicazione deve consentire ad un cliente di effettuare ordini
scegliendo tra i prodotti presenti in un catalogo.
I prodotti, i loro attributi e le categorie in cui i prodotti sono
suddivisi devono poter essere creati, modificati e/o eliminati
direttamente tramite interfaccia web dal titolare del negozio."
Con tutto il rispetto, bastasse wikipedia x programmare!

 impossibile).
Mi aiuti a capire con un esempio? Mi sfuggono gli effetti collaterali
da te pronosticati.
Ecco una possibile situazione:
Tabella Prodotto:
------------------------
(id, nome, categoria, stringa_attributi, prezzo, qta)
1, "Nikon Star 5",  1, "1_5_7_19_4", 120, 12
2, "Audi A3", 5, "25_14_3", 40000, 2
Tabella Attributo_Valore:
----------------------------------
(id, attributo, valore)
1, "megapixel", "5,5"
2, "megapixel", "3"
3, "colore", "grigio metalizzato"
4, "colore", "nero"
5, "zoom", "10x"
6, "diametro", "1,2"
7, "custodia", "si"
...
14, "clima", "si"
....
19, "garanzia", "3 anni"
....

 Con tutto il rispetto, bastasse wikipedia x programmare!
Non basta Wiki per programmare, ma basta per chiarire alcuni concetti.
E per programmare non basta neanche Php+Mysql o qualsiasi cosa abbinata.
Alla prossima.
	MAX

 sempre tabelle distinte.
A livello di impiego di risorse, di prestazioni, di carico del server,
credo che 2 o 3 tabelle siano meglio di 50 con i relativi indici.
Fare cinque join complicate su una tabella già in cache dovrebbe
essere più veloce di una union di 20 tabelle non tutte disponibili
nella cache.
E secondo me trovare una struttura che risolve il problema in fase
progettuale è il risultato di un'ottima progettazione.
Aggiungere tabelle runtime non lo trovo troppo elegante.

 Aggiungere tabelle runtime non lo trovo troppo elegante.
Mai parlato di aggiungere a runtime.
E cmq rallenterebbe di parecchio le prestazioni.
Ciauz.
	MAX

 E cmq rallenterebbe di parecchio le prestazioni.
Se il catalogo è interamente gestito dal titolare/gestore del negozio,
nel momento in cui questi vorrà inserire un nuovo tipo di prodotto,
seguendo la logica una_tabella_x_tipo_di_prodotto, il sistema dovrà
generare runtime una nuova tabella con le colonne e i tipi definiti
runtime dal gestore. Per forza!

Antonio Pedone ha scritto:

mi trovi con una sola query le macchine fotografiche con una garanzia di 3 anni da 5 megapixel?
;)
*perchè* non puoi?

 *perchè* non puoi?
non lo so!

 runtime dal gestore. Per forza!
Allora non puo' crearsi delle nuove tabelle??
Bho, forse sono un po' duro di comprendonio, ma non riesco a seguirti.
	MAX
..

 Bho, forse sono un po' duro di comprendonio, ma non riesco a seguirti.
no, assolutamente, sono io che forse non so spiegarmi!
Sarà compito del gestore creare le nuove tabelle, ma non posso
farglielo fare direttamente con l'sql! Gli devo mettere il codice
opportuno affinchè lui, attraverso la scintillante interfaccia grafica
del pannello di controllo del sito, si crea le categorie, i prodotti e
gli attributi che gli servono e il sistema da sotto fa il lavoro sporco
di crearsi le nuove tabelle. Tradotto: creazione della tabelle runtime,
da codice, su input del gestore.

 compilati a runtime in base alla tabella "attributo_valore":
Sorry, ma come farai a discriminare gli attributi??
Pensa a tutti i possibili colori di tutti i modelli di tutte le marche 
di auto.
Ed e' solo un tipo prodotto, pensa in grande, non su due o tre attributi.
Se poi andiamo nella categoria dei cellulari, c'e' da impazzire.
Alla prossima.
	MAX

 
Sbagliato, tu crei tutte le tabelle.
Il tuo cliente puo' solo riempirle.
E se le tabelle sono progettate correttamente, le query "vengono giu'" 
da sole :)
Ciao.
	MAx

massimo61 ha scritto:

Si possono discriminare agevolmente.
Ci sarà una tabella categoria che, oltre al nome ed altre amenità,
conterrà gli attributi (non i valori) possibili per ciascuna categoria
(faccio un master-detail che è meglio). Uso questo dato per fare le
opportune select su attributo_valore al fine di compilare i combobox.
In definitiva dovrebbe essere così:
prodotto (id, nome, stringa_attributi, categoria, prezzo, qta)
categoria (id, nome)
categoria_attributo (categoria, attributo_ammesso)
attributo (id, nome)
attributo_valore (id, attributo, valore)
Al di la di tutto, vi ringrazio per la disponibilità e per avermi
tenuto compagnia per un pomeriggio intero!!!

 da sole :)
Non posso creare oggi tutte le tabelle! Non so cosa servirà tra un
mese, sul serio!
A meno che non gli faccia l'assistenza sulla struttura logica e ogni
volta che vuole aggiungere nuovi tipi di prodotti mi debba chiamare per
adeguare il db: soluzione poco ortodossa ma più remunerativa!

 stringa_attributi LIKE "%_114_%"
...il che causerà una meravigliosa table scan dell'unica tabella
che hai, vanificando il proposito di migliorare le prestazioni.

 progettuale è il risultato di un'ottima progettazione.
Mi spiace, non esistono le scorciatoie. Una soluzione semplicistica
è un problema forse anche maggiore...

 adeguare il db: soluzione poco ortodossa ma più remunerativa!
Del design EAV ne abbiamo già parlato, ed ormai sta diventando una faq.
Al cliente devi semplicemente comunicare che sta diventanto il nuovo
dba. Come sono le sue conoscenze di data modeling?
Questo design è ancora meno dell'application-managed data integrity;
siamo all'user-managed data integrity. Il dbms viene relegato
al ruolo di string-manager che può solamente mostrare sullo
schermo i dati, nella speranza che l'utente sappia cosa farsene; il
che è come fare fotocopie, solo senza carta [cit.].
Come altri ti hanno già detto, verrà il momento che col db
dovrai farcene qualcosa di significativo, e lì il vantaggio di
perdere meno tempo della stesura dello schema svanirà in un bagno
di sangue di codice complesso.
Il senso di un design normalizzato è che maggiore è il livello di
separazione, maggiore è l'utilità dei dati, dato che maggiori sono
le _deduzioni_ che siamo in grado di trarre dal db. Semplicemente ci
si è accorti che normalizzando, nuove ed interessanti proprietà
emergono da quello che prima sembrava un "unicum" informe; sopra
questo si possono costruire regole deduttive e utili vincoli di
integrità.
bye

The man with two watches ha scritto:

   senza parlare del fatto che 25 possa essere il *primo* (?!) attributo
e quindi %_25_% *non* lo troverà ;)

 Sicuramente si.
Mmmmh. Prove/misure fisiche di tutto ciò?
Bye :-)


 e quindi %_25_% *non* lo troverà
Con un pizzico di immaginazione potresti pensare alla stringa attributi
come una cosa del genere "_id1_id2_..._idN_", ma non è il caso di
scrivere qui tutto il codice, non credi? O forse pensi che questo sia
il vero problema da affrontare?
Volevi una sola query? Come vedi è possibile.
Ora non chiedermi di fare tutta l'applicazione in una sola riga di
codice!

 "Antonio Pedone"

Certo, se il db fosse un papiro egizio!
Un ovvio e banale indice sulla colonna categoria, aiuterebbe parecchio,
non credi?

 recuperano una maggiore quantità di dati significativi.
Cosa ti fa sospettare che le tabelle da me ipotizzate non siano
normalizzate?

 Mmmmh. Prove/misure fisiche di tutto ciò?
Credo di non aver previsto cose esatte riguardo le prestazioni e le
risorse, ma a questo punto per fare un'analisi seria bisognerebbe
prendere le due possibili versioni (EAV e "tabellosa" ;) ) e fare una
seria analisi degli accessi in lettura e scrittura per ogni operazione
prevista dall'applicazione, considerando volumi dei dati, indici, ecc.

 è un problema forse anche maggiore...
Dopo aver appreso che trattasi di "design EAV" ho fatto una ricerca in
questo ng per scoprire che tu, altrove, hai dato il placet per una
soluzione simile a quella proposta da me, sostenendo che alla fine è
un buon compromesso tra esigenze applicative e dogmi relazionali.
Scusa la semplificazione dei concetti, i termini non sono quelli, lo
so, ma la fretta nello scrivere mi impone praticità.
Ancora grazie.

 prevista dall'applicazione, considerando volumi dei dati, indici, ecc.
Infatti le analisi serie si fanno tranquillamente.
Con mysql 4 non vedo molte possibilità, con il 5 non penso che ci siano
significative novità sul tema (ora controllo).
Se vuoi prova a creare il database di test nelle due versioni per
Oracle, me lo mandi e provo a fare qualche misura con le tue query. Non
ho tempo per crearne uno da solo, se no lo farei volentieri.


 scrivere qui tutto il codice, non credi?
Con tutto quel codice arriveresti a riscrivere le funzionalità che un
database qualunque GIÀ ti da, non pensi?
Bye


 database qualunque GIÀ ti da, non pensi?
Vabbè, parliamo, nel caso specifico della gestione stringa_attributi,
di *al massimo*, ad essere asini, una decina di righe!
Il guadagno però sta nell'avere una struttura che rende il db pronto
per qualsiasi variazione al catalogo, consentendo di ricavare i dati
utili alla compilazione di un modulo di ricerca, o all'elencazione dei
prodotti suddivisi per categorie, con delle interrogazioni su tabelle
certe e immutabili. Diversamente, nell'altra soluzione, per diverse
operazioni utili all'applicazione, da codice dovrei controllare ogni
volta qual'è al momento la struttura del db.

 ho tempo per crearne uno da solo, se no lo farei volentieri.
Ti ringrazio davvero tanto. Se avessi il tempo per sfruttare la tua
disponibilità lo farei senza esitare!!
PURTROPPO non è così, e lo scopo di queto thread era proprio questo:
attingere alle esperienze e alla competenza del ng per prendere una
decisione "veloce".
Mi rendo conto che non è detto che qualcuno si sia trovato di fronte
al mio stesso identico problema, agli stessi vincoli realizzativi, ma
dalla mia parte ho il conforto di un'applicazione come osCommerce, per
lo scopo da me velocemente analizzata, la cui struttura, dovendo
servire ad uno utilizzo il più generico e flessibile possibile,
risulta essere simile a quella da me proposta.

 e-mail a 
email.it
Ho scaricato quel documento sulla progettazione suggerito nel tuo blog.
Appena avrò finito darò una lettura più attenta sia a quel documento
che al tuo blog.
Spero non debba accorgermi in ritardo di aver fatto delle grandi
stupidaggini.
Ciao :-)

 normalizzate?
Nessuna ipotesi da parte mia: hai postato lo schema.
Quel design non raggiunge neppure la 1nf, requisito fondamentale
dei db relazionali.
bye

 stupidaggini.
Allora leggi subito la sezione: "Don't Use Generic Data Models"
"Frequently, I see applications built on a generic data model for
"maximum flexibility" or applications built in ways that
prohibit performance. [...]
But how does this model perform? Miserably, terribly, and horribly."

"Antonio Pedone"


Ti sto dicendo appunto di no: una clausola where così scritta impedisce
il seek nell'albero binario dell'indice.

 il seek nell'albero binario dell'indice.
Sottintendevo l'aggiunta di categoria="fotocamere". Spero il problema
non stia in dettagli omessi ma facilmente immaginabili!

 But how does this model perform? Miserably, terribly, and horribly."
Ci sono le mie tabelle!! Che copioni!

 è un buon compromesso tra esigenze applicative e dogmi relazionali.
Probabilmente ti riferisci a questo:
"Voglio essere pragmatico: per potere, si può. Il vero punto in
questione è quanto è importante per il tuo business la correttezza dei
dati. In alcuni contesti non mission-critical, specie se chi fa il
data entry sono uno o due specifici addetti ai lavori, potrebbe essere
tollerato. In altro ambiente, sarebbe impensabile."
Penso e spero di non aver dato una assoluzione omnibus, ma motivata
peraltro con pesanti pregiudiziali ("quanto è importante la correttezza
dei dati"). Quello che mi preme sottolineare è che ogni cosa ha il
suo prezzo da pagare.
Naturalmente poi, ciascuno sceglie, ed è questo in fondo che ci fa
sentire liberi; per me la libertà è anche quella di trasgredire.
Ma qua andiamo sul filosofico :-)
bye
PS: non credere che io non abbia fatto i miei bei errori... quello
che desidero è in realtà farli evitare agli altri

 tollerato. In altro ambiente, sarebbe impensabile."
No, mi riferisco a questo:
[quote]
Può andare, ma prova a pensare uno schema semi-eav ancora più
semplice, composto da una tabella "base" e una con le caratteristiche
"opzionali", tipo:
Articoli {Codice, Nome, Prezzo, Giacenza}
Caratteristiche {CodiceArticolo, Descrizione[, Valore]}
Più semplice tieni la seconda, meno ti incasini, e ricordando
comunque che non puoi farci troppo affidamento perché "problematica".
[/quote]
Mi sembra il fratello del mio schema, o comunque un parente
strettissimo!

 dei db relazionali.
Ti riferisci all'attributo "stringa_attributi" multivalore, vero?
Un po' di codice, anche piuttosto semplice, permetterebbe di sfruttare
l'"illecito formale" come trucco per evitare fastidiose join multiple,
costruibili solo attraverso la scrittura di molto più noioso e
cavilloso codice. Senza parlare dell'altra soluzione, quella "una
tabella per ogni tipo di prodotto", che, a meno che il cliente non
decida di assumermi, comporterebbe la stesura di un codice mille volte
più complesso, se si vuole che il sistema "regga" qualsiasi
variazione, aggiunta o sottrazione, della struttura dati.
Nello stesso documento succitato (il pdf del blog) si parla,
all'inizio, dell'opportunità di un lavoro congiunto tra programmatori
e dba.
Credo che gli integralismi, da entrambe le parti, possano far mancare
l'obiettivo.
A mio modo di vedere una struttura dati più corretta formalmente
porterebbe al suicidio del programmatore, che comunque dovrà rendere
conto della risposta del sistema ai requisiti posti dal cliente.

 conto della risposta del sistema ai requisiti posti dal cliente.
Nella mia esperienza, né lunga né breve, ho più prove del contrario.
Comunque tienici aggiornati, facci sapere che cosa scegli e come procede.
Bye
-- 


 Comunque tienici aggiornati, facci sapere che cosa scegli e come procede.
Sarebbe bello poter realizzare entrambe le versioni e farle gareggiare
sul campo per vedere chi vince. Potrei gestire eventuali scommesse! ;-)
Grazie.

 
Ciao. Oltre alle osservazioni che sono state fatte su questo "modello" (osservazioni che condivido), vorrei farti notare
un altro punto debole che, IMHO, potrebbe interessare anche il tuo cliente:
le coppie attributo-valore assegnabili ad un oggetto sono solo quelle presenti nella tabella attributo_valore (insieme
definito dall'utente); quindi anche per attributi tipo "larghezza" o "altezza", che possono avere normalmente un valore
numerico, dovranno essere inseriti tutti i possibili valori? L'utente vedrà una tendina con tutti i valori di larghezza
utilizzati (dalla macchina fotografica all'automobile)?
Inoltre: alcuni attributi sono applicabili ad oggetti di differenti categorie (es colore), ma i valori possibili non
sono gli stessi per entrambe le categorie: nella tendina in cui selezionare il colore di una camicia non è molto bello
vedere "grigio metallizzato".
Ti faccio una domanda provocatoria. Se le idee su quali sono le caratteristiche degli oggetti da vendere sono così
incerte non hai preso in considerazione la possibilità di fare una banalissima tabella:
oggetto (nome, prezzo, quantità, descrizione)
dove "descrizione" è compilato dal gestore del sito come meglio crede e ricercabile full-text dagli utenti del sito?
Certo non si potrà pretendere (se non a prezzi alti) di tirare fuori dei dati strutturati da un database come questo ma
è un il prezzo da pagare in futuro per non aver voluto spendere ora qualcosa in più per strutturare i dati in partenza.
Spero che queste osservazioni ti siano utili.
Ciao.

 Volevi una sola query? 
volevo invitarti a riflettere sulla struttura del tuo db

 Spero che queste osservazioni ti siano utili.
Tutte le osservazioni fin qui sono state preziose.
Spero questo thread risulti d'aiuto a chi si troverà nella situazione
in cui mi trovavo ieri. Ho scelto come titolo "attributi imprevedibili,
valori multipli" proprio per facilitare chi sta cercando una soluzione
al problema dell'imprevedibilità. Io con quelle chiavi di ricerca non
ho trovato molto.

 join multiple,
Lo desideri proprio, a tutti i costi, vero? Allora niente al mondo
potrà fermarti.
Ti regalo uno dei miei orologi e buona fortuna :-)

 Ti regalo uno dei miei orologi e buona fortuna :-)
Rinunceresti a metà del tuo nick?
Non saprei come ricambiare, se vuoi ti regalo il mio cognome, ma non
penso te ne possa fare granchè!
Alla prossima.

Grazie e........ affrettatevi, sono come al solito in ritardo!
Io volevo provare a darti un consiglio perchè sgli schemi eav ci sono
cascato pure io anche se non ho capito bene il tuo problema...
ti do due consiglio che hanno dato a me
1) Il db ragiona tramite chiavi fai altrettanto
2) esamina bene ed isola i tuo problemi e cerca di capire
"veramente" quale è il problema.
3)fai una analisi dettaglia ci sono 2000 modi per modellare uno schema
trova più di una soluzione....
4) poniti delle domande cosa succede se ... ? e se .. ?
Metti che tu usi una strategia per rendere felice il cliente e te ma quella 
strategia
ti porta al degrado snaturamente del db e quindi risolve il tuo problema
imminente, ma tua sai meglio di me che un software e specialmente
un e-commerce cresce si modificano rapidamente, ti porta a non poter
fare più certe scelte che ne so
supponiamo che voglia fare statistiche
cosa gli dici che devi riprogettare il db ?
Sono solo esempi astratti
O se ti dice che vuole cambiare host e db ? che gli dici ?
Comunque per progettare un db ci sono tutta una serie di passi
da fare io ti consiglio prima di farli e poi di valutare se seguirli o
meno ma almeno sei coscente dei limiti delle possibilità e dove stai
andando a finire...
prima lo scopo del db ,
poi tabella
poi campi
poi chiavi
etc
etc
Un db è uno strumento molto potente e flessibile ma va usato con accortezza
Devi capire esattemente quali sono i tuoi limiti o i limiti del tuo db
Si dice che un programmatore usa sempre quello gli serve in base alle 
esigenze!
Bè devi fare lo stesso devi valutare lo strumento come lo usi e vedere
e può essere di tuo aiuto etc ma usarlo per quello che è stato pensato!
Un db non può fare tutto ed il cliente vuole sempre tutto... (inventa sul 
momento)
E' il consiglio migliore che possa darti...
ciao
e
buon lavoro

 momento)
*Inventata non inventa, per non confondere...