Newsgroup: it.comp.software.database
Titolo: Anagrafiche su tabelle diverse in base al tipo colonna

Ciao a tutti,
Ho il seguente dilemma:
In una tabella ho una colonna che in base al codice mi dice da che
tabella devo decodificare.
Ad esempio se c'è 1 è l'anagrafica delle persone fisiche, se 2
anagrafica delle aziende.
Secondo voi qual'è il metodo migliore ?
Fare due colonne una per il codice delle persone fisiche e una per le
aziende, oppure una sola colonna ?
Grazie
Max

 Max
-- 
Francesco Quaratino
MCP, MCDBA, MCT
http://www.xplayn.org
dotNetSide Member
http://www.dotnetside.org

Max ha scritto:

Secondo me quando si arriva al punto i cui un vincolo (foreign key verso l'anagrafica) è determinato da un valore in un
campo e non dal modello dei dati, significa che c'è qualcosa che non va nel modello.
Se usi una sola colonna non potrai definire una foreign key (non sapendo a priori verso quale tabella), quindi dovrai
gestire l'integrità da programma (!!)
Se usi due colonne dovrai inserire dei NULL che però non sono "dati sconosciuti" ma dati "non esistenti per costruzione"
(e qui si potrebbe aprire una discussione sull'utilizzo dei NULL... ma evitiamo).
Io ripenserei il modello dei dati in questo modo:
Alternativa 1: se le "persone", indipendentemente dal fatto che siano fisiche o giuridiche, sono identificabili con
attributi univoci comuni farei così:
Persona {id_persona, (attributi_comuni)}
PersonaGiuridica {id_persona, ragione_sociale, p_iva..} FK id_persona -> Persona(id_persona)
PersonaFisica {id_persona, nome, cognome,...} FK id_persona -> Persona(id_persona)
Tabella {...,id_persona,...} FK id_persona -> Persona(id_persona)
Alternativa 2: dividere anche la tabella in base a persona fisica o persona giuridica:
PersonaGiuridica {id_persona_giuridica, ragione_sociale, p_iva...}
PersonaFisica {id_persona_fisica, nome, cognome,...}
TabellaPG {...,id_persona_giuridica,...} FK id_persona_giuridica -> PersonaGiuridica(id_persona_giuridica)
TabellaPF {..., id_persona_fisica,...} FK id_persona_fisica -> PersonaFisica(id_persona_fisica)
Poi se proprio vuoi vedere i dati come nella tabella originale crei una vista:
CREATE VIEW Tabella AS
SELECT *, 1 AS cod_tipo_persona FROM TabellaPF
UNION
SELECT *, 2 AS cod_tipo_persona FROM TabellaPG;
Nota: dove ho scritto id_... intendo un insieme di attributi che identificano univocamente il record, non un id numerico
autoincrementante, se possibile.
Spero sia chiaro.
Ciao.


[CUT]
La scelta che proponi però dà per scontato che i dati anagrafici
stanno in una sola tabella, invece nel mio caso stanno su due
AnagraficaPersone e AnagraficaAziende
Max

Zac ha scritto:

Sei stato chiaro, l'alternativa 1 non mi sembra percorribile poichè
come hai scritto tu non ci sono campi comuni fra le due tabelle. Una
persona fisica ha un nome ed un cognome, mentre un azienda ha una
ragione sociale anche se per altri problemi mi potrà essere utile.
Forse la seconda alternativa mi sembra percorribile, ma come imposto
l'integrità ? Con triggers ?
Comunque forse mi sono espresso male, la situazione è questa:
AnagraficaPersone, AnagraficaAziende - TabellaRighe e una riga può
essere "fatta" da una persona o da un'azienda. Essendo due cose diverse
(nel primo caso ho un nome e un cognome 2 campi, mentre nel secondo una
ragione sociale 1 campo) non posso ricondurre tutto ad una tabella.
Max


Scusami, rileggendo il 2° esempio mi è chiaro.
Il problema è che la vista che creo mi va in grid e va gestito
l'editing, a questo punto devo sapere dove fare l'UPDATE, ma questo è
un problema di programmazione ;-P
Grazie
Massimo

 aziende, oppure una sola colonna ?
Il terzo, che non hai detto :-)
bye

 Tabella {...,id_persona,...} FK id_persona -> Persona(id_persona)
Dato che tale schema permette l'inserimento di una riga in Persona
ma non nelle altre due, esattamente, a quale entità corrisponde
tale riga, premesso che non si tratta né di una persona fisica né
di una persona giuridica?
Tendo a pensare che si tratti solo di un artificio derivato dalla
programmazione object oriented (superclasse), volta a minimizzare
la scrittura di codice (attributi "comuni" in questo caso). Non
credo che si applichi tanto bene al data modeling.
bye

) e mi
spiace di non averlo visto prima perché il problema affrontato è quasi identico a questo.
Se devo dire la verità mi ha lasciato un po' perplesso la conclusione: se non ho capito male tu chiami "business rules"
le regole che non possono essere definite con il modello relazionale (a meno di sporchi trucchi), quindi non tutte le
regole possono essere definite mediante questo modello. Questo non è un (grosso) limite del modello relazionale?
Faccio un esempio riprendendo il caso in discussione qui:
Ho un cliente che è una azienda con ragione sociale <rag_soc>...
ClienteAzienda {rag_soc PK}
Ho un cliente che è una persona fisica con nome <nome> e cognome <cognome>...
ClientePersona {nome PK, cognome PK}
L'azienda <rag_soc> ha fatto un ordine a cui ho assegnato il numero <num_ordine>...
OrdineAzienda {num_ordine PK, rag_soc FK ->ClienteAzienda(rag_soc)}
La persona <nome>, <cognome> ha fatto un ordine a cui ho assegnato il numero <num_ordine>...
OrdinePersona {num_ordine PK, nome, cognome} FK (nome, cognome) FK -> ClientePersona(nome, cognome)
In questo caso dici che non c'è modo di imporre nello schema la regola che <num_ordine> deve essere univoco per le
aziende e le persone? Eppure sembra una regola talmente ovvia e banale...(comunque anche a me in questo momento non
viene in mente nulla di "pulito")
Ciao.

 a me in questo momento non viene in mente nulla di "pulito")
