Un modello per la gestione trasparente della

M2 ORM2 : Un modello per la gestione
trasparente della persistenza relazionale di
oggetti
Luca Cabibbo e Roberto Porcelli
Dipartimento di Informatica e Automazione
Università degli studi Roma Tre
Sommario Lo sviluppo di applicazioni orientate agli oggetti richiede
comunemente di memorizzare degli oggetti in una base di dati. I sistemi
per la gestione trasparente della persistenza degli oggetti liberano il programmatore dalle problematiche della gestione della persistenza. Questo
lavoro presenta M2 ORM2 , un modello per descrivere corrispondenze basate sull’incontro a metà strada di schemi a oggetti e schemi relazionali, di
supporto alla gestione trasparente della persistenza di oggetti mediante
basi di dati relazionali.
1
Introduzione
Nello sviluppo di sistemi informatici si sono affermate numerose tecnologie, che
vanno utilizzate in modo combinato e, possibilmente, sinergico. Da una parte, i
sistemi di gestione di basi di dati relazionali consentono una gestione efficiente
ed efficace di dati persistenti, condivisi e transazionali [2]. Dall’altra, gli strumenti e i metodi orientati agli oggetti (linguaggi di programmazione, ma anche
metodologie di analisi e progettazione) consentono una sviluppo efficace della
logica applicativa delle applicazioni [15]. In pratica, è comune realizzare applicazioni a oggetti con una architettura a strati, con almeno uno strato per la logica
applicativa, uno di presentazione e uno per la persistenza. Le classi i cui oggetti
posseggono i dati che devono essere resi persistenti appartengono allo strato della
logica applicativa, e sono normalmente ispirate a classi concettuali della realtà
di interesse dell’applicazione. Queste classi, chiamate classi persistenti, vengono
rese persistenti scrivendo del codice che le collega in modo opportuno allo strato
che si occupa della persistenza dei dati.
La persistenza degli oggetti può essere realizzata in vari modi, ad esempio
usando una base di dati a oggetti o relazionale. Nel primo caso, ciascun oggetto
viene rappresentato direttamente da un oggetto della base di dati a oggetti. Nel
secondo caso, i dati di ciascun oggetto vanno rappresentati mediante una o più
tuple della base di dati relazione. A livello del codice, la persistenza relazionale
degli oggetti può essere poi realizzata in vari modi, ad esempio mediante il linguaggio SQL e le API di JDBC. Nel seguito ci occuperemo di oggetti persistenti
gestiti mediante basi di dati relazionali.
Recentemente sono stati realizzati dei framework per la gestione trasparente
della persistenza degli oggetti [17,20]. Con essi, il programmatore gestisce gli
oggetti persistenti usando delle API standard come quelle di ODMG [6], ovvero
nello stesso modo in cui userebbe gli oggetti di una base di dati a oggetti. In
realtà, questi framework possono rendere persistenti gli oggetti anche mediante
una base di dati relazionale oppure dei file. La persistenza è quindi trasparente
al programmatore, nel senso che non ne conosce i dettagli effettivi della gestione.
La corrispondenza tra gli oggetti e il supporto alla persistenza viene gestita da
uno strato software, implementato come un pre-compilatore, un post-compilatore
oppure un interprete.
La persistenza trasparente degli oggetti può essere ottenuta in vari modi.
Nell’R/O mapping (Relation to Object mapping, chiamato anche reverse engineering) vengono generate automaticamente le classi persistenti a partire da una
base di dati relazionale. In questo modo, il programmatore popola la base di dati
creando o modificando oggetti delle classi persistenti; queste sono realizzate in
modo tale da propagare tali creazioni e modifiche nella base di dati sottostante.
Nell’O/R mapping (Object to Relation mapping, chiamato anche forward engineering), a partire dalle classi che devono essere rese persistenti viene invece
generata automaticamente la base di dati, insieme a tutto il codice necessario a
propagare la persistenza degli oggetti nella base di dati.
Una gestione della persistenza completamente trasparente non è sempre utile
o possibile. Spesso infatti bisogna realizzare applicazioni che accedono a basi di
dati relazionali pre-esistenti e condivise tra più applicazioni; questo evidentemente limita l’uso dell’O/R mapping. Inoltre, il progettista della logica applicativa
vuole poter sfruttare tutte le potenzialità del modello a oggetti, senza essere
vincolato dallo schema della base di dati; questo limita invece l’uso dell’R/O
mapping. Fortunatamente, esiste una ulteriore modalità per ottenere la persistenza degli oggetti, che consente di gestire i casi in cui l’applicazione e la base
di dati siano state progettate ed evolvono in modo indipendente. Nell’approccio
meet in the middle le classi persistenti e la base di dati vengono progettate e
realizzate separatamente. Inoltre vengono descritte, solitamente in modo dichiarativo, le corrispondenze che esistono tra le classi persistenti e le relazioni della
base di dati. Queste corrispondenze descrivono un “incontro tra schemi a metà
strada” e vengono usate dal gestore della persistenza per rendere persistenti gli
oggetti mediante la base di dati. L’approccio meet in the middle è molto versatile,
perché cambiamenti nelle classi persistenti e/o nella base di dati possono essere
gestiti semplicemente ridefinendo le corrispondenze tra i due schemi. Purtroppo,
i sistemi esistenti supportano l’approccio meet in the middle solo in casi molto
limitati. Molti sistemi per la gestione della persistenza di oggetti sono infatti
basati principalmente sull’approccio O/R oppure su quello R/O, e consentono
di gestire essenzialmente solo corrispondenze tra strutture simili (ad esempio,
gli oggetti di una singola classe con le tuple di una singola relazione); questi
sistemi consentono un eventuale incontro tra schemi, ma solo come attività di
ottimizzazione locale successiva alla traduzione di uno schema da un modello
di dati all’altro. Le limitazioni dei sistemi esistenti sono legate alle difficoltà nel
ragionare su corrispondenze complesse per evitare anomalie e inconsistenze.
Questo lavoro presenta M2 ORM2 (un acronimo per Meet-in-the-Middle Object/Relational Mapping Model ), un modello per descrivere corrispondenze tra
schemi a oggetti e schemi relazionali al fine di supportare la gestione trasparente
della persistenza degli oggetti di tipo meet in the middle. Rispetto ai sistemi
attualmente esistenti, M2 ORM2 consente maggiori possibilità di incontro tra
schemi. Anziché considerare solo corrispondenze tra singole classi e singole relazioni, in M2 ORM2 è anche possibile esprimere corrispondenze tra cluster di
classi correlate (che intuitivamente descrivono un singolo concetto) e cluster di
relazioni correlate. È inoltre possibile esprimere corrispondenze che descrivono
relationship1 tra cluster. Rispetto ad altre proposte, M2 ORM2 fa riferimento a
dettagli specifici dei modelli dei dati considerati (a oggetti e relazionale), proprio
al fine di identificare maggiori possibilità di incontro tra schemi.
Il contributo principale di questo lavoro consiste nella presentazione del modello M2 ORM2 . Inoltre, viene avviata una discussione sulla correttezza delle
corrispondenze e vengono identificate alcune condizioni per la correttezza.
La Sezione 2 riporta la terminologia e le notazioni usate per descrivere gli
schemi a oggetti e gli schemi relazionali. La Sezione 3 introduce il modello
M2 ORM2 per descrivere la corrispondenza tra schemi, insieme a degli esempi.
La Sezione 4 discute il problema della correttezza delle corrispondenze. Infine,
la Sezione 5 discute l’efficacia del modello, confrontandolo con altre proposte.
2
Modello a oggetti e modello relazionale
Questa sezione ha lo scopo di illustrare i modelli di dati utilizzati (modello a
oggetti e modello relazionale) e le loro caratteristiche (costrutti e vincoli), nonché
la terminologia usata.
Il modello a oggetti di riferimento è un modello semantico (ovvero, ha caratteristiche strutturali ma non comportamentali) non nidificato e senza gerarchie
di generalizzazione/specializzazione. Si tratta di una versione semplificata del
modello di ODMG [6] e di quello di UML [4].
A livello intensionale, una classe descrive un insieme di oggetti che hanno le
stesse caratteristiche strutturali. Ciascuna classe è caratterizzata da un insieme
di attributi, ciascuno con un nome e un tipo.2 Una associazione descrive una
relazione binaria tra una coppia di classi (o meglio, tra gli oggetti di tali classi).
Uno schema a oggetti è un insieme di classi e associazioni tra tali classi. La
Figura 1 mostra un esempio di schema a oggetti.
A livello estensionale, una classe è un insieme di oggetti (ogni oggetto è una
istanza di una classe). Ciascun oggetto è dotato di un oid, un identificatore univoco che permette di referenziarlo. Lo stato di un oggetto è definito dall’insieme
1
2
Nel seguito, useremo il termine relationship per indicare le relazioni tra elementi, al
fine di evitare di usare in modo sovraccarico il termine “relazione”.
In questo lavoro viene fatta l’ipotesi semplificativa che gli attributi delle classi siano
tutti di uno stesso tipo semplice, ad esempio, delle stringhe.
1
Risiede
residenza
Comune {RO}
-nome {KEY}
-provincia
*
Progetto
-nome
-budget
*
Partecipa *
progetti
Impiegato
-matricola {KEY}
-cognome
-stipendio {null}
impiegati
Afferisce
*
dipartimento
1
Dipartimento
-nome
-divisione
Figura 1. Uno schema a oggetti
dei valori assunti in un certo momento dagli attributi dell’oggetto. Una associazione è un insieme di collegamenti ; ogni collegamento è una istanza di una
associazione e descrive una relazione tra una coppia di oggetti.
In questo lavoro vengono considerati anche alcuni vincoli di integrità. Gli
attributi di una classe possono assumere oppure non assumere valore nullo; un
attributo che non può assumere valore nullo è detto non nullo. Talvolta è utile
poter cercare in modo univoco gli oggetti di una classe sulla base del valore
assunto da alcuni dei loro attributi; in questo caso, gli attributi che identificano
gli oggetti sono chiamati attributi chiave e la classe viene detta con chiave;
altrimenti, la classe viene detta senza chiave. Gli attributi chiave devono essere
non nulli. Una classe di sola lettura è una classe da cui non è possibile istanziare
nuovi oggetti persistenti e non è possibile modificare o cancellare oggetti esistenti.
In una applicazione, le classi di sola lettura sono utili per accedere informazioni
generate da altre applicazioni ma che non possono essere modificate da questa
applicazione. Nella Figura 1, gli attributi chiave sono indicati dal vincolo {KEY},
e gli attributi che possono avere valore nullo sono indicati dal vincolo {null}. Il
vincolo {RO} indica le classi di sola lettura.
Per le associazioni possono sussistere vincoli di molteplicità e di navigabilità.
Un ruolo è una estremità di una associazione, relativo a una classe che partecipa
nell’associazione. I ruoli sono caratterizzati da nome, navigabilità e molteplicità.
La molteplicità di un ruolo di una associazione indica quanti oggetti (al minimo
e al massimo) di quella classe possono essere collegati a ogni oggetto della classe
sull’altro ruolo dell’associazione. La navigabilità di un ruolo di una associazione
indica se è possibile raggiungere gli oggetti di quella classe navigando i collegamenti dagli oggetti dell’altro ruolo dell’associazione. Ad esempio, nello schema
di Figura 1, ciascun Impiegato è associato all’(unico) Comune in cui vive; questa
associazione è navigabile dall’Impiegato verso il Comune, ma non viceversa.
Nel modello relazionale [2], a livello intensionale una relazione descrive un
insieme di tuple. Lo schema di una relazione è costituito da un insieme di attributi, ciascuno con un nome e un tipo.3 Uno schema relazionale è un insieme di
3
Anche in questo caso viene fatta l’ipotesi semplificativa che tutti gli attributi siano
di uno stesso tipo semplice, ad esempio, delle stringhe.
impiegato
partecipazione
imp {NK}{FK: impiegato}
prog {NK}{FK: progetto}
matricola {NK}
cognome
stipendio {null}
comune
provincia
dip {FK: dipartimento}
dipartimento
codice {AK}
nome
div {FK:divisione}
progetto
codice {AK}
denominazione
budget
dataInizio {null}
divisione
codice {AK}
nome
comune {null}
Figura 2. Uno schema relazionale
relazioni. A livello estensionale, una relazione è un insieme di tuple sugli attributi
della relazione.
Questo lavoro tiene in considerazione i seguenti vincoli di integrità. Ciascun
attributo può essere o non essere non nullo. Ciascuna relazione ha una chiave,
ovvero un insieme di uno o più attributi che permette di identificare le tuple
della relazione. Un attributo chiave un attributo che fa parte di una chiave;
gli attributi chiave devono essere non nulli. Talvolta le relazioni, anziché essere identificate mediante chiavi naturali (ovvero, chiavi basate su attributi che
hanno significato nella realtà), vengono identificate mediante chiavi artificiali
(o surrogati ). In una relazione con chiave artificiale, l’inserimento di una nuova
tupla nella relazione richiede anche la generazione di una nuova chiave artificiale,
il che viene normalmente gestito dal DBMS. Per integrità referenziale si intende
un insieme di uno o più attributi di una relazione che consente di referenziare le
tuple di un’altra relazione.
La Figura 2 mostra un esempio di schema relazionale. Gli attributi che formano una chiave naturale sono indicati dal vincolo {NK}, e quelli che formano
una chiave artificiale dal vincolo {AK}. Le integratità referenziali sono indicate da frecce e implementate da attributi con il vincolo {FK}. Il vincolo {null}
indica gli attributi che possono assumere valore nullo.
3
Un modello per la corrispondenza tra schemi
M2 ORM2 (Meet-in-the-Middle Object/Relational Mapping Model ) è un modello
per descrivere corrispondenze tra schemi a oggetti e schemi relazionali di supporto alla gestione trasparente della persistenza degli oggetti di tipo meet in the
middle. In questo lavoro viene fatta l’ipotesi che lo schema a oggetti e lo schema
relazionale siano stati progettati autonomamente. In particolare, lo schema relazionale potrebbe essere (parzialmente) denormalizzato per motivi di efficienza;
anche lo schema a oggetti potrebbe essere denormalizzato, fornendo oggetti “a
grana grossa”.
Oggetti e collegamenti dello schema a oggetti devono poter essere manipolati mediante le cosiddette operazioni CRUD (Create, Read, Update, Delete),
consentendo la creazione persistente di oggetti, la lettura di oggetti persistenti
(ovvero, la ricerca univoca di oggetti sulla base della chiave), la modifica persistente di oggetti, la cancellazione persistente di oggetti, nonché la navigazione,
la formazione, la rottura e la modifica di collegamenti persistenti tra oggetti. 4
Tutte queste operazioni devono essere automaticamente implementate mediante
manipolazioni della base di dati relazionale.
Una corrispondenza M2 ORM2 è descritta da un multi-grafo orientato, ovvero
da un insieme di nodi e da un insieme di archi, con l’osservazione che potrebbero
esserci più archi che collegano una stessa coppia di nodi. Ciascun nodo descrive
corrispondenze tra un insieme di classi e un insieme di relazioni. Ciascun arco
descrive una relationship tra le corrispondenze descritte da una coppia di nodi.
Intuitivamente, usando la terminologia del modello Entità-Relazione, ciascun
nodo rappresenta una entità (eventualmente non normalizzata in uno dei due
schemi) e ciascun arco una relazione (relationship) binaria tra entità.
Un cluster di classi (o c-cluster ) è formato da un insieme non vuoto di classi,
nonché da un insieme di associazioni tra tali classi.5 In un c-cluster, una delle
classi va designata come classe primaria del c-cluster; le altre classi sono secondarie. Le associazioni del nodo devono essere, direttamente o indirettamente,
tutte di tipo uno-a-uno oppure uno-a-molti dalla classe primaria alle classi secondarie. Intuitivamente, queste associazioni devono collegare ciascun oggetto
della classe primaria ad al più un oggetto di ciascuna delle classi secondarie.
Un cluster di relazioni (o r-cluster ) è formato da un insieme non vuoto di
relazioni, nonché da eventuali vincoli di integrità tra di esse. In un r-cluster,
una delle relazioni va designata come relazione primaria dell’r-cluster; le altre
relazioni, dette secondarie, devono essere referenziate, direttamente o indirettamente, dalla relazione primaria dell’r-cluster. Intuitivamente, a ciascun tupla
della relazione primaria deve essere associata al più una tupla in ciascuna delle
relazioni secondarie mediante le integrità referenziali considerate.
Ciascun nodo di una corrispondenza è formato da un c-cluster e da un rcluster, nonché da informazioni sulle corrispondenze tra i loro elementi (ovvero,
classi, relazioni, attributi e associazioni). M2 ORM2 prevede tre tipologie di nodi,
per fare corrispondere una classe con una relazione, una classe con più relazioni
oppure più classi con una relazione.6 Un nodo inoltre descrive la corrispondenza
tra elementi del c-cluster e dell’r-cluster mediante un insieme di corrisponden4
5
6
L’operazione di lettura è significativa solo per classi con chiave. Inoltre, per le classi di
sola lettura non sono significative le operazioni di creazione, modifica e cancellazione.
Più precisamente, ciascun elemento di un c-cluster è in corrispondenza con una
classe dello schema a oggetti. Pertanto, è possibile che una stessa classe partecipi
in più c-cluster, o addirittura che partecipi più volte nello stesso c-cluster. Stesse
considerazioni valgono per gli r-cluster, che saranno introdotti tra breve.
Attualmente il modello non prevede la possibilità di far corrispondere mediante un
nodo più classi con più relazioni. In pratica, alcune corrispondenze complesse di
quest’ultimo tipo possono essere rappresentate mediante gli archi.
partecipazione
imp {NK}{FK: impiegato}
prog {NK}{FK: progetto}
Partecipa
*
AIP
Impiegato
*
-matricola {KEY}
-cognome
-stipendio {null}
*
progetti
-nome
-budget
Risiede *
codice {AK}
denominazione
budget
dataInizio {null}
NP
impiegato
impiegati
progetto
Progetto
residenza
1
Comune {RO}
Afferisce
-nome {KEY}
-provincia
NI
AID
1
dipartimento
Dipartimento
matricola {NK}
cognome
stipendio {null}
comune
provincia
dip {FK: dipartimento}
dipartimento
codice {AK}
nome
div {FK:divisione}
-nome
-divisione
divisione
codice {AK}
nome
comune {null}
ND
Figura 3. Corrispondenza tra gli schemi delle Figure 1 e 2
ze tra attributi. Una corrispondenza tra attributi è una coppia formata da un
attributo di una classe e un attributo di una relazione.
La Figura 3 mostra una corrispondenza tra gli schemi di Figura 1 e 2, basata
su tre nodi: un nodo NP che descrive la corrispondenza tra la classe Progetto
e la relazione progetto, un nodo NI che descrive la corrispondenza tra le classi
Impiegato e Comune e la relazione impiegato e un nodo ND che descrive la
corrispondenza tra la classe Dipartimento e le relazioni dipartimento e divisione.
Il nodo NP descrive la corrispondenza tra una classe (Progetto) e una relazione (progetto); evidentemente, sia la classe che la relazione sono primarie nel
nodo. La loro corrispondenza è basata sulle corrispondenze tra attributi (Progetto.nome, progetto.denominazione) e (Progetto.budget, progetto.budget). Il nodo
NP descrive una corrispondenza totale tra una classe e una relazione: ciascun
oggetto della classe viene rappresentato da una tupla della relazione. La corrispondenza è tra una classe senza chiave e una relazione con chiave artificiale.
Tutti gli attributi della classe sono coinvolti dalla corrispondenza. Viceversa, non
tutti gli attributi della relazione sono coinvolti dalla corrispondenza. Questa cor-
rispondenza permette di gestire, ad esempio, la creazione di un nuovo Progetto
mediante l’inserimento di una nuova tupla in progetto; questa tupla prende il
valore di progetto.denominazione e progetto.budget dagli attributi dell’oggetto,
sulla base della corrispondenza; inoltre, il valore di progetto.codice viene generato
automaticamente e il valore di progetto.dataInizio rimane nullo.
Il nodo NI descrive invece la corrispondenza tra due classi (Impiegato e Comune) legate da una associazione (Risiede) e una relazione (impiegato). In questo
nodo la classe primaria è Impiegato. In pratica, a ciascun oggetto della classe primaria Impiegato può essere associato (mediante l’associazione Risiede) anche un
oggetto della classe secondaria Comune (il Comune in cui Risiede l’Impiegato).
Ciascuna tupla di impiegato viene usata per rappresentare un oggetto Impiegato
insieme all’oggetto Comune ad esso associato, nonché al collegamento di tipo
Risiede tra questi due oggetti. In questo nodo, in cui la classe primaria è con
chiave, la corrispondenza è basata sulle corrispondenze tra gli attributi chiave della classe primaria e della relazione primaria (Impiegato.matricola, impiegato.matricola), nonché sulle corrispondenze tra attributi (Impiegato.cognome,
impiegato.cognome), (Impiegato.stipendio, impiegato.stipendio), (Comune.nome,
impiegato.comune) e (Comune.provincia, impiegato.provincia).
Infine, il nodo ND descrive la corrispondenza tra una classe (Dipartimento)
e due relazioni (dipartimento e divisione); la relazione primaria è dipartimento. In pratica, ciascun oggetto Dipartimento viene rappresentato da una tupla
di dipartimento e da una tupla di divisione, legate da una integrità referenziale. La corrispondenza è basata sulle corrispondenze tra attributi (Dipartimento.nome, dipartimento.nome) e (Dipartimento.divisione, divisione.nome). Quest’ultima corrispondenza ha senso solo con riferimento all’integrità referenziale
tra la relazione primaria dipartimento e la relazione secondaria divisione dell’rcluster. Infatti, questo nodo permette di rappresentare nella corrispondenza sia
le due relazioni che il vincolo di integrità referenziale che sussiste tra di esse.
In generale, non tutte le corrispondenze sono corrette. Ad esempio, se la classe
primaria di un nodo è con chiave, allora è necessario che i suoi attributi chiave
siano posti in corrispondenza con gli attributi chiave della relazione primaria del
nodo. Viceversa, se la classe primaria è senza chiave, allora la relazione primaria
del nodo deve essere con chiave artificiale. Il problema della correttezza delle
corrispondenze sarà discusso nella Sezione 4.
Una corrispondenza M2 ORM2 può contenere anche degli archi; intuitivamente, questi permettono di rappresentare corrispondenze ed elementi che non trovano spazio nei nodi, e in particolare ulteriori associazioni e integrità referenziali,
a talvolta anche delle relazioni. Ciascun arco di una corrispondenza descrive una
relationship tra una coppia di nodi, e può essere di tipo uno-a-uno, uno-a-molti
e molti-a-molti.
Un arco è basato su una corrispondenza tra classi e una tra relazioni. Una
corrispondenza tra classi descrive la corrispondenza tra le classi primarie dei
c-cluster dei nodi collegati dall’arco, ed è basata sui ruoli navigabili di una associazione tra le due classi. In pratica, i ruoli vengono implementati da attributi
riferimento (per la navigazione a-uno) e/o da attributi collezioni a riferimenti
(per la navigazione a-molti). Dato che una associazione può essere unidirezionale
o bidirezionale, viene coinvolto un solo attributo nel primo caso e una coppia
di attributi nel secondo caso. Una corrispondenza tra relazioni descrive la corrispondenza tra le relazioni primarie degli r-cluster dei nodi collegati dall’arco,
ed è basata sull’insieme degli attributi che implementano la relationship tra le
due relazioni mediante integrità referenziali, che coinvolgono eventualmente anche altre relazioni. Un arco raggruppa una corrispondenza tra classi e una tra
relazioni, stabilendo una relationship uno-a-uno, uno-a-molti o molti-a-molti tra
le istanze descritte da una coppia di nodi.
Ad esempio, la corrispondenza di Figura 3 tra gli schemi delle Figure 1 e 2
contiene due archi: AID per l’associazione uno-a-molti tra Impiegato e Dipartimento e AIP per l’associazione molti-a-molti tra Impiegato e Progetto.
L’arco AID tra NI e ND descrive la relationship uno-a-molti tra impiegati e
dipartimenti. Questa relationship è rappresentata dalla corrispondenza [Impiegato.dipartimento, Dipartimento.impiegati] tra le classi Impiegato e Dipartimento
e dalla corrispondenza [impiegato.dip] tra le relazioni impiegato e dipartimento.
In pratica, questo arco fa corrispondere l’associazione Afferisce tra Impiegato e
Dipartimento con l’integrità referenziale tra impiegato e dipartimento.
L’arco AIP tra NI e NP descrive la relationship molti-a-molti tra impiegati e
progetti. Esso è basato sulla corrispondenza (unidirezionale) [Impiegato.progetti]
tra le classi Impiegato e Progetto e sulla corrispondenza [partecipazione.imp,
partecipazione.prog] tra le relazioni impiegato e progetto. In pratica, questo arco
fa corrispondere l’associazione Partecipa tra Impiegato e Progetto con le integrità referenziali tra impiegato e progetto memorizzate nelle tuple della relazione
partecipazione.
4
Correttezza delle corrispondenze
Nella sezione precedente M2 ORM2 è stato utilizzato come strumento sintattico
per rappresentare corrispondenze. Le corrispondenze hanno anche una semantica, che descrive come sia possibile realizzare le operazioni su oggetti e collegamenti dello schema a oggetti mediante operazioni sulle relazioni dello schema
relazionale. Tuttavia, non tutte le corrispondenze che possono essere descritte da
M2 ORM2 sono corrette. Intuitivamente, una corrispondenza è corretta se consente effettivamente di realizzare le operazioni CRUD su oggetti e collegamenti.
Viceversa, è possibile dire che una corrispondenza è non corretta se le operazioni su oggetti e collegamenti possono causare anomalie. Nel resto di questa
sezione vengono identificate le possibili anomalie provocate da corrispondenze
non corrette, nonché alcune categorie di condizioni adeguate allo studio della
correttezza delle corrispondenze M2 ORM2 .
Si consideri una sequenza di operazioni CRUD su oggetti e collegamenti che
complessivamente trasforma una istanza valida dello schema a oggetti in un’altra
istanza valida, ovvero in cui tutti i vincoli di integrità imposti dallo schema sono
rispettati. Una corrispondenza non corretta può causare le seguenti anomalie
nell’esecuzione di una tale sequenza di operazioni:
– le anomalie di creazione si verificano se lo schema relazionale non è in grado
di gestire la creazione di oggetti da una qualche classe (non di sola lettura); le anomalie di creazione si verificano ad esempio se la classe non viene
rappresentata nella corrispondenza, se non tutti i suoi attributi sono messi
in corrispondenza con attributi dello schema relazionale, se non tutti i suoi
attributi chiave sono messi in corrispondenza opportuna con attributi chiave
dello schema relazionale;
– le anomalie di lettura sono relative all’impossibilità di identificare univocamente oggetti da classi con chiave mediante la chiave; queste anomalie sono
legate, ad esempio, ad errate corrispondenze tra attributi chiave delle classi
e attributi chiave di relazioni;
– le anomalie di aggiornamento impediscono di gestire la modifica di attributi
di oggetti (non di sola lettura);
– le anomalie di cancellazione impediscono di gestire la cancellazione di oggetti
(non di sola lettura).
In modo simile, è possibile identificare anomalie relative alla formazione di
collegamenti, nonché alla loro navigazione, modifica e rottura.
Le anomalie possono essere causate da corrispondenze tra elementi non corrette oppure da rappresentazioni non corrette di vincoli di integrità. Un caso del
primo tipo si verifica ad esempio se le corrispondenze tra elementi sono incomplete, ovvero se non tutti gli elementi dello schema a oggetti (classi, associazioni
e attributi) sono stati messi in corrispondenza con elementi dello schema relazionale. In effetti, ciascuna classe deve occorrere in almeno un nodo, e similmente
gli attributi delle classi devono normalmente occorrere in almeno una corrispondenza tra attributi. Inconsistenze nella rappresentazione di vincoli di integrità
possono avvenire in molti modi. Ad esempio, relativamente ai vincoli di chiave,
è necessario che gli attributi chiave delle classi primarie con chiave siano posti in
corrispondenza con attributi chiave delle corrispondenti relazioni primarie; viceversa, classi primarie senza chiave vanno poste in corrispondenza con relazioni
con chiave artificiale. Come ulteriore esempio, relativo a vincoli di integrità referenziale, in un nodo che fa corrispondere una classe a più relazioni, gli attributi
non chiave della classe devono essere posti in corrispondenza con attributi non
chiave delle relazioni, e le integrità referenziali verso relazioni secondarie devono
essere realizzate mediante chiavi artificiali.
Quelle descritte sono condizioni necessarie per la correttezza delle corrispondenze M2 ORM2 . D’altra parte, una implementazione deve fissare condizioni sufficienti per gestire effettivamente le corrispondenze considerate corrette. In pratica, nei sistemi esistenti le condizioni utilizzate sono molto restrittive. Uno degli
obiettivi di questa ricerca è identificare condizioni quanto più possibili permissive
rispetto alle quali le corrispondenze siano semanticamente significative.
5
Discussione
La letteratura “professionale” delle basi di dati e quella dei pattern languages è
ricca di contributi su come gestire classi persistenti mediante basi di dati relazio-
nali [1,5,9,14]. La maggior parte dei lavori descrive l’O/R mapping, una sorta di
progettazione logica [2] effettuata a partire da uno schema a oggetti anziché da
uno schema entità-relazione. Ma come è stato già detto nell’Introduzione, l’O/R
mapping sostiene la definizione di una base di dati di supporto a una singola
applicazione, e non condivisa tra molte applicazioni, essendo quest’ultima una
delle motivazioni principali per gestire dati persistenti mediante un DBMS.
Anche la letteratura scientifica delle basi di dati si è occupata di questo argomento. Persistence [13] è un sistema per l’O/R mapping. Gateway [18] è un
sistema per la gestione di oggetti persistenti mediante base di dati relazionali
basato sull’approccio meet in the middle; tuttavia, il lavoro non fornisce dettagli
sul modello di corrispondenza impiegato. EBO [19] è un sistema per l’R/O mapping, che fornisce alcune funzionalità per le corrispondenze meet in the middle;
anche in questo caso manca una descrizione del modello delle corrispondenze.
Il problema della descrizione e dell’analisi delle corrispondenze tra schemi è
di interesse anche nei lavori sulla trasformazione dei dati [7] e sull’integrazione di
dati [8]. La nozione di corrispondenza usata in questo lavoro è ispirata a quella
proposta in [3] nel contesto del model management.
La Tabella 1 confronta M2 ORM2 con alcuni standard e sistemi commerciali oppure open source per la gestione trasparente della persistenza di oggetti.
JDO [10] è uno standard per la gestione persistente di oggetti Java. OJB [17]
è un progetto open-source Apache, che offre una implementazione delle API di
ODMG che permettono di interagire con gli oggetti persistenti come se fossero
memorizzati in una base di dati a oggetti ODMG [6]; il progetto prevede anche
una futura implementazione delle API di JDO. JDX [11] offre caratteristiche
di O/R mapping simili a quelli di OJB; gli oggetti persistenti vanno acceduti
mediante delle API proprietarie. JRELAY [12] è una implementazione di JDO,
che consente tutti e tre gli approcci di mapping, ma con varie limitazioni.
In futuro, è prevista da una parte l’implementazione di un framework per la
gestione della persistenza di oggetti basato su M2 ORM2 . Da un punto di vista
teorico, è inoltre previsto lo studio di estensioni del modello (ad esempio, per
gestire l’ereditarietà, classi e attributi transienti, ulteriori vincoli di integrità,
ma anche eterogeneità schematiche [16]) nonché di caratterizzazioni più precise
della correttezza di corrispondenze M2 ORM2 .
Riferimenti bibliografici
1. S.W. Ambler. The fundamentals of mapping objects to relational databases. White
Paper, http://www.agiledata.org, 2003.
2. P. Atzeni, S. Ceri, S. Paraboschi e R. Torlone. Basi di dati. Modelli e linguaggi di
interrogazione. McGraw-Hill, 2002.
3. P.A. Bernstein, A.Y. Halevy, and R.A. Pottinger. A vision for the management of
complex models. ACM Sigmod Record, 29(4):55–63, 2000.
4. G. Booch, J. Rumbaugh, and I. Jacobson. The Unified Modeling Language User
Guide. Addison-Wesley, 1999.
Tabella 1. Confronto con altri modelli e strumenti
Caratteristica
O/R mapping (forward engineering)
R/O mapping (reverse engineering)
Meet in the middle
Una classe una relazione
Una classe più relazioni con integr. referenz.
Una classe più relazioni con partiz. verticale
Più classi una relazione
Più classi più relazioni
Classi con chiave
Classi senza chiave
Classi di sola lettura
Attributo di classe mappato in più relazioni
Relationship uno-a-uno
Relationship uno-a-molti
Relationship molti-a-molti senza attributi
Relationship molti-a-molti con attributi
Relationship molti-a-molti con attrib. selettivo
a
b
JDO
si
n/a
n/a
n/a
n/a
n/a
n/a
n/a
si
si
no
n/a
n/a
n/a
n/a
n/a
n/a
OJB JRELAY JDX M2 ORM2
si
si
si
no
si
si
si
no
si
si
si
si
si
si
si
si
sia
si
no
si
no
no
no
si
no
no
si
si
no
no
no
no
si
si
si
si
no
si
no
si
no
no
no
si
no
no
no
si
si
si
si
si
si
si
si
si
si
si
no
si
no
no
no
sib
no
no
no
sib
Si, ma non implementato.
Si, ma non discusso qui.
5. K. Brown and B.G. Whitenack. Crossing Chasms: A pattern language for objectRDBMS integration. In Pattern Languages of Program Design 2, 1996.
6. R.G.G. Cattell et al. The Object Data Standard: ODMG 3.0. MK, 2000.
7. Data Transformations. S.ı. of the IEEE Bull. on Data Engineering, 22(1), 1999.
8. Integration management. S.ı. of the IEEE Bull. on Data Engineering, 25(3), 2002.
9. M.L. Fussell.
Foundations of object relational mapping.
White Paper,
http://www.chimu.com, 1997.
10. Java Data Objects. http://www.jdocentral.com.
11. JDX. http://www.softwaretree.com/.
12. JRELAY. http://www.objectindustries.com/.
13. A.M. Keller, R. Jensen, and S. Agrawal. Persistence Software: Bridging objectoriented programming and relational databases. In ACM SIGMOD International
Conf. on Management of Data, pages 523–528, 1993.
14. W. Keller. Mapping object to tables: A pattern language. In European Conf. on
Pattern Languages of Programming, 1997.
15. C. Larman. Applying UML and Patterns. An introduction to object-oriented
analysis and design and the Unified Process. Prentice Hall PTR, 2002.
16. R.J. Miller. Using schematically heterogeneous structures. In ACM SIGMOD
International Conf. on Management of Data, pages 189–200, 1998.
17. ObJect relational Bridge. http://db.apache.org/ojb/.
18. J.A. Orenstein and D.N. Kamber. Accessing a relational database through an
object-oriented database interface. In 21st Int. Conf. on VLDB, 702–705, 1995.
19. J.A. Orenstein. Supporting retrievals and updates in an object/relational mapping
system. IEEE Bull. on Data Engineering, 20(1):50–54, 1999.
20. Torque. http://db.apache.org/torque/.