Newsgroup: it.comp.java
Titolo: Hibernate e chiavi

Non vorrei sbagliare, ma credo di aver trovato un caso in cui non è
possibile usare un tool di mapping relazionale.
La questione è: Hybernate, ad esempio, in una relazione uno a molti,
vuole sempre la chiave dell'"uno"?
Perché io, non ce l'ho.
E non è un errore, il fatto è che i miei dati hanno validità temporale.
Per cui, una classica tabella
Persona(
  codiceFiscale varchar primary key,
  nome varchar,
  cognome varchar
)
supponendo che nome possa variare nel tempo, ho
Persona(
	codiceFiscale varchar,
	nome varchar,
	cognome varchar,
	vt_begin datetime,
	vt_end datetime
)
con vt_begin=validity begin e vt_end=validity_end, che definiscono il
periodo di validità della tupla, in particolare il periodo in cui era
vero che una persona aveva un certo nome
Quindi, codiceFiscale, individua una tupla solo all'interno di un
periodo, mentre possono esistere due tuple diverse con lo stesso
codiceFiscale, in due diversi periodi.
P. es se gino cambia nome in "paolo" il primo gennaio 2000 ho:
codfisc1, gino, pinoni, -inf, 2000-01-01
codfisc1, paolo, pinoni, 2000-01-01, +inf
(-inf sta per -infinito, cioè da sempre, +inf sta per "per sempre")
Quindi, mi pare che in questo caso non ho chiave primaria da dare ad
hybernate, e stavo valutando se usarlo, ma mi sa che non posso e basta.
-- 
Herbie


Herbie,
stai scherzando, vero...oppure è il caldo?
Quella tabella ce l'hai già, o te la sei inventata tu? In entrambi i 
casi è quella tabella che è sbagliata.
Provo un suggerimento di soluzione (usando il tuo stesso pseudocode SQL, 
e supponendo (per non so quale motivo) di non voler introdurre chiavi 
surrogate (sconsigliatissimo per me non farlo)):
Persona (
   codiceFiscale varchar primary key,
   cognome varchar
)
Nome (
   codiceFiscale varchar,
   nome varchar,
   vt_begin datetime,
   vt_end datetime,
   primary key (codiceFiscale, vt_begin),
   foreign key (codiceFiscale) references Persona(codiceFiscale)
)
Banalmente...se il nome di una persona può cambiare (e se ne vuole tener 
traccia), significa che c'è una relazione uno-a-molti fra Persona e Nome.
Ciao
   Lucio
-- 
Lucio Benfante
JUG Padova           
http://www.parancoe.org
 ...have a look at it!
www.jugpadova.it
 
http://www.jugevents.org

 traccia), significa che c'è una relazione uno-a-molti fra Persona e Nome.
Dunque, la tua soluzione è incompleta, ma effettivamente in certe condizioni
si può usare una chiave come proponi tu.
La condizione è che gli intervalli non si sovrappongano, e questo non si
può dirlo via SQL "standard".
Riguardo Hybernate, avevo finora visto solo esempi con chiavi singole,
mi sono accorto nel frattempo che chiavi composte sono ammesse.
Comunque, come dici tu, una chiave int surrogata rende più facile il
riferimento
Riguardo la "normalizzazione", l'aver scorporato cioè le due tabelle, il
problema è che se ho 5 attributi per Persona, come era nome, dovrei
avere in teoria 5 tabelle come Nome, e per ricostruire i dati di Persona
in un certo momento dovrei usare un bel po' di join. Essendo consapevoli
che i dati non sono normalizzati, a volte credo si possa anche usare una
sola tabella che includa tutti e 5 gli attributi. Chiaro che, appena ne
cambia uno, devi riscrivere una tupla con uno modificato e i 4 immutati,
e questa è una chiara ridondanza.
Riguardo la possibile sovrapposizione di valori, con la chiave
(codiceFiscale, vt_begin) questo può accadere, guarda qua
Nome:
codfisc1, pino, 1970-01-01, 1990-01-01
codfisc1, gino, 1975-01-01, 1991-01-01
dall'1/1/1975, ho due nomi per lo stesso codice fiscale.
Si risolve usando asserzioni, implementate eventualmente mediante
trigger.
-- 
Herbie