consigli trasformare una generalizzazione / specializzazione mysql

Allora ragazzi in breve sto realizzando un database per una compagnia telefonica (il progetto è un caso di studio )

I clienti potranno sottoscrivere uno o piu contratti

Il cliente può essere un privato o un azienda e per questo ho deciso sostanzialmente di fare due tabelle PRIVATO e AZIENDA (anzichè fare un unica tabella)e fin qui ok.

Il cliente può sottoscrivere uno o più contratti. I contratti possono essere di tipo "ricaricabile" o con "abbonamento".

Nel caso il contratto è "ricaricabile" bisogna conoscere il saldo sulla scheda e sapere se il cliente vuole avere la fattura.

Nel caso il contratto è con "abbonamento" bisogna conoscere i dati bancari della banca.

E già qui non so quale sia la strada migliore da eseguire. Ho varie soluzioni in mente ve le elenco

1) creare 4 tabelle :

                         contratto_privato_ricaricabile

                         contratto_privato_abbonamento

                         contratto_azienda_ricaricabile

                         contratto_azienda_abbonamento

Questa soluzione mi eviterebbe di avere campi Null inutilizzati però quando devo eseguire query del tipo "a quale contratto fa parte questo numero di telefonO" mi renderebbe più complesse le query sia a livello di estrazione dati sia a livello d'ispezione.... giusto ?

2) creare un unica tabella contratto :

     il problema però e che quando inserisco un record avrò sempre 2 campi vuoti perchè nel caso ad esempio sto inserendo un contratto con ricaricabile il campo "iban" e "intestatario_conto" non verebbero utilizzati e nel caso invece sto inserendo un contratto con abbonamento il campo "richiesta_fattura" e "saldo" non verebbero utilizzati.

Un altro problema e che ovviamente devo capire se il contratto si riferisce ad un azienda o a un cliente quindi pensavo di mettere all'interno due chiavi esterne "idprivato" e "idazienda" e nel caso il contratto è intestato a azienda riempio solo il campo "idazienda" mettendo l'id di riferimento dell'azienda, in caso invece il contratto è di un privato riempio solo il campo "idprivato" mettendo l'id di riferimento del cliente privato.

Però questa soluzione non mi convince molto...non so....

3) creare due tabelle : contratto_cliente  |  contratto_azienda

in questo caso le due tabelle hanno gli stessi campi tranne la chiave esterna dove a uno sarà idprivato e all'altro sarà idazienda. Anche qui c'è il problema che 2 campi rimarrano sempre vuoti.

Secondo voi quale soluzione mi conviene adoperare ? ovviamente se avete altre soluzioni migliori fatevi pure avanti :)

Ringrazio in anticipo tutti coloro che vorrano aiutarmi :*

inviato 7 anni fa
Toto007
modificato 7 anni fa
X 0 X

In allegato trovi il diagramma delle classi contenente 2 classi astratte "Cliente" e "Contratto" e 4 classi concrete che modellano le due tipologie di cliente (Privato e Azienda) e le due tipologie di contratto (Abbonamento e Ricaricabile).

Tra Cliente e Contratto c'è una associazione.

Il passaggio al modello relazionale è semplice in questo caso: ogni classe, anche astratta, diventa una tabella.

La tabella Cliente contiene tutti gli attributi comuni a Privato e Azienda. Stessa cosa per Contratto.

Nelle tabelle Privato, Azienda, Abbonamento e Ricaricabile invece metti solo le colonne che non possono essere spostate nelle tabelle Cliente e Contratto, ovvero quelle che appartengono ad una particolare categoria di Cliente e Contratto e non a tutti  i clienti e contratti.

In Cliente e Contratto aggiungi inoltre una chiave primaria di tipo IDCliente e IDContratto

Nelle tabelle Privato e Azienda metti una FK a IDCliente metre nelle tabelle Abbonamento e Ricaricabile metti una FK a IDContratto.

Anche nella tabella Contratto va messa una FK a IDCliente. In totale avrai 5 FK che corrispondono alle 5 relazioni del diagrmma delle classi.

 :bye:

risposto 7 anni fa
Gianni Tomasicchio
modificato 7 anni fa
X 0 X

Gianni, il mio cuore brilla solo per te   :smitten:

Piu chiaro di così non potevi essere...  :)

Se me lo consenti, volevo chiederti se hai da consigliarmi qualche libro che spieghi come sviluppare database calcolano vari aspetti (n. di join, spazio sprecato, etc.) e che possibilmente alleghi anche dei buoni casi di studio abbastanza complessi. Cercavo un libro che comunque non sia a livello "didattico" ma a livello "lavorativo" perchè mi piacerebbe approfondire di piu questi argomenti.

ps. possibilmente in italiano :P

un abbraccio

Giuseppe

risposto 7 anni fa
Toto007
X 0 X

Ciao caro, mi lusinghi sempre...

Un testo che ti posso consigliare è questo:

http://www.ateneonline.it/atzeni/homeA.asp

La parte sulla progettazione è fatta bene.

Comunque io ho imparato molte cose sul campo, ovvero a lavoro, vedendo i modelli realizzati dai colleghi analisti. Come al solito l'esperienza (propria ma sorpattutto quella degli altri) ha la sua importanza...

Ti abbraccio e ti faccio i miei auguri di buona Pasqua.

Bye  :bye:

risposto 7 anni fa
Gianni Tomasicchio
X 0 X

grazie per il consiglio... il libro è stato prontamente ehm..."comprato"... XD

