|
325 |
Consultas de PostgreSQL |
A raíz de que algunos de los lectores de mi página me hacen consultas acerca de PostgreSQL he decidido hacer esta página; puesto que las mismas
respuestas pueden servirle a alguien más.
Aunque tengo mucho usando PostgreSQL como manejador de bases de datos relacionales, en realidad nunca he llegado a ser un experto en este campo, así que estos consejos los escribo con el consabido "disclaimer": puede que esto no funcione.
En caso de duda, siempre se debería consultar directamente la página oficial de PostgreSQL.
PostgreSQL es la base de datos que uso para PaGEN.
|
[08/06/2002 17:10]
[ ] |
|
326 |
Como incluir una imagen dentro de una base de datos |
Aunque el sistema de archivos de un servidor unix es suficientemente eficiente para manejar grandes cantidades de archivos,
por alguna razón particular a veces es necesario incluir imágenes dentro de una base de datos.
PostgreSQL sólo permite introducir 8192 bytes por campo en una misma tupla, así que el límite es relativamente bajo.
Cuando queremos grabar más de 8192 bytes como un solo conjunto de datos (como en el caso de una imagen fotográfica), las cosas se complican. En este caso usamos "Large Objects" (Objetos grandes), que es un método interno de la base de datos que separa en páginas de 8192 bytes automáticamente y las
reacomoda de nuevo cuando ejecutamos una búsqueda. El usuario no tiene control sobre la fragmentación ni sobre la manipulación de esos datos, que no deja
de ser en realidad una ventaja.
Este es un ejemplo fácil que puede dar la pauta para crear otros programas más complicados. Primero, creamos una tabla que contiene un campo de
tipo oid , que son los objetos largos.
create table imagenes (
nombre_de_la_imagen text,
contenido oid);
|
Ahora insertamos una imagen dentro de la tabla con la función lo_import
insert into imagenes values (`mi auto`, lo_import(`/share/Fotos/carro-luis1.jpg`));
|
Para verificar que los datos son correctos, ahora exporto la imagen con otro nombre y la reviso en un editor de imágenes (por ejemplo, el Gimp.
select lo_export(imagenes.contenido, `/share/Fotos/carro_nueva_foto.jpg`)
from imagenes
where nombre_de_la_imagen = `mi auto`;
|
Como ya lo escribí más arriba, este ejemplo es burdo. Lo complicado viene cuando se quiere hacer una modificación a los datos que están grabados como objeto grande. Para eso se utilizan las funciones:
int lo_open(PGconn *conn, Oid lobjId, int mode) . Para abrir un objeto grande dentro de una transacción.
int lo_read(PGconn *conn, int fd, char *buf, size_t len) . Para cerrar el objeto.
int lo_write(PGconn *conn, int fd, const char *buf, size_t len) . Escribe bytes directamente en el objeto, a partir de la dirección donde está el apuntador. Para mover el apuntador, hay que usar lo_lseek .
int lo_lseek(PGconn *conn, int fd, int offset, int whence) . Busca una posición interna dentro del objeto; el usuario no tiene control sobre las páginas que el manejador de base de datos tiene que abrir para acceder a la dirección final de búsqueda.
int lo_close(PGconn *conn, int fd) . Cierra el objeto. Si no se cierra, éste se cerrará automáticamente al terminar la transacción.
Información más precisa acerca de estas funciones y otras propiedades de los objetos grandes se puede encontrar en el capítulo 16 de la guía del programador para PostgreSQL. Si obtuviste el programa de una fuente estándar (el sitio oficial o una distribución de GNU/Linux, por ejemplo), esta guía seguramente venía incluída.
Notas:
- Si el proceso de postgreSQL no tiene permiso de escritura en el directorio destino, un error aparecerá.
|
[08/06/2002 17:18]
[ ] |
|
356 |
Cambios en tablas |
Un lector me preguntó si es posible cambiar el tipo de una columna. Aunque lo he probado en Oracle, según el manual de PostgreSQL esto no es posible.
Asimismo, este usuario quiere borrar una columna que ya no utiliza. Desafortunadamente, este hecho va en contra de la naturaleza de las bases de datos relacionales y puede significar que el modelado original de la base de datos que se está usando ya no sea válido o que haya estado equivocado desde el principio.
Sin embargo, por cualquiera que sea la razón o circunstancia que nos lleve a hacer estos cambios, el siguiente es un método que podría seguirse para llevarlos a cabo.
Supongamos en un principio que tenemos una tabla con tres campos: id tipo numérico, nombre tipo texto, apellido tipo texto. Como segunda suposición, diremos que el campo id lo queremos cambiar de numérico a texto para poder aceptar códigos como "A1" o algo por el estilo. En el mismo proceso, dejaremos de lado la columna apellido .
Creamos la tabla de muestra con el siguiente código SQL (al tiempo que agregamos un par de tuplas de muestra):
pagen=# create table prueba (id int4, nombre text, apellido text);
CREATE
pagen=# insert into prueba values (1, `Luis`, `Arteaga`);
INSERT 75541 1
pagen=# insert into prueba values (2, `David`, `Alvarez`);
INSERT 75542 1
|
Acto seguido, creamos una tabla temporal que nos servirá para almacenar los datos tal como nosotros los queremos. Esta tabla será la que finalmente venga a suplir a nuestra tabla original.
pagen=# create table temporal (id text, nombre text);
CREATE
|
Como tercer paso, hay que copiar todos los datos de la tabla vieja (prueba) a la nueva (temporal). Otra suposición que haremos en nuestro ejemplo es que el apellido será agregado al nombre y quedarán ambos datos en un mismo campo. Hacemos luego un select para verificar que nuestros datos están tal como los queremos.
pagen=# insert into temporal (select to_char(id, `9`), nombre || ` ` || apellido from prueba);
INSERT 0 2
pagen=# select
pagen-# * from temporal;
id | nombre
----+---------------
1 | Luis Arteaga
2 | David Alvarez
(2 rows)
|
El último y decisivo paso: hay que borrar la tabla original y luego renombrar nuestra tabla temporal con su nombre final. De nuevo verificamos que los datos que tenemos son los correctos.
pagen=# drop table prueba;
DROP
pagen=# alter table temporal rename to prueba;
ALTER
pagen=# select
pagen-# * from prueba;
id | nombre
----+---------------
1 | Luis Arteaga
2 | David Alvarez
(2 rows)
|
Por supuesto, como cualquier otro movimiento crítico que incluya datos, siempre debe hacerse antes un respaldo de toda la base de datos, o al menos una copia de las tablas que se van a modificar.
También, este método sólo es válido si no hay otros procesos accesando las tablas al mismo tiempo, es decir, que la base de datos está abierta de manera exclusiva por el administrador. En caso contrario se deberá usar un método más sofisticado que el mostrado aquí.
|
[23/08/2002 19:55]
[ ] |
|
362 |
Configuración de PostgreSQL |
A continuación algunas variables de configuración importantes que se encuentran en el archivo postgresql.conf dentro del directorio data:
Variable | Descripción | Ejemplo |
max_connections |
Cambiando el valor de esta variable, postgreSQL permite hasta un máximo de conecciones simultáneas igual al valor asignado. Hay que tener cuidado con esta variable, pues postgreSQL asigna un cierto porcentaje de recursos para las sesiones, aún cuando éstas no estén abiertas. Para un sistema pequeño, unas 32 sesiones es un buen número. Nota: cuando se cambie este valor, hay que incrementar shared_buffers de manera acorde. |
max_connections = 50 |
|
|
[05/03/2003 17:13]
[ ] |
|
|