Aiuto su struttura db: tabella singola o multiple

di il
14 risposte

Aiuto su struttura db: tabella singola o multiple

Ciao a tutti.
Sono agli inizi con i DB, per cui vorrei chiedervi un aiuto nella creazione di una struttura di DB x SQLite.

Vorrei fare un DB di libri che hanno alcuni attributi statici e altri dinamici.
Per quelli statici pensavo a una tabella tipo:
Book (bookID (P), title, author, subtitle, type (e-book, pb, audiobook) )
per quelli dinamici potrei voler monitorare:
pages
reviews + ratings per market
internal ranking per market
price (che cambia anche altri parametri come royalty)

Pensavo a 2 soluzioni:

es:
date = 24 Oct, bookID = 35, price = 13.90, royalty = 5.01, page = 245, review = 232, rating = 312, ranking = 23467

1) creare diverse tabelle per ogni attributo da monitorare con la data della sua modifica:
Page    (actualDate, bookID FK, page)
Review  (actualDate, bookID FK, market, review)
Rating  (actualDate, bookID FK, market, ratings)
Ranking (actualDate, bookID FK, market, ranking)
Price   (actualDate, bookID FK, market, price, royalty)
In questo caso inserirei una riga solo se quell'attributo cambia.
se cambiano tutti:
Page    -->     24 Oct,     35,         245
Review  -->     24 Oct,     35,         "com",  232
Rating  -->     24 Oct,     35,         "com",  312
Ranking -->     24 Oct,     35,         "com",  23467
Price   -->     24 Oct,     35,         "com",  1390,       501
Solo che in questo modo avrei per ogni libro 4x3 più ripetizioni rispetto alla 2) di: [24 Oct, 35, "com"]


2) fare una sola tabella dove metto i vari attributi, a parte magari il Price:
BookData (actualDate, bookID FK, market, priceID FK, page, review, rating, ranking) 
Price    (priceID, price, royalty)
se in una data sono cambiati tutti :
BookData-->     24 Oct,     35,         "com",  16,         245,     232,   312,   23467
Price   -->     16,         1390,       501
Però qui mi toccherebbe creare una riga anche se solo un attributo cambia (e mettere null negli altri?) es:
BookData-->     24 Oct,     35,         "com",  null,         null,     null,    23467
Potrei magari ridurre una tabella, accorpando review + rating, però se ho il dato review ho anche il rating, NON sempre viceversa, per cui potrei avere una situazione come:
Review --> 24 Oct, 35, "com", 232,312
Review --> 28 Oct, 35, "com", null, 321
E quindi alla data 28 Oct il libro avrebbe 232 review e 321 ratings, ma in due righe diverse

Nelle query, vorrei poter recuperare i dati statici e dinamici di un libro/tutti i libri, nella data attuale o in un range di date.
Quindi dovrei riuscire a gestire sia gli eventuali null che i dati raccolti in più date diverse...

Che struttura mi consigliereste di usare?
Grazie, ciao