Non c'è; per ogni design si ricasca in uno dei casi già analizzati.
Ho la netta sensazione che questa impossibilità non sia casuale.
Il che può significare qualcosa, ad esempio che stiamo cercando
di modellare qualcosa che non esiste.
Forse, semplicemente ci facciamo influenzare dal fatto che le
tabelle sono "tipi diversi di ordini", quando dovrebbero essere
cose distinte.
Proviamo a pensarla così: se abbiamo un gruppo di tabelle
COMPLETAMENTE differenti, (es. Clienti, Stati, Animali) e per
qualche motivo volessimo assegnare un numero "globale" progressivo
ad ogni riga di ciascuna, innanzitutto non suonerebbe strana questa
regola?
Inoltre, non per questo le tabelle diventerebbero "sottotipi" di
una unica tabella "Numerazione", benchè ciò potrebbe essere lo
strumento materiale per realizzare una numerazione unica.
Trasportando questo ragionamento con le ns. due tabelle OrdiniPersone
e OrdiniAziende, ci dovrebbe similmente apparire strano il fatto di
dare una numerazione unica a righe in tabelle differenti.
Se non ci sembra strano, è probabilmente perché:
- il linguaggio ci condiziona il pensiero, facendoci credere che
"in fondo sempre di ordini si tratta"
- la pratica quotidiana ci condiziona, ad esempio il fatto di mettere
i fogli in un faldone e di dargli un numero progressivo
(per cui ora un foglio = un ordine, la numerazione ha più senso)
Da questo dovrebbe apparire maggiormente evidente che il discorso
"numerazione unica per differenti tabelle" è una business rule,
una regola aziendale più che una proprietà intrinseca dei dati, e
come tale trova ambiente ideale in un algoritmo definito dall'utente;
il db si limiterà a catturare questa informazione senza chiedersi come
sia stata generata (specialmente considerando che tale regola potrebbe
essere soggetta a cambiamenti decisi dall'azienda, esempio azzerarsi
a fine anno, o avere una numerazione per-cliente, etc).