2. Bases de dades Objecte-Relacionals
1. Base de dades Objecte-Relacional
En aquesta secció treballarem amb la base de dades PostgreSQL. Com el sistema de gestió de bases de dades objecte-relacional de codi obert, que ha tingut el major impacte, sent un rival directe del gran Oracle.
Ens centrarem en les novetats que ofereix Postgres enfront de MySQL, com una extensió dels conceptes del primer any.
Important
Serà interessant:
- Instal·lar el teu propi servidor PostgreSQL. Es recomana utilitzar-lo mitjançant un contenidor Docker.
- Instal·lar un client per mostrar la teva base de dades. Recomanem DBeaver.
Treballarem amb aquest conegut exemple:
2. Definició de tipus
En PostgreSQL existeixen els tipus habituals que es troben en els SGBD moderns. A més, destaquen tipus especials per emmagatzemar adreces d'Internet (Tipus d'Adreça de Xarxa), XML i JSON per guardar i processar aquests formats, tipus propis i col·leccions. Amb això, podem observar els grans avanços de PostgreSQL, que d'una manera relaxada podríem considerar com Objecte-Relacional i Documental.
2.1. Enumeració
Els tipus enumerats són tipus que només permeten valors específics, generalment també coneguts com a dominis. En PostgreSQL els podem crear de la següent manera:
per exemple:
| SQL | |
|---|---|
Aquesta manera de definir aquest tipus evitarà les comprovacions de valors (clàusules CHECK) existents en alguns SGBD relacionals.
2.2. Tipus estructurats
Els tipus estructurats són els precursors dels objectes en si. Si recordem, en la programació estructurada, a partir dels tipus bàsics, podíem crear estructures de dades:
- On tots els elements són iguals (vectors, arrays i col·leccions)
- On els seus elements podrien ser de diferents tipus. Aquestes estructures van evolucionar cap als objectes actuals afegint comportament i altres característiques.
En el model relacional, com que hem de respectar l'atomicitat de les dades, no podíem generar aquestes estructures. En Postgres podem crear aquests nous tipus de dades estructurats amb la següent sintaxi, molt semblant a la creació d'una taula:
per exemple:
o, fent servir un una enumeració, de les vistes abans:
i finalment creariem la següent taula:
Recordatori
- No es poden aplicar restriccions NOT NULL, DEFAULT o CHECK als camps que pertanyen als tipus creats.
- La tipificació té sentit en dades que no existeixen per si mateixes, que necessiten ser incrustades en altres estructures o taules.
- Quan s'utilitza dins d'una taula i es manipula la inserció, es farà en un bloc, entre parèntesis, ja que determina una estructura.
- Per seleccionar un subtipus, hem d'envoltar el tipus general entre parèntesis, en cas contrari Postgres el confon amb una taula i genera un error.
3. Classes (o realment taules?)
Anem a crear una classe Figura, que serà el punt de partida d'una herència del model presentat a l'inici de la unitat. Vegem què incorpora respecte a les implementacions del model relacional. Figura conté una clau primària, i contindrà un Punto per localitzar-la en el pla. A més, conté una col·lecció de colors, per fer possibles degradats, guardats com un array. Guardar col·leccions és també una capacitat afegida que no suporta el model relacional, donada l'absència de valors multivaluats.
Es crea una classe amb la mateixa sintaxi que una taula, ja que, a efectes pràctics, des d'un punt de vista estructural és el mateix. Posteriorment, l'herència distingeix que una taula "hereta" d'una altra.
| SQL | |
|---|---|
Per inserir nous registres, tingues en compte que:
- Els elements de tipus
Puntos'han d'emmagatzemar utilitzant un constructor que crea unafilaabstracta, anomenadaROWo entre parèntesis. - Per als arrays, també necessitem un constructor anomenat
ARRAY, amb una llista d'elements.
A partir d'aquí, crearem noves classes per representar els cercles, quadrats i rectangles de Figura utilitzant l'herència. La sintaxi és la següent:
Com podem veure, simplement afegim inherits per crear la relació d'herència. Pel disseny que teníem anteriorment:
| SQL | |
|---|---|
Inserim algunes files, tenint en compte que també hem d'incloure els atributs de la superclasse.
Si executem diversos Select * from, obtenim a DBeaver:
Com és lògic, és possible pensar que quan seleccionem dades de la taula general (Select * from Figura) apareixeran tots els elements de les subclasses. Si volguéssim seleccionar només aquells que són Figura, podríem fer-ho amb (Select * from ONLY Figura).
Anem a completar l'exemple creant un dibuix amb totes les figures que hem emmagatzemat. Guardarem el dibuix en una nova classe que conté la identificació del dibuix, i guardarem una col·lecció amb els identificadors de les figures que componen el dibuix.
| SQL | |
|---|---|
Comentar que la selecció dels identificadors de Figura pot ser directa, o seleccionant aquells que volem, mitjançant una consulta incrustada dins del constructor ARRAY. Això es pot fer quan el select retorna una sola columna.
Obtenim els dibuixos que tenim, aquesta col·lecció de figures es mostra. Però si volem descompondre el vector, per accedir a cadascuna de les figures que hi ha, ho podem fer amb la funció unnest.