14 Risposte

  • Re: Aiuto su struttura db: tabella singola o multiple

    frank10 ha scritto:


    aiuto nella creazione di una struttura di DB x SQLite
    Io non so usare SQLite, ma le strutture database sono standard per tutte le applicazioni.

    frank10 ha scritto:


    Vorrei fare un DB di libri che hanno alcuni attributi statici e altri dinamici.
    Cosa intendi? Anche leggendo il resto che hai scritto (si scrive davvero tutto così come lo hai scritto tu?): non capisco.

    Database per libri: sicuramente ti servono molte tabelle correlate. Lo scopo è stile "biblioteca" oppure "libreria" (per vendita)? In ogni caso, a seconda di "cosa ti interessa davvero tracciare", potrebbero cambiare alcune tabelle/relazioni.

    Se ti riesce una descrizione più "verticale" e con termini in italiano (molti campi non li ho capiti), proviamo a rendere la discussione più fluida.
  • Re: Aiuto su struttura db: tabella singola o multiple

    Allora metto i campi in italiano con una legenda e cerco di spiegare meglio anche con esempi:

    P = primary key, chiave primaria
    FK = foreign Key, chiave esterna
    "mercato" è il mercato dove viene commercializzato il libro, tipo "com"=USA, "it"=Italia, "de"=Germania etc
    "tipologia" può essere: (libro digitale, PB = stampato on demand, audiolibro)
    libri on demand = libri che vengono stampati solo al momento dell'acquisto online: non c'è magazzino e si possono quindi cambiare più volte i contenuti e quindi cambiano le pagine etc
    Anche il prezzo oscilla.
    I siti che li vendono, come Amazon, utilizzano recensioni dei clienti, punteggio (comprendono le valutazioni fatte da 1 a 5 stelline senza recensione + le recensioni scritte), posizionamento in loro classifica interna per mercato di riferimento.
    E si possono vendere in vari mercati internazionali: per es. lo stesso libro scritto in inglese lo si può vendere in USA, in Canada, in Australia, in Inghilterra
    e quindi cambia il "mercato" e anche il n° di recensioni e la classifica interna avrà valori diversi a seconda del mercato anche se è lo stesso libro.

    Lo scopo di questo DB è raccogliere le modifiche fatte a certi libri nel tempo per poi poter interrogare il DB e avere una lista dei dati modificati in un certo intervallo di date, oppure la situazione attuale del libro per tutti gli attributi elencati.
    Poi eventualmente, con questi dati, comparare l'andamento delle modifiche fra libri concorrenti, fare grafici etc

    Tabella base per attributi statici del libro (non cambiano nel tempo)
    Libro           (libroID (P), ISBN, titolo, autore, sottotitolo, tipologia )  
    
    es:
    dataAttuale = 24 Oct, libroID = 35, ISBN= 3240276353, prezzo = 13.90, 
    incasso = 5.01, pagina = 245, recensione = 232, punteggio = 312, classifica = 23467
    Per gli attributi dinamici, che possono cambiare nel tempo e anche spesso:
    1)
    creare diverse tabelle per ogni attributo da monitorare con la data della sua modifica:
    Pagina          (dataAttuale, libroID FK, pagina)
    Recensione      (dataAttuale, libroID FK, mercato, recensione)
    Punteggio       (dataAttuale, libroID FK, mercato, punteggio)
    Classifica      (dataAttuale, libroID FK, mercato, classifica)
    Prezzo          (dataAttuale, libroID FK, mercato, prezzo, incasso)
    In questo caso inserirei una riga solo se quell'attributo cambia in quella determinata data.

    Se invece cambiano tutti gli attributi nella stessa data diventerebbe:
    Libro           -->     35, 3240276353, "titolo libro1", "autore1", "sottotitolo libro1", "PB"
    Pagina          -->     24 Ott,     35,         245
    Recensione      -->     24 Ott,     35,         "com",  232
    Punteggio       -->     24 Ott,     35,         "com",  312
    Classifica      -->     24 Ott,     35,         "com",  23467
    Prezzo          -->     24 Ott,     35,         "com",  1390,       501
    Ma in questo modo avrei per ogni libro 4x3 più ripetizioni rispetto alla 2) di: [24 Ott, 35, "com"]

    2)
    DatiDinamici    (dataAttuale, libroID FK, mercato, prezzoID FK, pagina, recensione, punteggio, classifica) 
    Prezzo          (prezzoID, prezzo, incasso)
    fare una sola tabella "DatiDinamici" dove metto i vari attributi dinamici, a parte magari il Prezzo:
    Libro           -->     35, 3240276353, "titolo libro1", "autore1", "sottotitolo libro1", "PB"
    DatiDinamici    -->     24 Ott,     35,         "com",  16,         245,     232,   312,   23467
    Prezzo          -->     16,         1390,       501
    Però qui mi toccherebbe creare una riga anche se solo un attributo cambia (e mettere null negli altri?) es:
    DatiDinamici    -->     24 Ott,     35,         "com",  null,       null,   null,   null,   23467

    Con un esempio più realistico, quindi si potrebbe creare una situazione in cui ho:

    1)
    Libro           -->     35, 3240276353, "titolo libro1", "autore1", "sottotitolo libro1", "PB"
    Pagina          -->     24 Ott,     35,         245
    Recensione      -->     24 Ott,     35,         "com",  232
    Punteggio       -->     24 Ott,     35,         "com",  312
    Punteggio       -->     28 Ott,     35,         "com",  314
    Classifica      -->     24 Ott,     35,         "com",  23467
    Classifica      -->     25 Ott,     35,         "com",  57877
    Classifica      -->     28 Ott,     35,         "com",  3432
    Classifica      -->     30 Ott,     35,         "com",  8932
    Prezzo          -->     24 Ott,     35,         "com",  1390,       501
    Prezzo          -->     28 Ott,     35,         "com",  1199,       432
    oppure:

    2)
    Libro           -->     35, 3240276353, "titolo libro1", "autore1", "sottotitolo libro1", "PB"
    DatiDinamici    -->     24 Ott,     35,         "com",  16,         245,     232,   312,   23467
    DatiDinamici    -->     25 Ott,     35,         "com",  null,       null,   null,   null,  57877
    DatiDinamici    -->     28 Ott,     35,         "com",  17,         null,   null,   314,   3432
    DatiDinamici    -->     30 Ott,     35,         "com",  null,       null,   null,   null,  8932
    Prezzo          -->     16,         1390,       501
    Prezzo          -->     17,         1199,       432
    
    Se io voglio sapere al 29 Ott, quali attributi dinamici ha il libro con ID=35, che query dovrei fare nella 1) e nella 2) tenendo conto dei null ?
    Quale approccio è migliore come query, come occupazione di spazio nel DB, come normalizzazione etc
    Cioè appunto... qual è la miglior struttura per un DB come questo: tabella singola riassuntiva o tabelle multiple ridondanti?
  • Re: Aiuto su struttura db: tabella singola o multiple

    frank10 ha scritto:


    Tabella base per attributi statici del libro (non cambiano nel tempo)
    Libro           (libroID (P), ISBN, titolo, autore, sottotitolo, tipologia )
    OK. Però mi raccomando i nomi delle tabelle vanno scritti al PLURALE, quindi Libri.

    frank10 ha scritto:


    Per gli attributi dinamici, che possono cambiare nel tempo e anche spesso:
    1)
    creare diverse tabelle per ogni attributo da monitorare con la data della sua modifica:
    Pagina          (dataAttuale, libroID FK, pagina)
    Recensione      (dataAttuale, libroID FK, mercato, recensione)
    Punteggio       (dataAttuale, libroID FK, mercato, punteggio)
    Classifica      (dataAttuale, libroID FK, mercato, classifica)
    Prezzo          (dataAttuale, libroID FK, mercato, prezzo, incasso)
    In questo caso inserirei una riga solo se quell'attributo cambia in quella determinata data.
    No. Facci caso molti campi sono uguali. Per risolvere questo aspetto utilizzi una sola tabella che potresti chiamare Variazioni o Varianti. Usi gli stessi campi omonimi con l'aggiunta di un campo di discriminazione che puoi nominare TipoVariazione, quindi specifichi se si tratta di Pagina, Recensione, Punteggio, Classifica, Prezzo.

    Inoltre non confondere i concetti di TABELLE e QUERY. Le tabelle sono i contenitori primordiali dei dati, quelli che solo l'utente deve digitare. Le query possono mostrare dati provenienti da più tabelle correlate. Mi raccomando un campo IDLibro (FK) nella tabella Varianti, quindi la relazione Libri.IDLibro uno-a-molti Varianti.IDLibro.
  • Re: Aiuto su struttura db: tabella singola o multiple

    Sul nome singolare o plurale delle tabelle, ho letto varie posizioni discordanti... soprattutto con le regole dei nomi plurali inglesi... per semplificare consigliavano appunto di usare sempre il singolare col quale non si può sbagliare la grammatica. Cmq basta essere consistenti, o sempre singolare o sempre plurale all'interno del DB...

    Non ho capito come imposteresti la tabella singola Varianti, tipo così?
    Varianti (  libroID FK, dataAttuale,  mercato, valore, tipoVariazione )
    es.
    
    Libri           -->     35, 3240276353, "titolo libro1", "autore1", "sottotitolo libro1", "PB"
    Varianti        -->     35, 24 Ott,  "com", 245,  "Pagina"
    Varianti        -->     35, 24 Ott,  "com", 232,  "Recensione"
    Varianti        -->     35, 24 Ott,  "com", 312,  "Punteggio"
    
    Se è così però non vedo il vantaggio rispetto alle singole tabelle dedicate... avrei cmq sempre molti duplicati della tripletta [35, 24 Oct, "com"], no?

    oppure intendi così:
    
    Varianti        ( varianteID (P), libroID FK, dataAttuale,  mercato, tipoVariazione )
    Recensione      ( varianteID FK, recensione )
    Punteggio       ( varianteID FK, punteggio )
    
    Varianti        -->     12, 35, 24 Ott,  "com", "Punteggio"
    Varianti        -->     13, 35, 24 Ott,  "com", "Recensione"
    Varianti        -->     14, 35, 28 Ott,  "com", "Punteggio"
    Punteggio       -->     12,  312
    Recensione      -->     13,  232
    Punteggio       -->     14,  314
    
    In questo modo uso la FK per evitare di riscrivere ogni volta i 3 valori, però allora non capisco cosa serve "tipoVariazione"
    questo approccio l'avrei pensato senza:
    
    Varianti        ( varianteID (P), libroID FK, dataAttuale,  mercato)
    Recensione      ( varianteID FK, recensione )
    Punteggio       ( varianteID FK, punteggio )
    
    Varianti        -->     12, 35, 24 Ott,  "com"
    Varianti        -->     13, 35, 28 Ott,  "com"
    Punteggio       -->     12,  312
    Recensione      -->     12,  232
    Punteggio       -->     13,  314
    e così riutilizzo la riga uguale di Varianti su multiple tabelle con un unico integer FK.
    
    Puoi scrivere con un esempio come intendevi comporre la tabella Varianti?
  • Re: Aiuto su struttura db: tabella singola o multiple

    frank10 ha scritto:


    Non ho capito come imposteresti la tabella singola Varianti, tipo così?
    Varianti (  libroID FK, dataAttuale,  mercato, valore, tipoVariazione )
    Ti consiglio di aggiungere sempre la PK, quindi IDVariante o VarianteID.

    frank10 ha scritto:


    es.
    Libri           -->     35, 3240276353, "titolo libro1", "autore1", "sottotitolo libro1", "PB"
    Varianti        -->     35, 24 Ott,  "com", 245,  "Pagina"
    Varianti        -->     35, 24 Ott,  "com", 232,  "Recensione"
    Varianti        -->     35, 24 Ott,  "com", 312,  "Punteggio"
    Se è così però non vedo il vantaggio rispetto alle singole tabelle dedicate... avrei cmq sempre molti duplicati della tripletta [35, 24 Oct, "com"], no?
    Sì esatto. Ora non so come si usa SQLite...io uso Access dove puoi creare una maschera/sottomaschera. Quest'ultima avrebbe LibroID in automatico. Poi per gli altri valori ripetuti esiste la comoda combinazione tasti CTRL+' (apostrofo) per riprendere automaticamente il valore campo del record precedente.
  • Re: Aiuto su struttura db: tabella singola o multiple

    Bé SQLite è molto simile a SQL... quindi facciamo finta sia un DB SQL...

    In ottica di ridurre più possibile le duplicazioni nelle celle delle tabelle, e quindi lo spazio nel file DB,
    ha senso una cosa così?
    Libri           ( libroID (P), ISBN, titolo, autore, sottotitolo, tipologia )
    DateRilevamenti ( dateID (P), dataAttuale )
    Mercati         ( mercatoID (P), mercato )
    Pagina          ( paginaID (P), dateID (FK), libroID (FK), pagina )
    Recensione      ( recensioneID (P), dateID (FK), libroID (FK), mercatoID (FK), recensione )
    Punteggio       ( punteggioID (P), dateID (FK), libroID (FK),  mercatoID (FK), punteggio )
    Classifica      ( classificaID (P), dateID (FK), libroID (FK),  mercatoID (FK), classifica )
    Prezzo          ( prezzoID (P), dateID (FK), libroID (FK),  mercatoID (FK), prezzo, incasso )
    Libri           -->     35, 3240276353, "titolo libro1", "autore1", "sottotitolo libro1", "PB"
    DateRilevamenti -->     1, 24 Ott
    DateRilevamenti -->     2, 25 Ott
    DateRilevamenti -->     3, 28 Ott
    DateRilevamenti -->     4, 30 Ott
    Mercati         -->     1, "com"
    e poi i dati dinamici con le varie FK:

    1)
    Pagina          -->     1,     35,         245
    Recensione      -->     1,     35,         1,  232
    Punteggio       -->     1,     35,         1,  312
    Punteggio       -->     3,     35,         1,  314
    Classifica      -->     1,     35,         1,  23467
    Classifica      -->     2,     35,         1,  57877
    Classifica      -->     3,     35,         1,  3432
    Classifica      -->     4,     35,         1,  8932
    Prezzo          -->     1,     35,         1,  1390,       501
    Prezzo          -->     3,     35,         1,  1199,       432

    2)
    DatiDinamici ( dinamiciID (P) , dateID (FK), libroID (FK), mercato, prezzoID (FK), pagina, recensione, punteggio, classifica)
    Prezzo ( prezzoID (P), prezzo, incasso)
    DatiDinamici    -->     1,     35,         1,  16,         245,     232,   312,   23467
    DatiDinamici    -->     2,     35,         1,  null,       null,   null,   null,  57877
    DatiDinamici    -->     3,     35,         1,  17,         null,   null,   314,   3432
    DatiDinamici    -->     4,     35,         1,  null,       null,   null,   null,  8932
    Prezzo          -->     16,         1390,       501
    Prezzo          -->     17,         1199,       432
  • Re: Aiuto su struttura db: tabella singola o multiple

    Ho provato a creare il DB x test :


    come query per ottenere un risultato come questo al 30 Ottobre, con i valori di recensione e punteggio più recenti e vicini alla data del 30, essendo però stati inseriti in date precedenti diverse:
    (per ora ho semplificato la data in un semplice integer del giorno di Ottobre, alla fine verrà inserito un timestamp più completo... )
    Risultato voluto:
    dataAttuale,   titolo, mercato, pagina, recensione, punteggio
    30,            titolo1, com,    245,    232,        314
    
    Come si procede con la Query?
    Ho provato così, ma ovviamente ci sono troppi risultati duplicati...
    
    SELECT d.dataAttuale, l.titolo, m.mercato, p.pagina, r.recensione, pu.punteggio 
    
    FROM Libri l, DateRilevamenti d, Mercati m
    
    INNER JOIN  Pagina p ON l.libroID = p.libroID
    INNER JOIN  Recensione r ON l.libroID = r.libroID
    INNER JOIN  Punteggio pu ON l.libroID = pu.libroID
    
    WHERE l.libroID = (SELECT l.libroID From Libri l WHERE l.titolo = "titolo libro1") and m.mercato = "com"
    
    Come si arriva al risultato corretto?
  • Re: Aiuto su struttura db: tabella singola o multiple

    Continui a proporre tutte quelle inutili e ridondanti tabelle. Ti servono solo 2 tabelle Libri e Varianti con le PK e FK e una relazione uno-a-molti che ti ho detto. Questo per quanto riguarda la Progettazione Database discutibile in questa sezione del forum. Per testare le query (assodata la corretta progettazione) devi aprire una nuova discussione nella sezione dedicata.
  • Re: Aiuto su struttura db: tabella singola o multiple

    Nella mia risposta sopra ti ho scritto:
    "Se è così però non vedo il vantaggio rispetto alle singole tabelle dedicate... avrei cmq sempre molti duplicati della tripletta [35, 24 Oct, "com"], no?"
    E mi hai risposto: "Sì esatto."

    Quindi quale vantaggio avrei a farlo col tuo suggerimento? Avrei la stessa ridondanza di eccessivi campi duplicati nel file DB e credo pure un DB non normalizzato.
    Per quel che ho capito la normalizzazione prevederebbe appunto di spostare i contenuti in tabelle separate collegate in FK o sbaglio? Oppure non servirebbe la normalizzazione?

    Per richiesta query in altra sezione ok, ma qui volevo provare a vedere quale livello di complicazione di query veniva fuori nei vari casi: anche questo poteva essere un discriminante per la scelta della struttura: se query troppo complicate e difficili da gestire, poteva essere da scartare quella struttura...
  • Re: Aiuto su struttura db: tabella singola o multiple

    Una tabella ha 5 campi che la rappresentano. Escludi la PK. Non è importante la duplicazione di 3 dei 4 campi rimanenti, ma l'intera combinazione dei 4 campi che deve risultare diversa.
  • Re: Aiuto su struttura db: tabella singola o multiple

    La struttura dovrebbe essere la seguente
    Relazioni.jpg
    Relazioni.jpg

    la query di recupero dati la seguente
    Query.jpg
    Query.jpg

    con il seguente risultato
    Risultato.jpg
    Risultato.jpg

  • Re: Aiuto su struttura db: tabella singola o multiple

    Grazie Stifone.
    Mi studio anche la tua struttura.
    Che programma hai usato per creare le immagini delle relazioni?
  • Re: Aiuto su struttura db: tabella singola o multiple

    Il database è stato creato con Access.
  • Re: Aiuto su struttura db: tabella singola o multiple

    Stifone ha scritto:


    La struttura dovrebbe essere la seguente
    Relazioni.jpg
    la query di recupero dati la seguente
    Query.jpg
    con il seguente risultato
    Risultato.jpg
    Esatto.
    Solo che non mi convince quella relazione 1 a 1 per le recensioni.
Devi accedere o registrarti per scrivere nel forum
14 risposte