Un dubbio mi sorge nella tua soluzione...o meglio nella tua metologia in generale...

 quando io vorro sapere le informazioni di un cliente dovro prima eseguire una query su "cliente" e poi analizzando il campo "tipologia" capisco se è un privato o un azienda e di conseguenza faccio una seconda query per recuperare le ulteriori informazioni.

Ora mi chiedo , il fatto di fare 2 query (immagina quando ad esempio vorro recuperare le informazioni di una fattura...dovro prima capire a quale contratto si riferisce  e poi capire quale cliente...quindi le join saranno molte di piu) non mi porta a una soluzione meno "performante" di fare invece un unica tabella contenente però piu campi vuoti?

Cioè se alla fine se devo decidere se rendere le query piu veloci o ottimizzare lo spazio, non è meglio puntare piu sulla velocità che sullo spazio (ormai con gli hard disk da 1 tera giga che costano una fesseria problemi di spazio non c'è ne sono piu) ?

A te la palla signor Gianni  ;D

risposto 7 anni fa
Toto007
modificato 7 anni fa
X 0 X

L'approccio che ti ho suggerito, come tutte le cose, ha vantaggi e svantaggi.

Vantaggi

 - Riduce il numero di campi a NULL

 - permette di definire in maniera più rigorosa i constraint di NOT NULL validi solo per un particolare cliente o contratto

 - evita che si possano inserire clienti o contratti con dati "ibridi" (ovvero appartenenti un po' ad una tipologia, un po' all'altra)

 - permette di effettuare operazioni comuni a tutti i clienti (o a tutti i contratti) lavorando su una sola tabella.

Svantaggi

 - richiede un numero maggiore di JOIN e query per interagire con le tabelle

Come puoi vedere quindi, a parte il numero dei campi NULL, il vero vantaggio che si ottiene sta nella "pulizia" della base di dati che risulterà meno soggetta alla presenza di dati sporchi. E questo, ti assicuro, è il valore più importante di una base di dati. Non fa nulla se bisogna fare qualche query in più per recuperare i dati, l'importante è che questi siano "buoni". Le performance e lo spazio sono problemi secondari, risolvibili con qualche intervento sistemistico o di un amministratore di database (DBA). Al massimo si ricorre alla denormalizzaione.

Se ad esempio si scopre che si effettuano delle query o delle JOIN solo per recuperare un campo non presente nelle tabelle "figlie" allora si copia il campo in questione dalla tabella padre alle tabelle figlie.

 :bye:

risposto 7 anni fa
Gianni Tomasicchio
X 0 X

quindi per dati "sporchi" intendi una giusta "catalogazione" dei dati, cioè che quando recupero delle informazioni questi contengono le informazioni che effettivamente voglio senza dover spulciare i singoli record e capire quali sono i dati che effettivamente mi interessano... giusto?

vorreo chiederti  altri due  consigli se   sua maestà me lo consente  :-[....

1)

per esempio, adesso devo creare l'entità "fattura" e  premesso che la fattura è associato al contratto che a sua volta è associato al cliente...  e un contratto può generare piu fatture...

nel creare la chiave primaria a "fattura" avrei due soluzioni o creare unica chiave primaria minimale "idfattura" oppure creare una superchiave fatta da "idfattura" e "idcontratto".

Il risultato è lo stesso....ma mi chiedo...c'è una strada precisa da seguire in merito? Sarei ovviamente piu intenzionato a creare un unica chiave primaria  ma facendo un ragionamento logico mi verrebbe da dire che la fattura non esiste senza contratto e quindi sarei intenzionato a mettere tutte  e due le chiavi (giusto per dare una corrispondenza logica con il mondo reale)

2)

quando scompongo la tabella CLIENTE in tre tabelle : "Cliente" - "Privato" - "Azienda" dove in Cliente metto i dati comuni tra privato e azienda. Come unica chiave primaria di Privato e Azienda posso mettere la chiave esterna di idcliente della tabelle CLIENTE ? la risposta è scontanta..però vorrei avere una conferma per esserne sicuro :)

uff se fossi  nata  donna ti avrei sposato all'istante...ma perchè sono nato maschio...maledizione   ;D

risposto 7 anni fa
Toto007
X 0 X

Ti faccio un esempio di dati sporchi. Supponi di creare un'unica tabella per privati e aziende. Sicuramente dovrai avere una colonna per la partita IVA. Questa colonna sarà obbligatoria per le aziende ma vietata per i privati.

Come fai ad essere certo che le righe di questa tabella che si riferiscono ad aziende contengono sicuramente la parita IVA? Come fai ad esser certo che le righe relative ai privati non contengono la partita IVA? Semplice, non puoi. Infatti se l'applicazione che stai realizzando impazzisce (e stai certo che prima o poi accadrà) ti ritroverai con dei privati con la partita IVA e con delle aziende senza. Questi sono dati sporchi e non c'è modo di ripulirli.

Se invece usi due tabelle, in quella dei privati non ci sarà la colonna della partita IVA metre in quella delle aziende questa colonna sarà NOT NULL. Se l'applicativo impazzisce al massimo non inserisce i dati.

1) per il discorso sulla fattura, io preferisco usare una chiave semplice idfattura. Ovviamente la fattura dovrà contenere una FK al contratto ma questa FK non costituisce PK per la tabella delle fatture.

2) Si, DEVI fare così

 :bye:

P.S.: meno male che sei nato maschio....

risposto 7 anni fa
Gianni Tomasicchio
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda