postgresql para almacenar documentos.

Alvaro Herrera alvherre en alvh.no-ip.org
Mie Mar 7 13:12:20 CLST 2007


Rodrigo Fuentealba escribió:

> Ahora, para esto tengo dos posibilidades: OID's y byte arrays. En
> experiencias como ésta... por tonta que sea la idea de meter un
> documento en una base de datos para compartirlo entre varias
> aplicaciones (la experiencia me dice que en el sistema de archivos la
> cosa no siempre funciona bien porque no existe un fine tunning como el
> que se requiere), ¿cuál será mejor, y por qué? sé cómo manipular ambos
> tipos de datos, pero desconozco los detalles de las diferencias como
> para discriminar, ¿qué me aconsejarían ustedes?

Yo te recomendaria usar bytea.

Los "large objects" (LO) tienen la desventaja de que no tienen control
de acceso y tienen una API que es totalmente diferente de lo que uno
acostumbra a usar en SQL (lo_open, lo_read etc).  Cuando quieres hacer
alguna cosa en "relacional" quedas muy amarrado de manos.

Los bytea tienen la desventaja de que no puedes operar sobre el objeto
porcionadamente; por ej. no puedes hacer seek y reemplazar un pedazo.
Pero creo que cuando almacenas documentos (PDF, Word, etc), rara vez
(lease nunca) haces eso; mas bien lo que haces es crear un objeto
totalmente nuevo.  La otra desventaja principal es que tienes que
escapar los bytes que vayas a insertar y des-escapar cuando los
extraigas(*); pero a cambio recibes el beneficio de poder operarlo
normalmente con INSERT, SELECT, etc, y construir un mecanismo de
"auditoria" puede ser mas sencillo.

Por otro lado, en Postgres el uso de bytea esta bastante optimizado por
el mecanismo conocido como TOAST.  Te recomiendo usar
ALTER TABLE tabla ALTER COLUMN columna SET STORAGE EXTERNAL
en la columna bytea, de manera que el sistema no trate de comprimir los
datos almacenados (generalmente la compresibilidad de esos documentos no
es mucha, y es mas rapido el acceso si no tiene que estar
comprimiendo/descomprimiendo).

(*) la alternativa a escapar/des-escapar es usar una API como
PQexecParams, pero si vas a usar PHP creo que eso no esta disponible.
En lenguajes razonables puedes hacerlo y es mucho mas eficiente porque
los datos binarios pasan directo a la base de datos y no se tiene que
gastar memoria en el proceso de escape.


Con respecto a la alternativa de almancenar los datos en el sistema de
archivos y guardar solo una referencia en la BD, te recomiendo que no lo
hagas a menos que el volumen de datos sea muy grande (hablo de decenas
de GB).  Es muy dificil hacerlo correctamente, sobre todo si nunca lo
has hecho, y no hacerlo correctamente lleva a documentos sin referencia
y referencias a documentos inexistentes, que son muy incomodos de
manejar.

-- 
Alvaro Herrera                        http://www.advogato.org/person/alvherre
"Changing the world ... one keyboard at a time!"
                         (www.DVzine.org)


Más información sobre la lista de distribución Linux