Suscríbete a DeepL Pro para poder traducir archivos de mayor tamaño.
Más información disponible en [Link]/pro.
PostgreSQL
Notas para los profesionales
Más de 60
páginas
de consejos y trucos
profesionales
[Link] Descargo
de responsabilidad Este es un libro gratuito no oficial creado con
fines educativos y no está afiliado con grupo(s) o compañía(s)
Libros de programación oficial(es) de PostgreSQL®.
Todas las marcas comerciales y marcas
gratuitos registradas pertenecen a sus
respectivos propietarios.
Contenido
Acerc . ...........................................................................................................................................................................1
a de
Capítulo 1: Introducción a PostgreSQL . ..............................................................................................2
Sección 1.1: Instalación de PostgreSQL en Windows ...................................................................................................................2
Sección 1.2: Instalar PostgreSQL desde el código fuente en Linux ....................................................................................3
Sección 1.3: Instalación en GNU+Linux.........................................................................................................................................4
Sección 1.4: Cómo instalar PostgreSQL a través de MacPorts en OSX..............................................................................5
Sección 1.5: Instalar postgresql con brew en Mac................................................................................................................7
Sección 1.6: [Link] para Mac OSX...............................................................................................................................7
Capítulo 2: Tipos de . .........................................................................................................................................8
datos
Sección 2.1: Tipos numéricos .......................................................................................................................................................8
Sección 2.2: Tipos de fecha/hora ............................................................................................................................................8
Sección 2.3: Tipos geométricos ....................................................................................................................................................9
Sección 2.4: Tipos de direcciones de red ...............................................................................................................................9
Sección 2.5: Tipos de caracteres..............................................................................................................................................9
Sección 2.6: Matrices....................................................................................................................................................................9
Capítulo 3: Fechas, marcas de tiempo e . .........................................................................................11
intervalos
Sección 3.1: SELECCIONE el último día del mes..................................................................................................................11
Sección 3.2: Convertir una marca de tiempo o . ..........................................................................................11
. ...........................................................................................11
intervalo en una cadena Sección 3.3: Contar el
número de registros por semana
Capítulo 4: Creación de .................................................................................................................................12
tablas
Sección 4.1: Mostrar definición de tabla ....................................................................................................................................12
Apartado 4.2: Crear tabla a partir de select ...............................................................................................................................12
Sección 4.3: Crear tabla no registrada .................................................................................................................................12
Sección 4.4: Creación de tablas con clave primaria ...........................................................................................................12
Sección 4.5: Crear una tabla que haga referencia a otra tabla ........................................................................................13
Capítulo 5: .................................................................................................................................................14
SELECCIÓN
Sección 5.1: SELECT con WHERE............................................................................................................................................14
Capítulo 6: Buscar Longitud de Cadena / . ...............................................................................15
Longitud de Carácter
Apartado 6.1: Ejemplo para obtener la longitud de un campo de caracteres variables...............................................15
Capítulo 7: COALESCE . .........................................................................................................................................16
Sección 7.1: Argumento único no nulo.................................................................................................................................16
Sección 7.2: Múltiples argumentos no nulos .............................................................................................................................16
Sección 7.3: Todos los argumentos nulos...................................................................................................................................16
Capítulo 8: .................................................................................................................................................17
INSERTAR
Sección 8.1: Insertar datos utilizando filas
COPIAR Sección 8.2: Insertar varias
.......................................................................................................................17
.......................................................................................................................18
Apartado 8.3: Datos INSERT y valores RETURING ..............................................................................................................18
Sección 8.4: INSERT básico ....................................................................................................................................................18
Sección 8.5: Insertar desde select ..............................................................................................................................................18
Sección 8.6: UPSERT - INSERT ... ON CONFLICT DO UPDATE. ............................................................................................19
Sección 8.7: SELECCIONAR datos en un fichero ..................................................................................................................19
Capítulo 9: . ..............................................................................................................................................21
ACTUALIZACIÓN
Apartado 9.1: Actualización de una tabla a partir de la unión con otra tabla............................................................................21
Sección 9.2: Actualizar todas las filas de una tabla ....................................................................................................................21
Sección 9.3: Actualizar todas las filas que cumplen una condición .................................................................................21
Sección 9.4: Actualización de varias columnas en una tabla ............................................................................................21
Capítulo 10: Soporte JSON .................................................................................................................................22
Sección 10.1: Uso de operadores JSONb ....................................................................................................................................22
Sección 10.2: Consulta de documentos JSON complejos ..................................................................................................26
Sección 10.3: Creación de una tabla JSON pura.................................................................................................................27
Capítulo 11: Funciones agregadas ....................................................................................................................28
Apartado 11.1: Estadísticas simples: min(), max(), avg() ...........................................................................................................28
Sección 11.2: regr_slope(Y, X) : pendiente de la ecuación lineal ajustada por mínimos cuadrados determinada por los
pares (X, Y)
. ........................................................................................................................................................................28
Sección 11.3: string_agg(expresión, delimitador) ......................................................................................................................29
Capítulo 12: Expresiones comunes de tabla . .....................................................................................31
(CON)
Sección 12.1: Expresiones de tabla comunes en consultas SELECT............................................................................................31
Sección 12.2: Recorrer el árbol utilizando WITH RECURSIVE ...........................................................................................31
Capítulo 13: Funciones de .........................................................................................................................32
ventana
Sección 13.1: ejemplo genérico .................................................................................................................................................32
Sección 13.2: valores de columna vs dense_rank vs rank vs row_number ....................................................................33
Capítulo 14: Consultas .........................................................................................................................34
recursivas
Sección 14.1: Suma de números enteros ...................................................................................................................................34
Capítulo 15: Programación con PL/pgSQL . ................................................................................................35
Sección 15.1: Función PL/pgSQL Básica................................................................................................................................35
Sección 15.2: excepciones ............................................................................................................................35
..............................................................................................................................36
personalizadas Sección 15.3:
Sintaxis PL/pgSQL
Sección 15.4: Bloque DEVOLUCIONES........................................................................................................................................36
Capítulo 16: Herencia . ......................................................................................................................................37
Sección 16.1: Creación de tablas de hijos ..................................................................................................................................37
Capítulo 17: Exportar la cabecera y los datos de la tabla de la base de datos ...........................38
PostgreSQL a un archivo CSV
Sección 17.1: copia desde consulta............................................................................................................................................38
Sección 17.2: Exportar tabla PostgreSQL a csv con cabecera para alguna(s) columna(s) ............................................38
Sección 17.3: Copia de seguridad de tabla completa a csv ................................................................................................38
con cabecera ..............................................................................................39
Capítulo 18: Disparadores y funciones
disparadoras
Apartado 18.1: Tipo de activadores.......................................................................................................................................39
Sección 18.2: Función básica de activación PL/pgSQL ......................................................................................................40
Capítulo 19: Activadores ................................................................................................................................42
de eventos
Sección 19.1: Registro de eventos de inicio de comandos DDL ........................................................................................42
Capítulo 20: Gestión de . ......................................................................................................................43
funciones
Sección 20.1: Crear un usuario con contraseña..................................................................................................................43
Sección 20.2: Concesión y revocación de privilegios.........................................................................................................43
Sección 20.3: Crear una base de datos de roles y correspondencias ..............................................................................44
Sección 20.4: Alterar search_path por defecto del usuario..............................................................................................44
Sección 20.5: Crear usuario de sólo lectura ........................................................................................................................45
Apartado 20.6: Conceder privilegios de acceso a objetos creados en el futuro............................................................45
Capítulo 21: Funciones criptográficas de . ........................................................................................46
Postgres
Sección 21.1: resumen ...............................................................................................................................................................46
Capítulo 22: Comentarios en .........................................................................................................47
PostgreSQL
Sección 22.1: COMENTARIO ..........................................................................................................................47
...........................................................................................................................47
sobre la tabla Sección 22.2:
Eliminar comentario
Capítulo 23: Copia de seguridad ....................................................................................................................48
y restauración
Sección 23.1: Copia de seguridad de una base de datos............................................................................................................48
Sección 23.2: Restauración de copias de seguridad ............................................................................................................48
Sección 23.3: Copia de seguridad de todo el cluster .........................................................................................................48
Sección 23.4: Uso de psql para exportar datos...................................................................................................................49
Apartado 23.5: Utilizar Copy para .......................................................................................................................49
importar Apartado 23.6: Utilizar . ......................................................................................................................50
Copy para exportar Usar Copiar
para exportar
Capítulo 24: Script de backup para una BD de . .....................................................................................51
producción
Sección 24.1: [Link]......................................................................................................................................................51
Capítulo 25: Acceso a datos mediante . ......................................................................................52
programación
Sección 25.1: Acceso a PostgreSQL con la C-API.................................................................................................................52
Sección 25.2: Acceso a PostgreSQL desde python usando psycopg2..............................................................................55
Sección 25.3: Acceso a PostgreSQL desde .NET usando el proveedor Npgsql ...............................................................55
Sección 25.4: Acceso a PostgreSQL desde PHP usando Pomm2.................................................................................56
Capítulo 26. Conectarse a PostgreSQL desde . .....................................................................................58
Java Conectarse a PostgreSQL desde Java
Sección 26.1: Conexión con [Link]..................................................................................................................58
Sección 26.2: Conexión con [Link] y Propiedades ...............................................................................58
Sección 26.3: Conexión con [Link] usando un pool de conexiones.......................................................59
Capítulo 27: PostgreSQL Alta . .................................................................................................61
Disponibilidad
Sección 27.1: Replicación en PostgreSQL ...................................................................................................................................61
Capítulo 28: EXTENSIÓN dblink y postgres_fdw . ...............................................................................64
Sección 28.1: Extensión FDW .....................................................................................................................................................64
Sección 28.2: Envoltura de datos ajenos .............................................................................................................................64
Sección 28.3: Extensión dblink..............................................................................................................................................65
Capítulo 29: Trucos y consejos para . ............................................................................................................66
Postgres
Sección 29.1: La alternativa DATEADD en Postgres ...........................................................................................................66
Sección 29.2: Valores separados por comas de una columna..........................................................................................66
Sección 29.3: Borrar registros duplicados de la tabla postgres........................................................................................66
Apartado 29.4: Consulta de actualización con join entre dos tablas alternativa ya que Postresql no soporta join
en consulta de actualización..........................................................................................................................................66
Apartado 29.5: Diferencia entre dos marcas de fecha y hora en función del mes y del año.......................................66
Sección 29.6: Consulta para copiar/mover/transferir datos de una tabla de una base de datos a otra tabla de otra base de
datos con
mismo esquema.............................................................................................................................................................67
Crédit ........................................................................................................................................................................68
os
También le ...................................................................................................................................................70
puede interesar
Acerca de
Por favor, siéntase libre de compartir este PDF con
cualquier persona de forma gratuita, la última versión
de este libro se puede descargar desde:
[Link]
Este libro PostgreSQL® Notes for Professionals está compilado de la
Documentación de Stack Overflow, el contenido está escrito por la hermosa
gente de Stack Overflow. El contenido del texto está liberado bajo Creative
Commons BY-SA, vea los créditos al final de este libro de quienes contribuyeron
a los diversos capítulos. Las imágenes pueden ser copyright de sus respectivos
propietarios a menos que se especifique lo contrario.
Este es un libro gratuito no oficial creado con propósitos educativos y no está
afiliado con grupo(s) o compañía(s) oficial(es) de PostgreSQL® ni con Stack
Overflow. Todas las marcas y marcas registradas son propiedad de sus
respectivos dueños.
No se garantiza que la información presentada en este libro sea correcta ni
exacta. Utilícelo bajo su propia responsabilidad.
Envíe sus comentarios y correcciones a web@[Link]
[Link] - Apuntes de PostgreSQL® para 1
profesionales
Capítulo 1: Introducción a PostgreSQL
Versión Fecha de lanzamiento Fecha EOL
10.0 2017-10-05 2022-10-01
9.6 2016-09-29 2021-09-01
9.5 2016-01-07 2021-01-01
9.4 2014-12-18 2019-12-01
9.3 2013-09-09 2018-09-01
9.2 2012-09-10 2017-09-01
9.1 2011-09-12 2016-09-01
9.0 2010-09-20 2015-09-01
8.4 2009-07-01 2014-07-01
Sección 1.1: Instalación de PostgreSQL en Windows
Aunque es una buena práctica utilizar un sistema operativo basado en Unix (por ejemplo, Linux o BSD) como
servidor de producción, puede instalar fácilmente PostgreSQL en Windows (a ser posible, sólo como servidor de
desarrollo).
Descargue los binarios de instalación para Windows desde EnterpriseDB:
[Link] Se trata de una empresa externa creada por
colaboradores principales del proyecto PostgreSQL que han optimizado los binarios para Windows.
Selecciona la última versión estable (no beta) (9.5.3 en el momento de escribir estas líneas). Lo más probable
es que quieras el paquete Win x86-64, pero si estás ejecutando una versión de 32 bits de Windows, lo que es
habitual en ordenadores antiguos, selecciona Win x86-32 en su lugar.
Nota: El cambio entre las versiones Beta y Estable implicará tareas complejas como volcado y restauración. La
actualización dentro de la versión beta o estable sólo necesita un reinicio del servicio.
Puede comprobar si su versión de Windows es de 32 o 64 bits accediendo al Panel de control -> Sistema y seguridad ->
Sistema
-> Tipo de sistema, que dirá "##-bit Operating System". Esta es la ruta para Windows 7, puede ser ligeramente
diferente en otras versiones de Windows.
En el instalador, seleccione los paquetes que desea utilizar. Por ejemplo:
pgAdmin ( [Link] ) es una GUI gratuita para gestionar su base de datos y la recomiendo
encarecidamente. En
9.6 se instalará por defecto .
PostGIS ( [Link] ) proporciona funciones de análisis geoespacial sobre coordenadas GPS, distancias,
etc. muy populares entre los desarrolladores de SIG.
El paquete de lenguajes proporciona las librerías necesarias para los lenguajes procedimentales soportados
oficialmente PL/Python, PL/Perl y PL/Tcl.
Otros paquetes como pgAgent, pgBouncer y Slony son útiles para servidores de producción más grandes, sólo se
comprueban cuando es necesario.
Todos esos paquetes opcionales pueden instalarse posteriormente a través de "Application Stack Builder".
Nota: También existen otros lenguajes no soportados oficialmente como PL/V8, PL/Lua PL/Java.
Abra pgAdmin y conéctese a su servidor haciendo doble clic en su nombre, por ejemplo, "PostgreSQL 9.5
[Link] - Apuntes de PostgreSQL® para 2
profesionales
(localhost:5432)".
A partir de este punto puedes seguir guías como el excelente libro PostgreSQL: Up and Running, 2ª Edición (
[Link] ).
[Link] - Apuntes de PostgreSQL® para 3
profesionales
Opcional: Servicio manual Tipo de puesta en marcha
PostgreSQL se ejecuta como un servicio en segundo plano, lo que es ligeramente diferente a la mayoría de los
programas. Esto es común para bases de datos y servidores web. Su tipo de inicio por defecto es automático, lo
que significa que siempre se ejecutará sin ninguna intervención por su parte.
¿Por qué querrías controlar manualmente el servicio PostgreSQL? Si estás usando tu PC como un servidor de
desarrollo parte del tiempo y también lo usas para jugar videojuegos por ejemplo, PostegreSQL podría ralentizar
un poco tu sistema mientras se ejecuta.
¿Por qué no querrías un control manual? Iniciar y detener el servicio puede ser una molestia si lo haces a menudo.
Si no nota ninguna diferencia en la velocidad y prefiere evitar las molestias, deje el Tipo de inicio como Automático
e ignore el resto de esta guía. De lo contrario...
Vaya a Panel de control -> Sistema y seguridad -> Herramientas administrativas.
Selecciona "Servicios" de la lista, haz clic con el botón derecho en su icono y selecciona Enviar a -> Escritorio para crear
un icono en el escritorio y acceder a él con mayor comodidad.
Cierre la ventana Herramientas administrativas y, a continuación, inicie Servicios desde el icono del
escritorio que acaba de crear. Desplácese hacia abajo hasta que vea un servicio con un nombre
como postgresql-x##-9.# (por ejemplo, "postgresql-x64-9.5").
Haga clic con el botón derecho en el servicio postgres, seleccione Propiedades -> Tipo de inicio -> Manual ->
Aplicar -> Aceptar. Puede volver a cambiarlo a automático con la misma facilidad.
Si ve otros servicios relacionados con PostgreSQL en la lista como "pgbouncer" o "PostgreSQL Scheduling Agent -
pgAgent" también puede cambiar su Tipo de Inicio a Manual porque no son de mucha utilidad si PostgreSQL no se
está ejecutando. Aunque esto significará más molestias cada vez que se inicie y se detenga por lo que depende de
usted. No utilizan tantos recursos como el propio PostgreSQL y puede que no tengan ningún impacto notable en el
rendimiento de su sistema.
Si el servicio se está ejecutando, su Estado dirá Iniciado, de lo contrario no se está ejecutando.
Para iniciarlo, haz clic con el botón derecho del ratón y selecciona Iniciar. Aparecerá un mensaje de carga que
debería desaparecer por sí solo poco después. Si te da error, inténtalo una segunda vez. Si no funciona, es
que ha habido algún problema con la instalación, posiblemente porque has cambiado algún ajuste en
Windows que la mayoría de la gente no cambia, así que para encontrar el problema puede que tengas que
investigar un poco.
Para detener Postgres, haga clic con el botón derecho en el servicio y seleccione Detener.
Si alguna vez se produce un error al intentar conectarse a la base de datos, compruebe los Servicios para asegurarse de que
se están ejecutando.
Para otros detalles muy específicos sobre la instalación de EDB PostgreSQL, por ejemplo, la versión de ejecución
de python en el paquete de idioma oficial de una versión específica de PostgreSQL, consulte siempre la guía
oficial de instalación de EBD , cambie la versión en enlace a la versión principal de su instalador.
Sección 1.2: Instalar PostgreSQL desde el código fuente en Linux
Dependencias:
[Link] - Apuntes de PostgreSQL® para 4
profesionales
GNU Make Versión > 3.80
un compilador de C ISO/ ANSI (por
ejemplo, gcc) un extractor como tar
o gzip
zlib-devel
[Link] - Apuntes de PostgreSQL® para 5
profesionales
readline-devel o libedit-devel
Fuentes: Enlace a la última fuente
(9.6.3) Ahora puede extraer los
tar -xzvf [Link]
archivos fuente:
Hay un gran número de opciones diferentes para la configuración de PostgreSQL:
Enlace completo al procedimiento completo de instalación
Pequeña lista de opciones disponibles:
--prefix=Ruta PATH para todos los archivos
--exec-prefix=PATH ruta para el archivo architectur-dependet
--bindir=PATH ruta para programas ejecutables
--sysconfdir=PATH ruta para los archivos de configuración
--with-pgport=NUMBER especifique un puerto para su servidor
--with-perl añade soporte perl
--with-python añade soporte para python
--with-openssl añade soporte openssl
--with-ldap añadir soporte ldap
--with-blocksize=BLOCKSIZE establece el tamaño de las páginas en KB
BLOCKSIZE debe ser una potencia de 2 y estar comprendido entre 1 y
32
--with-wal-segsize=SEGSIZE establece el tamaño del segmento WAL en
MB
SEGSIZE debe ser una potencia de 2 entre 1 y 64
Vaya a la nueva carpeta creada y ejecute el script cofigure con las opciones deseadas:
./configure --exec=/usr/local/pgsql
Ejecuta make para crear los archivos objeto
Ejecute make install para instalar PostgreSQL desde los
archivos creados. Ejecute make clean para limpiar.
Para la extensión cambia el directorio cd contrib, ejecuta make y make install
Sección 1.3: Instalación en GNU+Linux
En la mayoría de los sistemas operativos GNU+Linux, PostgreSQL puede instalarse fácilmente mediante el gestor
de paquetes del sistema operativo.
Familia Red Hat
Los repositorios se pueden encontrar aquí:
[Link] Descargue el repositorio a la máquina
yum -y install [Link]
[Link] - Apuntes de PostgreSQL® para
[Link] 6
profesionales
local con el comando
Ver paquetes disponibles:
[Link] - Apuntes de PostgreSQL® para 7
profesionales
yum list available | grep postgres*
Los paquetes necesarios son: postgresqlXX postgresqlXX-server postgresqlXX-libs postgresqlXX-contrib
Se instalan con el siguiente comando: yum -y install postgresqlXX postgresqlXX-server postgresqlXX-libs
postgresqlXX-contrib
Una vez instalado tendrá que iniciar el servicio de base de datos como propietario del servicio (por defecto es
postgres). Esto se hace con el comando pg_ctl.
sudo -su postgres
./usr/pgsql-X.X/bin/pg_ctl -D /var/lib/pgsql/X.X/data start
Para acceder a la BD en CLI introduzca psql
Familia Debian
En Debian y sistemas operativos derivados, escriba:
sudo apt-get install postgresql
Esto instalará el paquete del servidor PostgreSQL, en la versión por defecto ofrecida por los repositorios de paquetes del
sistema operativo.
Si la versión que se instala por defecto no es la que desea, puede utilizar el gestor de paquetes para buscar
versiones específicas que puedan ofrecerse simultáneamente.
También puede utilizar el repositorio Yum proporcionado por el proyecto PostgreSQL (conocido como PGDG)
para obtener una versión diferente. Esto puede permitir versiones aún no ofrecidas por los repositorios de
paquetes del sistema operativo.
Sección 1.4: Cómo instalar PostgreSQL a través de MacPorts en
OSX
Para instalar PostgreSQL en OSX, necesita saber qué versiones están soportadas actualmente.
Utilice este comando para ver qué versiones tiene disponibles.
sudo port list | grep "^postgresql[[:digit:]]\{2\}[[:space:]]"
Debería obtener una lista parecida a la siguiente:
postgresql80 @8.0.26 bases de
datos/postgresql80
postgresql81 @8.1.23 bases de
datos/postgresql81
postgresql82 @8.2.23 bases de
datos/postgresql82
postgresql83 @8.3.23 bases de
datos/postgresql83
postgresql84 @8.4.22 bases de
datos/postgresql84
postgresql90 @9.0.23 bases de
datos/postgresql90
postgresql91 @9.1.22 bases de
datos/postgresql91
postgresql92 @9.2.17 bases de
datos/postgresql92
[Link] - Apuntes de PostgreSQL® para 8
profesionales
postgresql93 @9.3.13 bases de
datos/postgresql93
postgresql94 @9.4.8 bases de
datos/postgresql94
postgresql95 @9.5.3 bases de
datos/postgresql95
postgresql96 @9.6beta2 bases de
datos/postgresql96
En este ejemplo, la versión más reciente de PostgreSQL que se admite en 9.6, por lo que vamos a instalar eso.
[Link] - Apuntes de PostgreSQL® para 9
profesionales
sudo port install postgresql96-server postgresql96
Verás un registro de instalación como éste:
---> Dependencias de computación para postgresql96-server
---> Dependencias a instalar: postgresql96
---> Fetching archive for postgresql96
---> Intentando obtener postgresql96-9.6beta2_0.darwin_15.x86_64.tbz2 de
[Link]
---> Intentando recuperar postgresql96-9.6beta2_0.darwin_15.x86_64.tbz2.rmd160 de
[Link]
---> Instalando postgresql96 @9.6beta2_0
---> Activando postgresql96 @9.6beta2_0
Para utilizar el servidor postgresql, instale el puerto postgresql96-server
---> Limpieza postgresql96
---> Fetching archive for postgresql96-server
---> Intentando obtener postgresql96-server-9.6beta2_0.darwin_15.x86_64.tbz2 de
[Link]
---> Intentando recuperar postgresql96-server-9.6beta2_0.darwin_15.x86_64.tbz2.rmd160 de
[Link]
---> Instalando postgresql96-server @9.6beta2_0
---> Activando postgresql96-server @9.6beta2_0
Para crear una instancia de base de datos, después de la instalación haga
sudo mkdir -p /opt/local/var/db/postgresql96/defaultdb
sudo chown postgres:postgres /opt/local/var/db/postgresql96/defaultdb
sudo su postgres -c '/opt/local/lib/postgresql96/bin/initdb -D
/opt/local/var/db/postgresql96/defaultdb'
---> Limpieza de postgresql96-server
---> Dependencias de computación para postgresql96
---> Limpieza postgresql96
---> Actualización de la base de datos de binarios
---> Análisis de binarios en busca de errores de vinculación
---> No se han encontrado archivos rotos.
El registro proporciona instrucciones sobre el resto de los pasos para la instalación, así que lo haremos a continuación.
sudo mkdir -p /opt/local/var/db/postgresql96/defaultdb
sudo chown postgres:postgres /opt/local/var/db/postgresql96/defaultdb
sudo su postgres -c '/opt/local/lib/postgresql96/bin/initdb -D
/opt/local/var/db/postgresql96/defaultdb'
Ahora iniciamos el servidor:
sudo port load -w postgresql96-server
Comprueba que podemos conectarnos al servidor:
su postgres -c psql
Verá un mensaje de postgres:
psql (9.6.1)
Escribe "help" para obtener ayuda.
[Link] - Apuntes de PostgreSQL® para 10
profesionales
postgres=#
Aquí puedes escribir una consulta para ver que el servidor está funcionando.
postgres=#SELECT setting FROM pg_settings WHERE NAME='directorio_datos';
Y ver la respuesta:
ajuste
/opt/local/var/db/postgresql96/defaultdb
(1 fila)
postgres=#
Teclee \q para salir:
postgres=#\q
Y estarás de vuelta en el prompt de tu shell.
¡Enhorabuena! Ahora tiene una instancia PostgreSQL en ejecución en OS/X.
Sección 1.5: Instalar postgresql con brew en Mac
Homebrew se autodenomina "el gestor de paquetes que faltaba para macOS". Se puede utilizar para crear e instalar
aplicaciones y bibliotecas. Una vez instalado, puede utilizar el comando brew para instalar PostgreSQL y sus
dependencias de la siguiente manera:
brebaje ACTUALIZACIÓN
brew install postgresql
Homebrew generalmente instala la última versión estable. Si necesita una diferente entonces brew SEARCH
postgresql listará las versiones disponibles. Si necesita PostgreSQL construido con opciones particulares
entonces brew info postgresql listará qué opciones están soportadas. Si necesita una opción de compilación no
soportada, puede que tenga que hacer la compilación usted mismo, pero aún puede usar Homebrew para instalar
las dependencias comunes.
Inicie el servidor:
brew services START postgresql
Abra el indicador PostgreSQL
psql
Si psql se queja de que no existe una base de datos correspondiente para su usuario, ejecute CREATEDB.
Sección 1.6: [Link] para Mac OSX
Una herramienta extremadamente sencilla para instalar PostgreSQL en un Mac está disponible descargando [Link].
Puede cambiar las preferencias para que PostgreSQL se ejecute en segundo plano o sólo cuando se esté ejecutando la
aplicación.
[Link] - Apuntes de PostgreSQL® para 11
profesionales
Capítulo 2: Tipos de datos
PostgreSQL tiene un rico conjunto de tipos de datos nativos disponibles para los usuarios. Los usuarios pueden añadir
nuevos tipos a PostgreSQL usando el comando CREATE TYPE.
[Link]
Sección 2.1: Tipos numéricos
Nombre Tamaño de almacenamiento Descripción Gama
SMALLINT 2 bytes entero de rango pequeño -32768 a +32767
ENTERO 4 bytes lección típica para enteros -2147483648 a +2147483647
-9223372036854775808 a
BIGINT 8 bytes entero de rango grande
+9223372036854775807
hasta 131072 dígitos antes del punto decimal;
DECIMAL variable precisión especificada por el
hasta 16383 dígitos después del punto
usuario, exacta decimal
hasta 131072 dígitos antes del punto decimal;
NÚMERO variable precisión especificada por el
hasta 16383 dígitos después del punto
usuario, exacta decimal
REAL 4 bytes precisión variable, inexacta 6 dígitos decimales
precisión DOBLE PRECISIÓN 8 bytes precisión variable,
inexacta 15 dígitos decimales de precisión smallserial 2 bytes pequeño
entero autoincrementable 1 a 32767
serie 4 bytes entero autoincrementado 1 a 2147483647
BIGSERIAL 8 bytes entero grande autoincrementable de 1 a 9223372036854775807
int4rango Rango de enteros
int8rango Rango de bigint
rango numérico Rango numérico
Sección 2.2: Tipos de fecha/hora
Tamañ
Nomb DescripciónValor bajo Valor alto Resolución
o de
re alma
cena
mient
o
TIMESTAMP
tanto la fecha como la hora (no 1 microsegundo / 14
(sin huso 8 bytes 4713
dígitos
horario) zona BC294276 AD
horaria)
TIMESTAMP (con tanto la fecha como la 1 microsegundo / 14
4713 BC294276 AD
zona horaria) 8 bytes hora, con la zona
horaria dígit
FECHA 4 bytesfecha (sin hora del día) 4713 a.C. os
5874897 d .C.1 día
HORA (sin hora 1 microsegundo / 14
8 bytes hora del día (sin fecha) 00:00:00 24:00:00
zona) dígitos
HORA (con sólo las horas del día, 1 microsegundo / 14
12 00:00: 00+145924:00:00-1459
huso horario) con zona horaria dígit
bytes
1osmicrosegundo / 14
INTERVALO 16 bytes intervalo de tiempo -178000000 años 178000000 años
dígit
rango de marca de os
tsrange
tiempo sin zona
[Link] - Apuntes de PostgreSQL® para 12
profesionales
horaria
rango de marca de
tstzrange
tiempo con zona
horaria
daterange rango de fecha
[Link] - Apuntes de PostgreSQL® para 13
profesionales
Sección 2.3: Tipos geométricos
Nombre Almacenamiento Tamaño Descripción Representación
punto 16 bytes Punto de un plano (x,y)
línea 32 bytes Línea infinita {A,B,C}
lseg 32 bytes Segmento de línea finito ((x1,y1),(x2,y2))
CAJA 32 bytes Caja rectangular ((x1,y1),(x2,y2))
path 16+16n bytes
Trayectoria cerrada (similar al polígono) ((x1,y1),...) path 16+16n
bytes Trayectoria abierta [(x1,y1),...]
polygon 40+16n bytes Polígono (similar a la trayectoria cerrada)
((x1,y1),...)
CIRCLE 24 bytes Círculo <(x,y),r> (punto central y radio)
Sección 2.4: Tipos de direcciones de red
Nombre Almacenamiento Tamaño Descripción
CIDR 7 o 19 bytes Redes IPv4 e IPv6
INET 7 o 19 bytes Redes y hosts IPv4 e IPv6
macaddr 6 bytes Direcciones MAC
Sección 2.5: Tipos de caracteres
Nombre Descripción
CHARACTER varying(n), varchar(n) longitud variable con límite
carácter(n), char(n) longitud fija, relleno en blanco
TEXTO variable longitud ilimitada
Sección 2.6: Matrices
En PostgreSQL puede crear Arrays de cualquier tipo incorporado, definido por el usuario o enum. Por defecto no
hay límite para un Array, pero puedes especificarlo.
SELECT ENTERO[];
SELECT ENTERO[3];
SELECT ENTERO[][];
SELECT ENTERO[3][3];
SELECT ENTERO ARRAY;
SELECT ENTERO ARRAY[3];
Declaración de una matriz
SELECCIONE '{0,1,2}';
SELECCIONE '{{0,1},{1,2}}';
SELECCIONE ARRAY[0,1,2];
SELECT ARRAY[ARRAY[0,1],ARRAY[1,2]];
Creación de una matriz
Acceso a una matriz
[Link] - Apuntes de PostgreSQL® para 14
profesionales
Por defecto, PostgreSQL utiliza una convención de numeración basada en uno para las matrices, es decir, una
matriz de n elementos comienza con ARRAY[1] y termina con ARRAY[n].
--acceso a un elemento spefífico
[Link] - Apuntes de PostgreSQL® para 15
profesionales
WITH arr AS (SELECT ARRAY[0,1,2] int_arr) SELECT int_arr[1] FROM arr;
int_arr
0
(1 FILA)
--sclicing an array
WITH arr AS (SELECT ARRAY[0,1,2] int_arr) SELECT int_arr[1:2] FROM arr;
int_arr
{0,1}
(1 FILA)
Obtener información sobre una matriz
--dimensiones de la matriz (como texto)
WITH arr AS (SELECT ARRAY[0,1,2] int_arr) SELECT ARRAY_DIMS(int_arr) FROM arr;
array_dims
[1:3]
(1 FILA)
--longitud de una dimensión de matriz
WITH arr AS (SELECT ARRAY[0,1,2] int_arr) SELECT ARRAY_LENGTH(int_arr,1) FROM arr;
longitud_array
3
(1 FILA)
--número total de elementos en todas las dimensiones
WITH arr AS (SELECT ARRAY[0,1,2] int_arr) SELECT cardinality(int_arr) FROM arr;
cardinality
3
(1 FILA)
Funciones de matriz
se añadirá
[Link] - Apuntes de PostgreSQL® para 16
profesionales
Capítulo 3: Fechas, marcas de tiempo e
intervalos
Sección 3.1: SELECCIONE el último día del mes
Puede seleccionar el último día del mes.
SELECT (DATE_TRUNC('MES', ('201608'||'01')::DATE) + INTERVALO '1 MES - 1 día')::DATE;
201608 es sustituible por una variable.
Sección 3.2: Convertir una marca de tiempo o un intervalo en
una cadena
Puede convertir un valor TIMESTAMP o INTERVALO en una cadena con la función TO_CHAR():
SELECT TO_CHAR('2016-08-12 16:40:32'::TIMESTAMP, 'DD Mon YYYY HH:MI:SSPM');
Esta sentencia producirá la cadena "12 Aug 2016 04:40:32PM". La cadena de formato se puede modificar de muchas
maneras diferentes; la lista completa de patrones de plantilla se puede encontrar aquí.
Tenga en cuenta que también puede insertar texto sin formato en la cadena de formato y que puede utilizar los patrones
de plantilla en cualquier orden:
SELECT TO_CHAR('2016-08-12 16:40:32'::TIMESTAMP,
'"Hoy es "FMDay", el día "DDth" del mes de "FMMonth" de "YYYY');
Esto producirá la cadena "Hoy es sábado, día 12 del mes de agosto de 2016". Debe tener en cuenta, sin
embargo, que cualquier patrón de plantilla - incluso los de una sola letra como "I", "D", "W" - se convierten, a
menos que el texto sin formato esté entre comillas dobles. Como medida de seguridad, debe poner todo el texto
sin formato entre comillas dobles, como se ha hecho anteriormente.
Puede localizar la cadena al idioma de su elección (nombres de día y mes) utilizando el modificador TM (modo
de traducción). Esta opción utiliza la configuración de localización del servidor que ejecuta PostgreSQL o del
cliente que se conecta a él.
SELECT TO_CHAR('2016-08-12 16:40:32'::TIMESTAMP, 'TMDay, DD" de "TMMonth" del año "YYYY');
Con una configuración regional española se obtiene "Sábado, 12 de Agosto del año 2016".
Sección 3.3: Contar el número de registros por semana
SELECT DATE_TRUNC('semana', <>) AS "Semana" ,
COUNT(*) FROM <>
GRUPO POR 1
ORDENAR POR 1;
[Link] - Apuntes de PostgreSQL® para 17
profesionales
Capítulo 4: Creación de tablas
Sección 4.1: Mostrar definición de tabla
Abra la herramienta de línea de comandos psql conectada a la base de datos donde se encuentra su tabla. A
continuación, escriba el siguiente comando:
\d tablename
Para obtener información ampliada, escriba
\d+ tablename
Si ha olvidado el nombre de la tabla, escriba \d en psql para obtener una lista de tablas y vistas de la base de datos
actual.
Sección 4.2: Crear tabla a partir de select
Digamos que tienes una tabla llamada persona:
CREAR TABLA persona (
person_id BIGINT NOT NULL,
apellido VARCHAR(255) NOT NULL,
nombre VARCHAR(255),
edad INT NOT NULL,
PRIMARY KEY (person_id)
);
Puedes crear una nueva tabla de personas mayores de 30 años de la siguiente manera:
CREATE TABLE people_over_30 AS SELECT * FROM persona WHERE edad > 30;
Sección 4.3: Crear tabla no registrada
Puede crear tablas no registradas para que las tablas sean considerablemente más rápidas. La tabla sin registro omite
la escritura
WRITE-ahead log, lo que significa que no es a prueba de fallos y no puede replicarse.
CREATE UNLOGGED TABLE persona (
person_id BIGINT NOT NULL PRIMARY KEY,
apellido VARCHAR(255) NOT NULL,
nombre VARCHAR(255), dirección
VARCHAR(255),
ciudad VARCHAR(255)
);
Sección 4.4: Creación de tablas con clave primaria
CREAR TABLA persona (
person_id BIGINT NOT NULL,
apellido VARCHAR(255) NOT NULL,
nombre VARCHAR(255), dirección
VARCHAR(255),
ciudad VARCHAR(255),
PRIMARY KEY (person_id)
[Link] - Apuntes de PostgreSQL® para 18
profesionales
);
También puede colocar la restricción PRIMARY KEY directamente en la definición de la columna:
CREAR TABLA persona (
person_id BIGINT NOT NULL PRIMARY KEY,
apellido VARCHAR(255) NOT NULL,
nombre VARCHAR(255), dirección
VARCHAR(255),
ciudad VARCHAR(255)
);
Se recomienda utilizar minúsculas para la tabla y todas las columnas. Si utiliza nombres en mayúsculas, como
Persona, tendrá que encerrar ese nombre entre comillas dobles ("Persona") en todas y cada una de las
consultas, ya que PostgreSQL aplica la distinción entre mayúsculas y minúsculas.
Sección 4.5: Crear una tabla que haga referencia a otra tabla
En este ejemplo, la tabla de usuarios tendrá una columna que hará referencia a la tabla de agencias.
CREAR TABLA agencias ( -- crear primero la tabla agencias
id SERIAL PRIMARY KEY,
NAME TEXT NOT NULL
)
CREAR TABLA usuarios (
id SERIAL PRIMARY KEY,
agency_id NOT NULL INTEGER REFERENCES agencies(id) DEFERRABLE INITIALLY DEFERRED -- esto va a hacer
referencia a su tabla de agencias.
)
[Link] - Apuntes de PostgreSQL® para 19
profesionales
Capítulo 5: SELECCIÓN
Sección 5.1: SELECT con WHERE
En este tema nos basaremos en esta tabla de usuarios :
CREAR TABLA sch_test.user_table
(
id serial NOT NULL,
username CHARACTER VARYING,
pass CHARACTER VARYING,
first_name CHARACTER varying(30),
last_name CHARACTER varying(30),
CONSTRAINT tabla_usuario_clave PRIMARY KEY
(id)
)
+----+------------+-----------+----------+ ---------+
| id | first_name | last_name | username | pass |
+----+------------+-----------+----------+ ---------+
| 1. Hola mundo. Hola
palabra.
+----+------------+-----------+----------+ ---------+
| 2. Raíz. Yo. Raíz.
Toor.
+----+------------+-----------+----------+ ---------+
Sintaxis
Selecciónalo todo:
SELECT * FROM nombre_esquema.nombre_tabla WHERE <condición>;
Seleccione algunos campos :
SELECT campo1, campo2 FROM nombre_esquema.nombre_tabla WHERE <condición>;
Ejemplos
-- SELECT every thing where id = 1
SELECT * FROM nombre_esquema.nombre_tabla WHERE id = 1;
-- SELECT id where username = ? and pass = ?
SELECT id FROM nombre_esquema.nombre_tabla WHERE nombre_usuario = 'root' AND pass = 'toor';
-- SELECT nombre donde id no es igual a 1
SELECT nombre FROM nombre_esquema.nombre_tabla WHERE id != 1;
[Link] - Apuntes de PostgreSQL® para 20
profesionales
Capítulo 6: Buscar longitud de cadena /
longitud de carácter
Para obtener la longitud de los campos "character varying", "text", utilice char_length() o character_length().
Apartado 6.1: Ejemplo para obtener la longitud de un campo de
caracteres variables
Ejemplo 1, Consulta: SELECT CHAR_LENGTH('ABCDE')
Resultado:
Ejemplo 2, Consulta: SELECT LONGITUD_CARÁCTER('ABCDE')
Resultado:
[Link] - Apuntes de PostgreSQL® para 21
profesionales
Capítulo 7: COALESCE
Coalesce devuelve el primer argumento no nulo de un conjunto de argumentos. Sólo se devuelve el primer
argumento no nulo, todos los argumentos siguientes se ignoran. La función se evaluará como null si todos los
argumentos son null.
Sección 7.1: Argumento único no nulo
PGSQL> SELECT COALESCE(NULL, NULL, 'HOLA MUNDO');
COALESCE
HOLA MUNDO
Sección 7.2: Múltiples argumentos no nulos
PGSQL> SELECT COALESCE(NULL, NULL, 'primero no nulo', NULL, NULL, 'segundo no nulo');
confluir
'first non null'
Sección 7.3: Todos los argumentos nulos
PGSQL> SELECT COALESCE(NULL, NULL, NULL);
COALESCE
[Link] - Apuntes de PostgreSQL® para 22
profesionales
Capítulo 8: INSERTAR
Sección 8.1: Insertar datos utilizando COPY
COPY es el mecanismo de inserción masiva de PostgreSQL. Es una manera conveniente de transferir datos entre
archivos y tablas, pero también es mucho más rápido que INSERT cuando se agregan más de unos pocos miles de
filas a la vez.
Empecemos por crear un fichero de datos de muestra.
cat > samplet_data.csv
1,Yogesh
2,Raunak
3,Varun
4,Kamal
5,Hari
6,Amit
Y necesitamos una tabla de dos columnas en la que importar estos datos.
CREAR TABLA copy_test(id INT, NOMBRE varchar(8));
Ahora la operación de copia real, esto creará seis registros en la tabla.
COPY copy_test FROM '/ruta/a/archivo/muestra_datos.csv' DELIMITADOR ',';
En lugar de utilizar un archivo en disco, puede insertar datos desde STDIN
COPY copy_test FROM STDIN DELIMITADOR ',';
Introduzca los DATOS a copiar seguidos de una nueva
línea.
TERMINA CON una barra invertida Y un punto EN una
línea POR sí misma.
>> 7,Amol
>> 8,Amar
>> \.
TIEMPO: 85254,306 ms
id * FROM copy_test ;
| nombre
SELECT
----+--------
1 | Yogesh
3 | Varun
5 | Hari
7 | Amol
2 | Raunak
4 | Kamal
6 | Amit
8 | Amar
También puede copiar datos de una tabla a un archivo como se indica a continuación:
COPY copy_test TO 'ruta/al/archivo/muestra_datos.csv' DELIMITADOR ',';
Para más información sobre COPY, consulte aquí
[Link] - Apuntes de PostgreSQL® para 23
profesionales
Sección 8.2: Insertar varias filas
Puede insertar varias filas en la base de datos al mismo tiempo:
INSERT INTO persona (NOMBRE, edad) VALORES
('john doe', 25),
("Jane Doe", 20);
Sección 8.3: Datos INSERT y valores RETURING
Si está insertando datos en una tabla con una columna de autoincremento y si desea obtener el valor de
la columna de autoincremento.
Digamos que tienes una tabla llamada mi_tabla:
CREAR TABLA mi_tabla
(
id serial NOT NULL, -- el tipo de datos serie es un entero de cuatro bytes de incremento automático
NOMBRE CARÁCTER VARIABLE,
número_de_contacto INTEGER,
CONSTRAINT mi_tabla_clave PRIMARY KEY (id)
);
Si quieres insertar datos en mi_tabla y obtener el id de esa fila:
INSERT INTO mi_tabla(NOMBRE, numero_contacto) VALUES ( 'USUARIO', 8542621) RETURNING id;
La consulta anterior devolverá el id de la fila en la que se ha insertado el nuevo registro.
Sección 8.4: INSERT básico
Supongamos que tenemos una tabla simple llamada persona:
CREAR TABLA persona (
person_id BIGINT,
NOMBRE
VARCHAR(255).
edad INT,
ciudad VARCHAR(255)
);
La inserción más básica consiste en insertar todos los valores de la tabla:
INSERT INTO persona VALUES (1, 'john doe', 25, 'nueva york');
Si sólo desea insertar determinadas columnas, deberá indicar explícitamente cuáles:
INSERT INTO persona (NOMBRE, edad) VALUES ('john doe', 25);
Tenga en cuenta que si existen restricciones en la tabla, como NOT NULL, deberá incluir esas columnas en
ambos casos.
Sección 8.5: Insertar desde select
Puede insertar datos en una tabla como resultado de una sentencia select:
[Link] - Apuntes de PostgreSQL® para 24
profesionales
INSERT INTO persona SELECT * FROM tmp_persona WHERE edad < 30;
Tenga en cuenta que la proyección de la selección debe coincidir con las columnas necesarias para la inserción. En este
caso, la columna tmp_persona
tiene las mismas columnas que persona.
Sección 8.6: UPSERT - INSERT ... ON CONFLICT DO UPDATE..
desde la versión 9.5 postgres ofrece la funcionalidad UPSERT con la sentencia INSERT.
Supongamos que tenemos una tabla llamada mi_tabla, creada en varios ejemplos anteriores. Insertamos una fila,
devolviendo el valor PK de la fila insertada:
b=# INSERT INTO mi_tabla (nombre,numero_contacto) values ('uno',333) RETURNING
id; id
2
(1 fila)
INSERTAR 0 1
Ahora, si intentamos insertar una fila con una clave única existente, se producirá una excepción:
b=# INSERT INTO mi_tabla VALUES (2,'uno',333);
ERROR: duplicate KEY VALUE violates UNIQUE CONSTRAINT "my_table_pkey"
DETALLE: KEY (id)=(2) already EXISTS.
La funcionalidad Upsert ofrece la posibilidad de insertarlo de todos modos, resolviendo el conflicto:
b=# INSERT INTO mi_tabla values (2,'uno',333) ON CONFLICT (id) DO UPDATE SET nombre =
mi_tabla.nombre|||' cambiado a: "dos" en '||now() volviendo *;
id | nombre| número_de_contacto
----+---------------------------------------------------------------------------------------------
--------------+----------------
2 | uno cambiado a: "dos" en 2016-11-23 08:32:17.105179+00 | 333
(1 fila)
INSERTAR 0 1
Sección 8.7: SELECCIONAR datos en un fichero
Puede COPIAR la tabla y pegarla en un archivo.
postgres=# select * from mi_tabla;
c1 | c2 | c3
----+----+----
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
4 | 4 | 4
5 | 5 |
(5 filas)
postgres=# copy my_table to '/home/postgres/my_table.txt' using delimiters '|' with null as
'null_string' csv header;
COPIA 5
[Link] - Apuntes de PostgreSQL® para 25
profesionales
postgres=# ¡\! cat mi_tabla.txt
c1|c2|c3
1|1|1
2|2|2
3|3|3
4|4|4
5|5|null_string
[Link] - Apuntes de PostgreSQL® para 26
profesionales
Capítulo 9: ACTUALIZACIÓN
Apartado 9.1: Actualización de una tabla a partir de la unión con
otra tabla
También puede actualizar los datos de una tabla basándose en los datos de otra tabla:
ACTUALIZAR persona
SET código_estado = ciudades.código_estado
DESDE las ciudades
WHERE [Link] = ciudad;
Aquí estamos uniendo la columna ciudad de la persona con la columna ciudad de las ciudades para
obtener el código de estado de la ciudad. A continuación, se utiliza para actualizar la columna state_code de la
tabla person.
Sección 9.2: Actualizar todas las filas de una tabla
Usted actualiza todas las filas de la tabla simplemente proporcionando un nombre_columna = VALOR:
UPDATE persona SET planeta = 'Tierra';
Sección 9.3: Actualizar todas las filas que cumplen una condición
UPDATE persona SET estado = 'NY' WHERE ciudad = 'Nueva York';
Sección 9.4: Actualización de varias columnas en una tabla
Puede actualizar varias columnas de una tabla en la misma sentencia, separando los pares col=val con comas:
ACTUALIZAR persona
SET country = 'USA',
state = 'NY'
WHERE ciudad = 'Nueva York';
[Link] - Apuntes de PostgreSQL® para 27
profesionales
Capítulo 10: Soporte JSON
JSON - Java Script Object Notation , Postgresql soporta el tipo de datos JSON desde la versión 9.2. Hay algunas funciones
predefinidas y operadores para acceder a los datos JSON. El operador -> devuelve la clave de la columna JSON. El
operador ->> devuelve el valor de la columna JSON.
Sección 10.1: Uso de operadores JSONb
Creación de una base de datos y una tabla
DROP DATABASE IF EXISTS books_db;
CREATE DATABASE books_db WITH ENCODING='UTF8' TEMPLATE template0;
DROP TABLE IF EXISTS libros;
CREAR TABLA libros (
id SERIAL PRIMARY KEY,
cliente TEXT NOT NULL,
DATA JSONb NOT NULL
);
Rellenar la base de datos
INSERT INTO books(client, DATA) VALUES (
'Joe',
'{ "título": "Siddhartha", "autor": { "first_name": "Herman", "last_name": "Hesse" } }'
),(
"Jenny",
'{ "title": "Dharma Bums", "author": { "first_name": "Jack", "last_name": "Kerouac" } }'
),(
"Jenny",
'{ "title": "100 años de soledad", "author": { "first_name": "Gabo", "apellido": "Marquéz" }
}'
);
Veamos todo lo que hay dentro de los libros de mesa:
SELECT * FROM libros;
Salida:
El operador -> devuelve valores de columnas JSON
Seleccionar 1 columna:
SELECCIONAR cliente,
DATA->'title' COMO título
DE libros;
Salida:
[Link] - Apuntes de PostgreSQL® para 28
profesionales
Seleccionar 2 columnas:
SELECCIONAR
cliente,
DATA->'title' COMO título, DATA->'author' COMO autor
DE libros;
Salida:
-> vs ->>
El operador -> devuelve el tipo JSON original (que puede ser un objeto), mientras que ->> devuelve texto.
Devuelve objetos NESTED
Puede utilizar el -> para devolver un objeto anidado y así encadenar los operadores:
SELECCIONAR
cliente,
DATA->'autor'->'apellido' COMO autor
DE libros;
Salida:
Filtrado
Seleccione filas basándose en un valor dentro de su JSON:
SELECCIONE
cliente,
DATA->'title' COMO título
DE libros
WHERE DATA->'title' = '"Dharma Bums"';
Fíjate que WHERE usa -> por lo que debemos comparar con JSON '"Dharma Bums"'
O podríamos usar ->> y comparar con 'Dharma Bums'
Salida:
[Link] - Apuntes de PostgreSQL® para 29
profesionales
Filtrado anidado
Buscar filas basándose en el valor de un objeto JSON anidado:
SELECCIONE
cliente,
DATA->'title' COMO título
DE libros
WHERE DATOS->'autor'->>'apellido' = 'Kerouac';
Salida:
Un ejemplo del mundo real
CREAR TABLA events (
NAME varchar(200),
visitor_id varchar(200),
properties json,
navegador json
);
Vamos a almacenar eventos en esta tabla, como pageviews. Cada evento tiene propiedades, que pueden ser
cualquier cosa (por ejemplo, la página actual) y también envía información sobre el navegador (como el sistema
operativo, resolución de pantalla, etc). Ambos son completamente libres y podrían cambiar con el tiempo (a
medida que pensamos en cosas adicionales para rastrear).
INSERT INTO events (NAME, visitor_id, properties, browser) VALUES
(
pageview', '1', '{
"page": "/" }',
'{ "nombre": "Chrome", "os": "Mac", "resolución": { "x": 1440, "y": 900 } }'
),(
pageview', '2', '{
"page": "/" }',
'{ "nombre": "Firefox", "os": "Windows", "resolución": { "x": 1920, "y": 1200 } }'
),(
'pageview', '1',
'{ "página": "/cuenta" }',
'{ "nombre": "Chrome", "os": "Mac", "resolución": { "x": 1440, "y": 900 } }'
),(
'compra', '5',
'{ "importe": 10 }',
'{ "nombre": "Firefox", "os": "Windows", "resolución": { "x": 1024, "y": 768 } }'
),(
"compra", "15",
'{ "importe": 200 }',
'{ "nombre": "Firefox", "os": "Windows", "resolución": { "x": 1280, "y": 800 } }'
),(
"compra", "15",
'{ "importe": 500 }',
'{ "nombre": "Firefox", "os": "Windows", "resolución": { "x": 1280, "y": 800 } }'
[Link] - Apuntes de PostgreSQL® para 30
profesionales
);
[Link] - Apuntes de PostgreSQL® para 31
profesionales
Ahora vamos a seleccionarlo todo:
SELECT * FROM eventos;
Salida:
Operadores JSON + funciones agregadas PostgreSQL
Usando los operadores JSON, combinados con las funciones agregadas tradicionales de PostgreSQL, podemos
sacar lo que queramos. Tienes todo el poder de un RDBMS a tu disposición.
Veamos el uso del navegador:
SELECT navegador->>'nombre' AS navegador,
COUNT(navegador)
FROM eventos
GROUP BY navegador->>'nombre';
Salida:
Ingresos totales por visitante:
SELECT visitor_id, SUM(CAST(properties->>'amount' AS INTEGER)) COMO total
DESDE eventos
WHERE CAST(propiedades->>'importe' AS INTEGER) > 0
GROUP BY visitor_id;
Salida:
Resolución media de pantalla
SELECT AVG(CAST(browser->'resolution'->>'x' AS INTEGER)) AS width,
AVG(CAST(browser->'resolution'->>'y' AS INTEGER)) COMO altura
DE eventos;
Salida:
[Link] - Apuntes de PostgreSQL® para 32
profesionales
Más ejemplos y documentación aquí y aquí.
Sección 10.2: Consulta de documentos JSON complejos
Tomar un documento JSON complejo en una tabla:
CREAR TABLA mytable (DATOS JSONB NOT NULL);
CREATE INDEX mytable_idx ON mytable USING gin (DATA jsonb_path_ops);
INSERT INTO mytable VALUES($$
{
"name": "Alice",
"emails": [
"alice1@[Link]",
"alice2@[Link]"
],
"eventos": [
{
"tipo": "cumpleaños",
"date": "1970-01-01"
},
{
"tipo": "aniversario",
"fecha": "2001-05-05"
}
],
"ubicaciones": {
"casa": {
"ciudad": "Londres",
"país": "Reino Unido"
},
"trabajo": {
"ciudad": "Edimburgo",
"país": "Reino Unido"
}
}
}
$$);
Consulta de un elemento de nivel superior:
SELECT DATA->>'nombre' FROM mytable WHERE DATA @> '{"nombre": "Alicia"}';
Consulta de un elemento simple en una matriz:
SELECT DATA->>'nombre' FROM mytable WHERE DATA @> '{"emails":["alice1@[Link]"]}';
Consulta de un objeto en un array:
SELECT DATA->>'nombre' FROM mytable WHERE DATA @> '{"eventos":[{"tipo": "aniversario"}]}';
Consulta de un objeto anidado:
SELECT DATA->>'name' FROM mytable WHERE DATA @> '{"locations":{"home":{"city": "London"}}}';
[Link] - Apuntes de PostgreSQL® para 33
profesionales
Rendimiento de @> comparado con -> y ->>
Es importante comprender la diferencia de rendimiento entre utilizar @>, -> y ->> en la parte WHERE de la consulta.
Aunque estas dos consultas parecen ser equivalentes en términos generales:
SELECT DATA FROM mytable WHERE DATA @> '{"name": "Alice"}';
SELECT DATA FROM mytable WHERE DATA->'name' = '"Alice"';
SELECT DATA FROM mytable WHERE DATA->>'name' = 'Alice';
la primera sentencia utilizará el índice creado anteriormente, mientras que las dos últimas no, lo que requerirá un escaneo
completo de la tabla.
Aún se permite utilizar el operador -> al obtener datos resultantes, por lo que las siguientes consultas también
utilizarán el índice:
SELECT DATA->'locations'->'work' FROM mytable WHERE DATA @> '{"name": "Alice"}';
SELECT DATA->'locations'->'work'->>'city' FROM mytable WHERE DATA @> '{"name": "Alice"}';
Sección 10.3: Creación de una tabla JSON pura
Para crear una tabla JSON pura es necesario proporcionar un único campo con el tipo JSONB:
CREAR TABLA mytable (DATOS JSONB NOT NULL);
También debe crear un índice básico:
CREATE INDEX mytable_idx ON mytable USING gin (DATA jsonb_path_ops);
En este punto, puede insertar datos en la tabla y consultarla de forma eficaz.
[Link] - Apuntes de PostgreSQL® para 34
profesionales
Capítulo 11: Funciones agregadas
Apartado 11.1: Estadísticas simples: min(), max(), avg()
Para determinar algunas estadísticas simples de un valor en una columna de una tabla, puede utilizar una
función de agregado. Si tu tabla de individuos es:
Nombre Edad
Allie 17
Amanda 14
Alana 20
Podrías escribir esta sentencia para obtener el valor mínimo, máximo y medio:
SELECT MIN(edad), MAX(edad), AVG(edad)
DE particulares;
Resultado:
min max avg
14 20 17
Sección 11.2: regr_slope(Y, X) : pendiente de la ecuación
lineal de ajuste por mínimos cuadrados determinada por los
pares (X, Y)
Para ilustrar cómo usar regr_slope(Y,X), lo apliqué a un problema del mundo real. En Java, si no limpias bien la
memoria, la basura puede atascarse y llenar la memoria. Usted vuelca estadísticas cada hora sobre la utilización
de memoria de diferentes clases y lo carga en una base de datos postgres para su análisis.
Todos los candidatos a fugas de memoria tendrán una tendencia a consumir más memoria a medida que pasa el
tiempo. Si trazamos esta tendencia, nos imaginamos una línea que va hacia arriba y hacia la izquierda:
^
|
s | Leyenda:
i | * - punto de
z | datos
e | -- - tendencia
( |
b | *
y | --
t | --
e | * -- *
s | --
) | *-- *
| -- *
| -- *
--------------------------------------->
tiempo
Supongamos que tienes una tabla que contiene datos del histograma de volcado de memoria (un mapeo de clases con
la cantidad de memoria que consumen):
[Link] - Apuntes de PostgreSQL® para 35
profesionales
CREAR TABLA heap_histogram (
-- cuando se tomó el histograma del montón
histwhen TIMESTAMP SIN ZONA HORARIA NOT NULL,
-- el tipo de objeto al que se refieren los bytes
-- ej: [Link]
CARÁCTER DE CLASE VARIABLE NO NULO,
-- el tamaño en bytes utilizado por la clase anterior
bytes INTEGER NOT NULL
);
Para calcular la pendiente de cada clase, agrupamos por sobre la clase. La cláusula HAVING > 0 garantiza que
sólo obtengamos candidatos con una pendiente positiva (una línea que va hacia arriba y hacia la izquierda).
Ordenamos por la pendiente de forma descendente para obtener las clases con la mayor tasa de aumento de
memoria en la parte superior.
-- epoch devuelve segundos
SELECT CLASS, REGR_SLOPE(bytes,EXTRACT(epoch FROM histwhen)) AS slope
FROM public.heap_histogram
GRUPO POR CLASE
HAVING REGR_SLOPE(bytes,EXTRACT(epoch FROM histwhen)) > 0
ORDER BY pendiente DESC ;
Salida:
clase | pendi
ente
---------------------------+----------------------
[Link] | 71.7993806279174
[Link] | 49.0324576155785
[Link] | 31.7770770326123
[Link] | 23.2036817108056
[Link] | 20.9013528767851
A partir de la salida vemos que el consumo de memoria de [Link] es el que aumenta más rápidamente a
71.799 bytes por segundo y es potencialmente parte de la fuga de memoria.
Sección 11.3: string_agg(expresión, delimitador)
Puede concatenar cadenas separadas por un delimitador utilizando la función
STRING_AGG(). Si tu tabla de individuos es:
Nombre Edad País
Allie15 [Link].
Amanda 14 [Link].
Alana20 Rusia
Podrías escribir la sentencia SELECT ... GROUP BY para obtener los nombres de cada país:
SELECT STRING_AGG(NOMBRE, ', ') COMO NOMBRES, país
DE particulares
GROUP BY país;
Tenga en cuenta que debe utilizar una cláusula GROUP BY porque STRING_AGG() es una función agregada.
Resultado:
[Link] - Apuntes de PostgreSQL® para 36
profesionales
nombres país
Allie, Amanda USA
Alana Rusia
Más funciones agregadas de PostgreSQL descritas aquí
[Link] - Apuntes de PostgreSQL® para 37
profesionales
Capítulo 12: Expresiones comunes de tabla
(CON)
Sección 12.1: Expresiones de tabla comunes en consultas SELECT
Las expresiones comunes de tabla permiten extraer partes de consultas más amplias. Por ejemplo:
CON ventas COMO (
SELECCIONE
orders.ordered_at,
orders.user_id,
SUM([Link]) AS total
DE pedidos
GROUP BY pedidos.fecha_pedido, pedidos.id_usuario
)
SELECCIONE
[Link],
[Link],
[Link]
DE ventas
JOIN usuarios USING (user_id)
Sección 12.2: Recorrer el árbol utilizando WITH RECURSIVE
CREAR TABLA empl (
NOMBRE TEXTO CLAVE PRIMARIA,
jefe TEXT NULL
REFERENCIAS NOMBRE
EN CASCADA DE
ACTUALIZACIÓN EN
CASCADA DE
SUPRESIÓN
DEFAULT NULL
);
INSERT INTO empl VALUES ('Paul',NULL);
INSERT INTO empl VALUES ('Luke','Paul');
INSERT INTO empl VALUES ('Kate','Paul');
INSERT INTO empl VALUES ('Marge','Kate');
INSERT INTO empl VALUES ('Edith','Kate');
INSERT INTO empl VALUES ('Pam','Kate');
INSERT INTO empl VALUES ('Carol','Luke');
INSERT INTO empl VALUES ('John','Luke');
INSERT INTO empl VALUES ('Jack','Carol');
INSERT INTO empl VALUES ('Alex','Carol');
WITH RECURSIVE t(NIVEL,ruta,jefe,NOMBRE) AS (
SELECT 0,NAME,boss,NAME FROM empl WHERE boss IS NULL
UNION
SELECCIONE
NIVEL + 1,
path || ' > ' || [Link],
[Link],
[Link]
DESDE
empl JOIN t
ON [Link] = [Link]
) SELECT * FROM t ORDER BY ruta;
[Link] - Apuntes de PostgreSQL® para 38
profesionales
Capítulo 13: Funciones de ventana
Sección 13.1: ejemplo genérico
Preparación de los datos:
CREATE TABLE wf_example(i INT, t TEXT,ts timestamptz,b BOOLEAN);
INSERT INTO wf_example SELECT 1,'a','1970.01.01',TRUE;
INSERT INTO wf_example SELECT 1,'a','1970.01.01',FALSE;
INSERT INTO wf_example SELECT 1,'b','1970.01.01',FALSE;
INSERT INTO wf_example SELECT 2,'b','1970.01.01',FALSE;
INSERT INTO wf_example SELECT 3,'b','1970.01.01',FALSE;
INSERT INTO wf_example SELECT 4,'b','1970.02.01',FALSE;
INSERT INTO wf_example SELECT 5,'b','1970.03.01',FALSE;
INSERT INTO wf_example SELECT 2,'c','1970.03.01',TRUE;
Corriendo:
SELECCIONAR *
DENSE_RANK() OVER (ORDER BY i) dist_by_i
LAG(t) OVER () prev_t
NTH_VALUE(i, 6) OVER () nth
COUNT(TRUE) OVER (PARTITION BY i) num_by_i
COUNT(TRUE) OVER () num_all
, NTILE(3) over() ntile
FROM wf_example
;
Resultado:
i | t | ts | b | dist_by_i | prev_t | nth | num_by_i | num_all | ntile
---+---+------------------------+---+-----------+--------+-----+----------+---------+-------
1 | a | 1970-01-01 00:00:00+01 | f | 1 | | 3 | 3 | 8 | 1
1 | a | 1970-01-01 00:00:00+01 | t | 1 | a | 3 | 3 | 8 | 1
1 | b | 1970-01-01 00:00:00+01 | f | 1 | a | 3 | 3 | 8 | 1
2 | c | 1970-03-01 00:00:00+01 | t | 2 | b | 3 | 2 | 8 | 2
2 | b | 1970-01-01 00:00:00+01 | f | 2 | c | 3 | 2 | 8 | 2
3 | b | 1970-01-01 00:00:00+01 | f | 3 | b | 3 | 1 | 8 | 2
4 | b | 1970-02-01 00:00:00+01 | f | 4 | b | 3 | 1 | 8 | 3
5 | b | 1970-03-01 00:00:00+01 | f | 5 | b | 3 | 1 | 8 | 3
(8
filas)
Explicación:
dist_por_i: DENSE_RANK() OVER (ORDER BY i) es como un número_de_filas por valores distintos. Se puede utilizar
para el número de valores distintos de i (COUNT(DISTINCT i) no funcionaría). Sólo tiene que utilizar el valor máximo.
prev_t: LAG(t) OVER () es un valor anterior de t sobre toda la ventana. ten en cuenta que es nulo para la primera fila.
nth: NTH_VALUE(i, 6) OVER () es el valor de la sexta fila columna i sobre toda la ventana
num_by_i: COUNT(TRUE) OVER (PARTITION BY i) es una cantidad de filas para cada
valor de i num_all: COUNT(TRUE) OVER ( ) es una cantidad de filas sobre toda la ventana
ntile: NTILE(3) over() divide toda la ventana en 3 partes (en lo posible) iguales en cantidad
[Link] - Apuntes de PostgreSQL® para 39
profesionales
Sección 13.2: valores de columna vs dense_rank vs rank vs
row_number
aquí puedes encontrar las funciones.
Con la tabla wf_ejemplo creada en el ejemplo anterior, ejecute:
SELECCIONE i
DENSE_RANK() OVER (ORDER BY i)
, ROW_NUMBER() SOBRE ()
RANK() OVER (ORDER BY i)
FROM wf_example
El resultado es:
i | dense_rank | row_number | rank
---+------------+------------+------
1 | 1 | 1 | 1
1 | 1 | 2 | 1
1 | 1 | 3 | 1
2 | 2 | 4 | 4
2 | 2 | 5 | 4
3 | 3 | 6 | 6
4 | 4 | 7 | 7
5 | 5 | 8 | 8
dense_rank ordena los valores de i por su aparición en la ventana. i=1 aparece, por lo que la primera fila
tiene dense_rank, el siguiente y tercer valor de i no cambia, por lo que es dense_rank muestra 1 - PRIMER
valor no cambiado. cuarta fila i=2, es el segundo valor de i encontrado, por lo que dense_rank muestra 2, y
así para la siguiente fila. Luego se encuentra con el valor i=3 en la 6ª fila, por lo que muestra 3. Lo mismo
para el resto de los dos valores de i. Así que el último valor de dense_rank es el número de valores distintos
de i.
row_number ordena las FILAS a medida que se enumeran.
rank No confundir con dense_rank esta función ordena el NÚMERO DE FILAS de los valores i. Así que
empieza igual con tres unos, pero tiene el siguiente valor 4, lo que significa que i=2 (nuevo valor) se
encontró en la fila 4. El mismo i=3 se encontró en la fila 6. Etc..
[Link] - Apuntes de PostgreSQL® para 40
profesionales
Capítulo 14: Consultas recursivas
No hay consultas recursivas reales.
Sección 14.1: Suma de números enteros
CON RECURSIVO t(n) COMO (
VALORES (1)
UNIÓN TODOS
SELECT n+1 FROM t WHERE n < 100
)
SELECT SUM(n) FROM t;
Enlace a la documentación
[Link] - Apuntes de PostgreSQL® para 41
profesionales
Capítulo 15: Programación con PL/pgSQL
Sección 15.1: Función PL/pgSQL básica
Una simple función PL/pgSQL:
CREAR FUNCIÓN active_subscribers() DEVUELVE BIGINT COMO $$
DECLARE
-- variable para el siguiente bloque BEGIN ... END bloque
abonados INTEGER;
BEGIN
-- SELECT debe utilizarse siempre con INTO
SELECT COUNT(user_id) INTO suscriptores FROM usuarios WHERE suscritos;
-- resultado de la función
RETURN abonados;
EXCEPTION
-- devuelve NULL si la tabla "usuarios" no existe
WHEN undefined_table
ENTONCES DEVUELVE
NULL; FIN;
$$ LANGUAGE plpgsql;
Esto se podría haber conseguido sólo con la sentencia SQL, pero demuestra la estructura básica de una
función. Para ejecutar la función haga:
SELECT suscriptores_activos();
Sección 15.2: excepciones personalizadas
creando excepción personalizada 'P2222':
CREATE OR REPLACE FUNCTION s164() RETURNS void AS
$$
COMENZAR
lanzar excepción USING message = 'S 164', detail = 'D 164', hint = 'H 164', errcode = 'P2222';
FIN;
$$ LANGUAGE plpgsql
;
crear excepción personalizada no asignar errm:
CREATE OR REPLACE FUNCTION s165() RETURNS void AS
$$
COMENZAR
lanzar excepción '%','nada especificado';
FIN;
$$ LANGUAGE plpgsql
;
llamando:
t=# DO
$$
DECLARE
_t TEXTO;
BEGIN
[Link] - Apuntes de PostgreSQL® para 42
profesionales
realiza s165();
exception WHEN SQLSTATE 'P0001' THEN raise info '%','estado P0001 capturado: '||SQLERRM;
perform s164();
FIN;
$$
;
INFO: estado P0001 capturado: NADA especificado
ERROR: S 164
DETALLE: D 164
SUGERENCIA: H 164
CONTEXTO: DECLARACIÓN SQL "SELECT s164()"
PL/pgSQL FUNCTION inline_code_block línea 7 AT PERFORM
aquí personalizado P0001 procesado, y P2222, no, abortando la ejecución.
También tiene mucho sentido mantener una tabla de excepciones, como aquí:
[Link]
Sección 15.3: Sintaxis PL/pgSQL
CREATE [OR REPLACE] FUNCTION functionName (someParameter 'parameterType')
DEVUELVE 'DATATYPE
AS $_nombre_bloque_$
DECLARE
--declarar algo
COMENZAR
--hacer algo
--devolver algo
FIN;
$_nombre_del_bloque
LANGUAGE plpgsql;
Sección 15.4: Bloque DEVOLUCIONES
Opciones para devolver en una función PL/pgSQL:
Tipo de datos Lista de todos los tipos de
datos Tabla(nombre_columna
tipo_columna, ...) SETOF 'Tipo_datos'
OR 'columna_tabla'
[Link] - Apuntes de PostgreSQL® para 43
profesionales
Capítulo 16: Herencia
Sección 16.1: Creación de tablas de hijos
CREATE TABLE users (username TEXT, email TEXT);
CREATE TABLE simple_users () INHERITS (users);
CREATE TABLE usuarios_con_contraseña (CONTRASEÑA TEXTO) INHERITS (usuarios);
Nuestras tres tablas tienen este aspecto:
usuarios
Tipo de
columna
nombre_usuario
texto emailtext
simple_users
Column Type
username text
email texto
users_with_password
Columna Tipo nombre
de usuario texto
correo
electrónico
text
o contraseña
texto
[Link] - Apuntes de PostgreSQL® para 44
profesionales
Capítulo 17: Exportar la cabecera y los datos
de la tabla de la base de datos PostgreSQL a
un archivo CSV
Desde la herramienta de administracion Adminer tiene la opcion de exportar a archivo csv para base de datos
mysql pero no esta disponible para base de datos postgresql. Aquí voy a mostrar el comando para exportar
CSV para base de datos postgresql.
Sección 17.1: copia de la consulta
COPY (SELECT oid,relname FROM pg_class LIMIT 5) TO STDOUT;
Sección 17.2: Exportar tabla PostgreSQL a csv con cabecera
para alguna(s) columna(s)
COPY products(is_public, title, discount) TO 'D:\csv_backup\products_db.csv' DELIMITER ',' CSV
HEADER;
COPY categories(NAME) TO 'D:\csv_backup\categories_db.csv' DELIMITER ',' CSV HEADER;
Sección 17.3: Copia de seguridad de tabla completa a csv con
cabecera
COPY products TO 'D:\csv_backup\products_db.csv' DELIMITER ',' CSV HEADER;
COPY categories TO 'D:\csv_backup\categories_db.csv' DELIMITER ',' CSV HEADER;
[Link] - Apuntes de PostgreSQL® para 45
profesionales
Capítulo 18: Disparadores y funciones
disparadoras
El disparador se asociará a la tabla o vista especificada y ejecutará la función especificada nombre_función
cuando se produzcan determinados eventos.
Apartado 18.1: Tipo de activadores
Se puede especificar el disparador para disparar:
ANTES de que se intente la operación en una fila: insertar, actualizar o eliminar;
DESPUÉS de que se haya completado la operación: insertar, actualizar o eliminar;
EN LUGAR DE la operación en el caso de inserciones, actualizaciones o eliminaciones en una vista.
Disparador que se marca:
FOR EACH ROW se llama una vez por cada fila que la operación modifica;
FOR EACH STATEMENT se llama onde para cualquier operación dada.
CREAR TABLA empresa (
idSERIAL PRIMARY KEY NOT NULL,
NOMBRE TEXTO NOT NULL,
created_at TIMESTAMP,
modified_at TIMESTAMP DEFAULT NOW()
)
CREAR TABLA log (
id SERIAL PRIMARY KEY NOT NULL,
table_name TEXT NOT NULL,
table_id TEXT NOT NULL,
description TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
)
Preparación para ejecutar ejemplos
Gatillo de inserción simple
CREATE OR REPLACE FUNCTION add_created_at_function()
DEVUELVE TRIGGER COMO $BODY
COMENZAR
NEW.created_at := NOW();
RETURN NEW;
FIN $BODY
LANGUAGE plpgsql;
Paso 1: cree su función
Paso 2: cree su activador
CREAR TRIGGER add_created_at_trigger
ANTES DE INSERTAR
Empresa ON
PARA CADA FILA
EJECUTAR PROCEDIMIENTO add_created_at_function();
[Link] - Apuntes de PostgreSQL® para 46
profesionales
Paso 3: pruébelo
INSERT INTO empresa (NOMBRE) VALUES ('Mi empresa');
SELECT * FROM empresa;
Disparador para múltiples
propósitos Paso 1: cree su
función
[Link] - Apuntes de PostgreSQL® para 47
profesionales
CREATE OR REPLACE FUNCTION add_log_function()
DEVUELVE TRIGGER COMO $BODY
DECLARE
vDescription TEXT;
vId INT;
vVolver RECORD;
COMENZAR
vDescription := TG_TABLE_NAME || ' ';
IF (TG_OP = 'INSERTAR') THEN
vId := [Link];
vDescription := vDescription || 'añadido. Id: ' ||
vId; vReturn := NEW;
ELSIF (TG_OP = 'UPDATE') THEN
vId := [Link];
vDescription := vDescription || 'actualizado. Id: ' || vId;
vReturn := NEW;
ELSIF (TG_OP = 'DELETE') THEN
vId := [Link];
vDescription := vDescription || 'borrado. Id: ' || vId;
vReturn := OLD;
END IF;
RAISE NOTICE 'TRIGER activado en % - Log: %', TG_TABLE_NAME, vDescription;
INSERT INTO registro
(nombre_tabla, id_tabla, descripción, fecha_creación)
VALORES
(TG_TABLE_NAME, vId, vDescription, NOW());
RETURN vReturn;
FIN $BODY
LANGUAGE plpgsql;
Paso 2: cree su activador
CREATE TRIGGER add_log_trigger
DESPUÉS DE INSERTAR, ACTUALIZAR O ELIMINAR
Empresa ON
PARA CADA FILA
EJECUTAR PROCEDIMIENTO add_log_function();
INSERT INTO empresa (NOMBRE) VALUES ('Empresa
1'); INSERT INTO empresa (NOMBRE) VALUES
('Empresa 2'); INSERT INTO empresa (NOMBRE)
VALUES ('Empresa 3');
UPDATE company SET NAME='Empresa nueva 2' WHERE NAME='Empresa 2';
DELETE FROM empresa WHERE NAME='Empresa 1';
SELECT * FROM log;
Paso 3: pruébelo
Sección 18.2: Función básica de activación PL/pgSQL
Se trata de una sencilla función de activación.
CREAR O SUSTITUIR FUNCIÓN my_simple_trigger_function()
DEVUELVE TRIGGER COMO
$BODY$
COMENZAR
[Link] - Apuntes de PostgreSQL® para 48
-- TG_TABLE_NAME :nombre de la tabla que ha provocado la invocación del trigger
profesionales
IF (TG_TABLE_NAME = 'users') THEN
--TG_OP : operación en la que se disparó el disparador
IF (TG_OP = 'INSERTAR') THEN
--[Link] contiene el valor de la nueva fila de la base de datos (en este caso id es la columna id de la
tabla users)
--NEW devolverá null para las operaciones DELETE
INSERT INTO log_table (date_and_time, description) VALUES (NOW(), 'Nuevo usuario insertado. ID
de usuario: '|| [Link]);
DEVOLUCIÓN NUEVO;
ELSIF (TG_OP = 'DELETE') THEN
--[Link] contiene el valor de la antigua fila de la base de datos (en este caso id es la columna id de la
tabla users)
--OLD devolverá null para las operaciones INSERT
INSERT INTO log_table (fecha_y_hora, descripción) VALUES (NOW(), 'Usuario eliminado.. ID de
usuario: ' ||
[Link]);
RETURN OLD;
END IF;
RETURN NULL;
END IF;
FIN;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Añadir esta función de activación a la tabla de usuarios
CREAR TRIGGER mi_disparador
DESPUÉS DE INSERTAR O ELIMINAR
Usuarios ON
PARA CADA FILA
EJECUTAR PROCEDIMIENTO my_simple_trigger_function();
[Link] - Apuntes de PostgreSQL® para 49
profesionales
Capítulo 19: Activadores de eventos
Los disparadores de eventos se activarán cada vez que se produzca un evento asociado a ellos en la base de datos.
Sección 19.1: Registro de eventos de inicio de comandos DDL
Tipo de evento
DDL_COMMAND_START
DDL_COMMAND_END
SQL_DROP
Este es un ejemplo para crear un Activador de Eventos y registrar eventos DDL_COMMAND_START.
CREATE TABLE TAB_EVENT_LOGS(
DATE_TIME TIMESTAMP,
EVENT_NAME TEXT,
TEXTO DE OBSERVACIONES
);
CREAR O SUSTITUIR LA FUNCIÓN FN_LOG_EVENT()
DEVUELVE EVENT_TRIGGER
LENGUAJE SQL
AS
$main$
INSERT INTO FICHA_REGISTROS_EVENTOS(FECHA_HORA,NOMBRE_EVENTO,OBSERVACIONES)
VALUES(NOW(),TG_TAG,'Registro de eventos');
$main$;
CREAR EVENTO TRIGGER TRG_LOG_EVENT EN DDL_COMMAND_START
EJECUTAR PROCEDIMIENTO FN_LOG_EVENT();
[Link] - Apuntes de PostgreSQL® para 50
profesionales
Capítulo 20: Gestión de funciones
Sección 20.1: Crear un usuario con contraseña
Generalmente deberías evitar usar el rol por defecto de la base de datos (a menudo postgres) en tu aplicación.
En su lugar, deberías crear un usuario con niveles más bajos de privilegios. Aquí creamos uno llamado
niceusername y le damos una contraseña muy-fuerte-PASSWORD
CREATE ROLE niceusername WITH PASSWORD 'very-strong-password' LOGIN;
El problema con eso es que las consultas escritas en la consola psql se guardan en un archivo de historial
.psql_history en el directorio personal del usuario y también pueden ser registradas en el registro del servidor
de base de datos PostgreSQL, exponiendo así la contraseña.
Para evitarlo, utilice el comando \PASSWORD para establecer la contraseña del usuario. Si el usuario que emite el
comando es un superusuario, no se le preguntará la contraseña actual. (Debe ser superusuario para modificar las
contraseñas de los superusuarios)
CREAR ROLE niceusername CON LOGIN;
\PASSWORD niceusername
Sección 20.2: Concesión y revocación de privilegios
Supongamos que tenemos tres usuarios :
1. El administrador de la base de datos > admin
2. La aplicación con un acceso completo para sus datos > read_write
3. El acceso de sólo lectura > read_only
--ACCESO A LA BASE DE DATOS
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT CONNECT ON DATABASE nova TO USER;
Con las consultas anteriores, los usuarios que no sean de confianza ya no podrán conectarse a la base de datos.
--ESQUEMA DE ACCESO
REVOKE ALLON SCHEMA public FROM PUBLIC;
CONCEDER USO ON SCHEMA public TO USER;
El siguiente conjunto de consultas revoca todos los privilegios de los usuarios no autenticados y proporciona un conjunto
limitado de privilegios para los usuarios no autenticados.
usuario read_write.
--TABLAS DE ACCESO
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
SELECT ON ALLTABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write
;GRANT ALL ON ALLTABLES IN SCHEMA public TO ADMIN ;
--SECUENCIAS DE ACCESO
REVOKE ALLON ALL SEQUENCES IN SCHEMA public FROM PUBLIC;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO read_only; -- permite el uso de CURRVAL
GRANT UPDATE ON ALL SEQUENCES IN SCHEMA public TO read_write; -- permite el uso de NEXTVAL y
SETVAL
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO read_write; -- permite el uso de CURRVAL y
[Link]
NEXTVAL - Apuntes de PostgreSQL® para 51
profesionales
CONCEDER TODAS LAS SECUENCIAS DEL SCHEMA public A ADMIN;
Sección 20.3: Crear una base de datos de roles y
correspondencias
Para dar soporte a una aplicación determinada, a menudo se crea un nuevo rol y
una base de datos a juego. Los comandos shell a ejecutar serían estos:
$ CREATEUSER -P blogger
Introduzca la contraseña para el nuevo
rol: ******** Introdúzcala de nuevo:
********
$ CREATEDB -O blogger blogger
Esto supone que se ha configurado correctamente pg_hba.conf, que probablemente tenga este aspecto:
# TIPO BASE DE USUARIO DIRECCIÓN MÉTODO
DATOS
host sameuser TODOS localhost md5
LOCAL sameuser TODOS md5
Sección 20.4: Alterar search_path por defecto del usuario
Con los siguientes comandos, se puede establecer el search_path por defecto del usuario.
1. Compruebe la ruta de búsqueda antes de establecer el esquema por defecto.
postgres=# \c postgres usuario1
Ahora está conectado A LA BASE DE DATOS "postgres" COMO
USUARIO "user1". postgres=> SHOW search_path;
camino_buscado
"$usuario",publ
ic (1 FILA)
2. Establezca search_path con el comando ALTER USER para añadir un nuevo esquema my_schema
postgres=> \c postgres postgres
Ahora está conectado A LA BASE DE DATOS "postgres" COMO USUARIO
"postgres". postgres=# ALTER USER user1 SET search_path='my_schema,
"$user", public'; ALTER ROLE
3. Compruebe el resultado tras la ejecución.
postgres=# \c postgres usuario1
CONTRASEÑA PARA USUARIO user1:
Ahora está conectado A LA BASE DE DATOS "postgres" COMO
USUARIO "user1". postgres=> SHOW search_path;
camino_buscado
mi_esquema, "$usuario",
public (1 FILA)
Alternativa:
[Link] - Apuntes de PostgreSQL® para 52
profesionales
postgres=# SET ROLE user1;
postgres=# SHOW search_path;
camino_buscado
mi_esquema, "$usuario",
public (1 FILA)
[Link] - Apuntes de PostgreSQL® para 53
profesionales
Sección 20.5: Crear usuario de sólo lectura
CREATE USER readonly WITH ENCRYPTED PASSWORD 'yourpassword';
GRANT CONNECT ON DATABASE <nombre_de_base_de_datos> TO readonly;
GRANT USAGE ON SCHEMA public TO readonly;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
Sección 20.6: Conceder privilegios de acceso a objetos creados en
el futuro
Supongamos que tenemos tres usuarios :
1. El administrador de la base de datos > ADMIN
2. La aplicación con un acceso completo para sus datos > read_write
3. El acceso de sólo lectura > read_only
Con las siguientes consultas, puede establecer privilegios de acceso en objetos creados en el futuro en el esquema
especificado.
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT EN TABLAS A
sólo lectura;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT,INSERT,DELETE,UPDATE ON TABLES TO
lectura_escritura;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT ALLON TABLES TO
ADMIN;
O bien, puede establecer privilegios de acceso en objetos creados en el futuro por el usuario especificado.
ALTER DEFAULT PRIVILEGES FOR ROLE ADMIN GRANT SELECT ON TABLES TO read_only;
[Link] - Apuntes de PostgreSQL® para 54
profesionales
Capítulo 21: Funciones criptográficas de
Postgres
En Postgres, las funciones criptográficas pueden ser desbloqueadas usando el módulo pgcrypto. CREAR EXTENSIÓN
pgcrypto;
Sección 21.1: resumen
Las funciones DIGEST() generan un hash binario de los datos dados. Puede utilizarse para crear un hash
aleatorio. Uso: digest(DATA TEXT, TYPE TEXT) DEVUELVE BYTEA
O: digest(DATA BYTEA, TYPE TEXT) RETURNS BYTEA
Ejemplos:
SELECT DIGEST('1', 'sha1')
SELECT DIGEST(CONCAT(CAST(CURRENT_TIMESTAMP AS TEXT), RANDOM()::TEXT), 'sha1')
[Link] - Apuntes de PostgreSQL® para 55
profesionales
Capítulo 22: Comentarios en PostgreSQL
El objetivo principal de COMMMENT es definir o modificar un comentario sobre un objeto de la base de datos.
En cualquier objeto de base de datos sólo se puede dar un único comentario (cadena). COMENTARIO nos
ayudará a saber lo que para el objeto de base de datos en particular se ha definido lo que su propósito real es.
La regla para COMENTAR SOBRE EL ROL es que debes ser superusuario para comentar sobre un rol de superusuario, o
tener el atributo
CREATEROLE para comentar roles de no superusuario. Por supuesto, un superusuario puede comentar cualquier cosa
Sección 22.1: COMENTARIO sobre la tabla
COMMENT ON TABLE nombre_tabla ES 'esta es la tabla de detalles del estudiante';
Sección 22.2: Eliminar comentario
COMMENT ON TABLE student IS NULL;
El comentario se eliminará con la ejecución de la declaración anterior.
[Link] - Apuntes de PostgreSQL® para 56
profesionales
Capítulo 23: Copia de seguridad y
restauración
Sección 23.1: Copia de seguridad de una base de datos
pg_dump -Fc -f BASE_DATOS.pgsql BASE_DATOS
El -Fc selecciona el "formato de copia de seguridad personalizado" que le da más poder que SQL sin formato; ver
pg_restore para más detalles. Si desea un archivo SQL vainilla, puede hacer esto en su lugar:
pg_dump -f BASE_DATOS.sql BASE_DATOS
o incluso
pg_dump BASE_DATOS > BASE_DATOS.sql
Sección 23.2: Restaurar copias de seguridad
psql < [Link]
Una alternativa más segura utiliza -1 para envolver la restauración en una transacción. La opción -f especifica el
nombre del archivo en lugar de utilizar la redirección del shell.
psql -1f [Link]
Los archivos con formato personalizado deben restaurarse utilizando pg_restore con la opción -d para especificar la
base de datos:
pg_restore -d BASE DE DATOS [Link]
El formato personalizado también puede convertirse de nuevo a SQL:
pg_restore [Link] > [Link]
Se recomienda utilizar el formato personalizado porque puede elegir qué cosas restaurar y, opcionalmente, activar
el procesamiento paralelo.
Puede que necesite hacer un pg_dump seguido de un pg_restore si actualiza de una versión de postgresql a otra
más reciente.
Sección 23.3: Copia de seguridad de todo el cluster
$ pg_dumpall -f [Link]
Esto funciona entre bastidores estableciendo múltiples conexiones con el servidor, una por cada base de datos, y
ejecutando
pg_dump en él.
A veces, puedes tener la tentación de configurar esto como un trabajo cron, por lo que quieres ver la fecha en que
se tomó la copia de seguridad como parte del nombre del archivo:
$ postgres-backup-$(DATE
[Link] +%Y-%m-%d).sql
- Apuntes de PostgreSQL® para 57
profesionales
Sin embargo, tenga en cuenta que esto podría producir archivos de gran tamaño diariamente. Postgresql dispone
de un mecanismo mucho mejor para realizar copias de seguridad periódicas: los archivos WAL.
[Link] - Apuntes de PostgreSQL® para 58
profesionales
La salida de pg_dumpall es suficiente para restaurar una instancia Postgres configurada de forma idéntica, pero los
archivos de configuración en $PGDATA (pg_hba.conf y [Link]) no forman parte de la copia de
seguridad, por lo que tendrá que hacer una copia de seguridad de ellos por separado.
postgres=# SELECT pg_start_backup('mi-backup');
postgres=# SELECT pg_stop_backup();
Para realizar una copia de seguridad del sistema de archivos, debe utilizar estas funciones para asegurarse de que
Postgres se encuentra en un estado coherente mientras se prepara la copia de seguridad.
Sección 23.4: Uso de psql para exportar datos
Los datos pueden exportarse mediante el comando copy o utilizando las opciones de línea de comandos del comando
psql.
Para Exportar datos csv de usuario de tabla a archivo csv:
psql -p \<port> -U \<username> -d \<DATABASE> -A -F<DELIMITER> -c<sql A EJECUTAR> \> \<output
filename WITH path>
psql -p 5432 -U postgres -d base_de_datos_prueba -A -F, -c "select * from usuario" >
/home/USUARIO/datos_usuario.CSV
En este caso, la combinación de -A y -F es suficiente.
-F es para especificar el delimitador
-A O --no-align
Cambia al modo de salida no alineado. (Por lo demás, el modo de salida por defecto es alineado).
Apartado 23.5: Utilizar Copy para importar
Para copiar datos de un archivo CSV a una tabla
COPIAR <nombre de tabla> DE <nombre de fichero con ruta>';
Para insertar en la tabla USER desde un archivo llamado user_data.CSV colocado dentro de /home/USER/:
COPIAR USUARIO DE '/home/usuario/usuario_datos.csv';
Para copiar datos de un archivo separado en una tabla
COPIAR USUARIO DESDE '/home/usuario/usuario_datos' CON DELIMITADOR '|';
Nota: En ausencia de la opción CON DELIMITADOR, el delimitador por defecto es la coma ,
Para ignorar la línea de cabecera al importar el archivo
Utilice la opción Cabecera:
COPY USER FROM '/home/user/user_data' WITH DELIMITER '|' HEADER;
Nota: Si los datos están entrecomillados, por defecto los caracteres de entrecomillado de los datos son comillas dobles.
Si los datos se entrecomillan utilizando cualquier otro carácter, utilice la opción QUOTE; sin embargo, esta opción sólo
está permitida cuando se utiliza el formato CSV.
[Link] - Apuntes de PostgreSQL® para 59
profesionales
Sección 23.6: Utilizar Copiar para exportar
Para copiar la tabla en un o/p estándar
COPIAR <nombre_tabla> A STDOUT (DELIMITADOR '|');
Para exportar el usuario de la tabla a la salida estándar:
COPY USER TO STDOUT (DELIMITER '|'); Para copiar la tabla en un archivo
COPY USER FROM '/home/user/user_data' WITH DELIMITER '|'; Para copiar el resultado de la sentencia SQL
en un archivo COPY (sql STATEMENT) TO '<filename with path>'; COPY (SELECT * FROM USER WHERE
user_name LIKE 'A%') TO '/home/user/user_data'; Para copiar en un archivo comprimido
COPIAR USUARIO AL PROGRAMA 'gzip > /home/usuario/datos_usuario.gz';
Aquí se ejecuta el programa gzip para comprimir los datos de la tabla de usuario.
[Link] - Apuntes de PostgreSQL® para 60
profesionales
Capítulo 24: Script de backup para una BD
de producción
parámetro detalles
guardar_ El directorio principal de copia de seguridad
db El directorio secundario de copia de seguridad
FECHA La fecha de la copia de seguridad en el
dbProd formato especificado
dbprod El nombre de la base de datos que se va a
guardar
/opt/postgres/9.0/bin/pg_dump La ruta al binario pg_dump
Especifica el nombre de host de la máquina en la que se ejecuta el servidor, Ejemplo :
-h
localhost
Especifica el puerto TCP o la extensión de archivo de socket de dominio Unix
-p
local en el que el servidor está a la escucha de conexiones, Ejemplo 5432
-Nombre de usuario con el que conectarse.
Sección 24.1: [Link]
En general, solemos hacer copias de seguridad de la BD con el cliente pgAdmin. El siguiente es un script sh
utilizado para guardar la base de datos (bajo linux) en dos formatos:
Archivo SQL: para una posible reanudación de los datos en cualquier versión de PostgreSQL.
Archivo de volcado: para una versión superior a la actual.
#!/bin/sh
cd /guardar_db
#rm -R /guardar_db/*
DATE=$(fecha +%d-%m-%Y-%Hh%M)
echo -e "Sauvegarde de la base du ${DATE}"
mkdir prodDir${FECHA}
cd prodDir${FECHA}
archivo #dump
/opt/postgres/9.0/bin/pg_dump -i -h localhost -p 5432 -U postgres -F c -b -w -v -f
"dbprod${DATE}.backup" dbprod
Archivo #SQL
/opt/postgres/9.0/bin/pg_dump -i -h localhost -p 5432 -U postgres --format plain --verbose -f
"dbprod${DATE}.sql" dbprod
[Link] - Apuntes de PostgreSQL® para 61
profesionales
Capítulo 25: Acceso a datos mediante
programación
Sección 25.1: Acceso a PostgreSQL con la C-API
La C-API es la forma más potente de acceder a PostgreSQL y es sorprendentemente cómoda.
Compilación y enlace
Durante la compilación, tiene que añadir el directorio de inclusión de PostgreSQL, que se puede encontrar con
pg_config -- includedir, a la ruta de inclusión.
Debe enlazar con la biblioteca compartida del cliente PostgreSQL ([Link] en UNIX, [Link] en Windows). Esta
biblioteca se encuentra en el directorio de bibliotecas de PostgreSQL, que se puede encontrar con pg_config
--libdir.
Nota: Por razones históricas, la biblioteca se llama [Link] no [Link], que es una trampa popular para los
principiantes. Dado que el ejemplo de código de abajo está en el archivo coltype.c, la compilación y el enlace se
harían con
gcc -Wall -I "$(pg_config --includedir)" -L "$(pg_config --libdir)" -o coltype coltype.c -lpq
con el compilador GNU C (considere añadir -Wl,-rpath,"$(pg_config --libdir)" para añadir la ruta de búsqueda
de la biblioteca) o con
cl /MT /W4 /I <directorio de inclusión> coltype.c <ruta a [Link]>
en Windows con Microsoft Visual C.
[Link] - Apuntes de PostgreSQL® para 62
profesionales
Programa tipo
/* necesario para todos los programas cliente PostgreSQL, debe ser el primero */
#include <libpq-fe.h>
#include <stdio.h>
#include <string.h>
#ifdef TRACE
#define TRACEFILE "[Link]"
#endif
int main(int argc, char **argv) {
#ifdef TRACE
FILE *trc;
#endif
PGconn *conn;
PGresult *res;
int recuento filas, recuento columnas, i, j, primercol;
/* el tipo de parámetro debe ser adivinado por PostgreSQL */
const Oid paramTypes[1] = { 0 };
/* valor del parámetro */
const char * const paramValues[1] = { "pg_database" };
/*
* Si se utiliza una connectstring vacía, se usarán valores por defecto para todo.
* Si se establecen, las variables de entorno PGHOST, PGDATABASE, PGPORT y
* Se utilizará PGUSER.
*/
conn = PQconnectdb("");
[Link] - Apuntes de PostgreSQL® para 63
profesionales
/*
* Esto sólo puede ocurrir si no hay suficiente memoria
* para asignar la estructura PGconn.
*/
si (conn == NULL)
{
fprintf(stderr, "Out of memory connecting to PostgreSQL.\n");
return 1;
}
/* comprueba si el intento de conexión ha funcionado */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "%s\n", PQerrorMessage(conn));
/*
* Aunque la conexión haya fallado, la estructura PGconn ha sido
* asignado y debe ser liberado.
*/
PQfinish(conn);
return 1;
}
#ifdef TRACE
if (NULL == (trc = fopen(TRACEFILE, "w"))
{
fprintf(stderr, "Error al abrir el archivo de trazas ¡"%s\"!\n", TRACEFILE);
PQfinish(conn);
Devuelve 1;
}
/* rastreo de la comunicación cliente-servidor */
PQtrace(conn, trc);
#endif
/* este programa espera que la base de datos devuelva los datos en UTF-8 */
PQsetClientEncoding(conn, "UTF8");
/* realizar una consulta con parámetros */
res = PQexecParams(
conn,
"SELECT nombre_columna, tipo_datos"
"FROM esquema_informacion.columnas "
"WHERE nombre_tabla = $1",
1, /* un parámetro */
paramTipos,
paramValores,
NULL, /* la longitud de los parámetros no es necesaria para las cadenas */
NULL, /* todos los parámetros están en formato texto */
0 /* el resultado estará en formato texto */
);
/* sin memoria o comunicación cortada */
if (NULL == res)
{
fprintf(stderr, "%s\n", PQerrorMessage(conn));
PQfinish(conn);
#ifdef TRACE
fclose(trc);
#endif }
[Link] - Apuntes de PostgreSQL® para 64
profesionales
Devuelve
1;
[Link] - Apuntes de PostgreSQL® para 65
profesionales
/* La sentencia SQL debe devolver resultados */
if (PGRES_TUPLES_OK != PQresultStatus(res))
{
fprintf(stderr, "%s\n", PQerrorMessage(conn));
PQfinish(conn);
#ifdef TRACE
fclose(trc);
#endif
Devuelve 1;
}
/* obtener el recuento de filas y columnas de resultados */
rowcount = PQntuples(res);
colcount = PQnfields(res);
/* imprimir encabezados de columna */
firstcol = 1;
printf("Descripción de la tabla \"pg_database\"\n");
for (j=0; j<colcount; ++j)
{
si (primercol)
firstcol = 0;
si no
printf(": ");
printf(PQfname(res, j));
}
printf("\n\n");
/* bucle a través de las filas rosult */
for (i=0; i<cuentafilas; ++i)
{
/* imprimir todos los datos de las columnas */
firstcol = 1;
for (j=0; j<colcount; ++j)
{
si (primercol)
firstcol = 0;
si no
printf(": ");
printf(PQgetvalue(res, i, j));
}
printf("\n");
}
/* esto debe hacerse después de cada sentencia para evitar fugas de memoria */
PQclear(res);
/* cerrar la conexión a la base de datos y liberar memoria */
PQfinish(conn);
#ifdef TRACE
fclose(trc);
#endif
Devuelve 0;
}
[Link] - Apuntes de PostgreSQL® para 66
profesionales
Sección 25.2: Acceso a PostgreSQL desde python usando
psycopg2
Puede encontrar la descripción del
controlador aquí. El ejemplo rápido es:
importar psycopg2
db_host = '[Link]'
db_port = '5432'
db_un = 'usuario'
db_pw =
'contraseña'
db_name = 'testdb'
conn = [Link]("dbname={} host={} user={} password={}".format(
db_name, db_host, db_un, db_pw),
cursor_factory=RealDictCursor)
cur = [Link]()
sql = 'select * from testtable where id > %s and id < %s'
args = (1, 4)
[Link](sql, args)
print([Link]())
Resultará:
[{'id': 2, 'fruta': 'manzana'}, {'id': 3, 'fruta': 'naranja'}]
Sección 25.3: Acceso a PostgreSQL desde .NET utilizando el
proveedor Npgsql.
Uno de los proveedores .NET más populares para Postgresql es Npgsql, que es compatible con [Link] y se utiliza
de forma casi idéntica a otros proveedores de bases de datos .NET.
Una consulta típica se realiza creando un comando, vinculando parámetros y, a continuación, ejecutando el comando.
En C#:
var connString = "Host=myserv;Username=myuser;Password=mypass;Database=mydb";
using (var conn = new NpgsqlConnection(connString))
{
var querystring = "INSERT INTO data (some_field) VALUES (@content)";
[Link]();
// Crear un nuevo comando con CommandText y Connection constructor
using (var cmd = new NpgsqlCommand(querystring, conn))
{
// Añade un parámetro y establece su tipo con el enum NpgsqlDbType
var contentString = "¡Hola Mundo!";
[Link]("@content", [Link]).Value = contentString;
// Ejecutar una consulta que no devuelve resultados
[Link]();
/* Es posible reutilizar un objeto comando y abrir conexión en lugar de crear nuevos
*/
// Crear
[Link] una nueva
- Apuntes consulta y establecer
de PostgreSQL® para sus 67
parámetros
profesionales
int keyId = 101;
[Link] = "SELECT primary_key, some_field FROM data WHERE primary_key = @keyId";
[Link]();
[Link]("@keyId", [Link]).Value = keyId;
// Ejecutar el comando y leer las filas una a una
using (NpgsqlDataReader reader = [Link]())
{
while ([Link]()) // Devuelve false para 0 filas, o después de leer la última fila de
los resultados
{
// leer un valor entero
int primaryKey = lector.GetInt32(0);
// o
primaryKey = Convert.ToInt32(reader["primary_key"]);
// leer un valor de texto
string algúnCampoTexto = lector["algún_campo"].ToString();
}
}
}
} // la directiva 'using' de C# llama a [Link]() y [Link]() por nosotros
Sección 25.4: Acceso a PostgreSQL desde PHP usando Pomm2
Sobre los hombros de los controladores de bajo nivel, está pomm. Propone un enfoque modular, convertidores de
datos, soporte listen/notify, inspector de base de datos y mucho más.
Asumiendo, que Pomm ha sido instalado usando composer, aquí hay un ejemplo completo:
<?php
utilizar PommProject\Foundation\Pomm;
$loader = require DIR . '/vendedor/[Link]';
$pomm = new Pomm(['mi_db' => ['dsn' => 'pgsql://usuario:pass@host:5432/nombre_db']]);
// comentario TABLE (
// comment_id uuid PK, created_at timestamptz NN,
// is_moderated bool NN por defecto false,
// contenido texto NN CHECK (contenido !~ '^\s+$'), autor_email texto NN)
$sql =
<<<SQL
SELECT
comment_id,
created_at,
is_moderated,
content,
author_email
DE comentario
INNER JOIN autor USING (correo_autor)
WHERE
age(now(), created_at) < $*::interval
ORDER BY created_at ASC
SQL;
// el argumento se convertirá tal y como aparece en la consulta anterior
$comentarios = $pomm['mi_db']
->getQueryManager()
->query($sql, [DateInterval::createFromDateString('1 day')]);
if ($comments->isEmpty()) {
printf("No hay nuevos comentarios desde ayer");
} else {
[Link] - Apuntes de PostgreSQL® para 68
profesionales
foreach ($comentarios como $comentario)
{ printf(
"%s ha publicado en %s. %s\n",
$comment['author_email'],
$comment['created_at']->format("A-m-d H:i:s"),
$coment['is_moderated'] ? '[OK]' : '');
}
}
El módulo gestor de consultas de Pomm escapa los argumentos de consulta para prevenir inyecciones SQL. Cuando
los argumentos son lanzados, también los convierte de una representación PHP a valores Postgres válidos. El
resultado es un iterador, usa un cursor internamente. Cada fila se convierte sobre la marcha, booleanos a booleanos,
marcas de tiempo a \DateTime, etc.
[Link] - Apuntes de PostgreSQL® para 69
profesionales
Capítulo 26. Conectarse a PostgreSQL
desde Java Conectarse a PostgreSQL desde
Java
La API para utilizar una base de datos relacional desde
Java es JDBC. Esta API se implementa mediante un
controlador JDBC.
Para utilizarlo, coloque el archivo JAR con el controlador en la ruta de clases JAVA.
Esta documentación muestra ejemplos de cómo utilizar el controlador JDBC para conectarse a una base de datos.
Sección 26.1: Conexión con [Link]
Es la forma más sencilla de conectarse.
En primer lugar, el controlador tiene que ser registrado con [Link] para que sepa
qué clase utilizar. Esto se hace cargando la clase del driver, típicamente con
[Link](;nombre de la clase del driver>).
/**
* Conectarse a una base de datos PostgreSQL.
* @param url la URL JDBC a la que conectarse; debe empezar por "jdbc:postgresql:"
* @param usuario el nombre de usuario para la conexión
* @param password la contraseña de la conexión
* @devuelve un objeto de conexión para la conexión establecida
* @throws ClassNotFoundException si la clase del controlador no se encuentra en la ruta de clases Java
* @throws [Link] si falla la conexión a la base de datos
*/
private static [Link] connect(String url, String user, String password)
lanza ClassNotFoundException, [Link]
{
/*
* Registre el controlador PostgreSQL JDBC.
* Esto puede generar una ClassNotFoundException.
*/
[Link]("[Link]");
/*
* Indica al gestor de controladores que se conecte a la base de datos especificada con la URL.
* Esto puede generar una SQLException.
*/
return [Link](url, usuario, contraseña);
}
Tenga en cuenta que el usuario y la contraseña también pueden incluirse en la URL JDBC, en cuyo caso no es
necesario especificarlos en la llamada al método getConnection.
Sección 26.2: Conexión con [Link] y
Propiedades
En lugar de especificar los parámetros de conexión como usuario y contraseña (ver una lista completa aquí) en la URL
o e n parámetros separados, puede empaquetarlos en un objeto [Link]:
[Link] - Apuntes de PostgreSQL® para 70
profesionales
/**
* Conectarse a una base de datos PostgreSQL.
* @param url la URL JDBC a la que conectarse. Debe comenzar con "jdbc:postgresql:"
* @param usuario el nombre de usuario para la conexión
* @param password la contraseña de la conexión
[Link] - Apuntes de PostgreSQL® para 71
profesionales
* @devuelve un objeto de conexión para la conexión establecida
* @throws ClassNotFoundException si la clase del controlador no se encuentra en la ruta de clases Java
* @throws [Link] si falla la conexión a la base de datos
*/
private static [Link] connect(String url, String user, String password)
lanza ClassNotFoundException, [Link]
{
/*
* Registre el controlador PostgreSQL JDBC.
* Esto puede generar una ClassNotFoundException.
*/
[Link]("[Link]");
[Link] props = new [Link]();
[Link]("usuario", usuario);
[Link]("contraseña", contraseña);
/* no utilizar sentencias preparadas por el servidor */
[Link]("prepareThreshold", "0");
/*
* Indica al gestor de controladores que se conecte a la base de datos especificada con la URL.
* Esto puede generar una SQLException.
*/
return [Link](url, props);
}
Sección 26.3: Conexión con [Link] usando un pool
de conexiones
Es habitual utilizar [Link] con JNDI en contenedores de servidores de aplicaciones, donde se
registra una fuente de datos con un nombre y se busca cada vez que se necesita una conexión.
Se trata de código que demuestra cómo funcionan las fuentes de datos:
/**
* Crear una fuente de datos con pool de conexiones para conexiones PostgreSQL
* @param url la URL JDBC a la que conectarse. Debe comenzar con "jdbc:postgresql:"
* @param usuario el nombre de usuario para la conexión
* @param password la contraseña de la conexión
* @devolver una fuente de datos con las propiedades correctas establecidas
*/
private static [Link] createDataSource(String url, String user, String password)
{
/* utilizar una fuente de datos con agrupación de conexiones */
[Link] ds = new [Link]();
[Link](url);
[Link](usuario);
[Link](contraseña);
/* el pool de conexiones tendrá de 10 a 20 conexiones */
[Link](10); [Link](20);
/* utilizar conexiones SSL sin comprobar el certificado del servidor */
[Link]("require");
[Link]("[Link]");
devolver ds;
}
Una vez que hayas creado una fuente de datos llamando a esta función, la utilizarías de la siguiente manera:
/* obtener una conexión del pool de conexiones */
[Link] conn = [Link]();
[Link] - Apuntes de PostgreSQL® para 72
profesionales
/* hacer algo de trabajo */
/* devolver la conexión al pool - no se cerrará */ [Link]();
[Link] - Apuntes de PostgreSQL® para 73
profesionales
Capítulo 27: PostgreSQL Alta Disponibilidad
Sección 27.1: Replicación en PostgreSQL
Configuración del servidor primario
Requisitos:
Replicación Usuario para las actividades
de replicación Directorio para almacenar
los archivos WAL
Crear usuario de replicación
CREATEUSER -U postgres replication -P -c 5 --replication
+ OPCIÓN -P le pedirá NUEVA CONTRASEÑA
+ OPCIÓN -c ES PARA conexiones máximas. 5 conexiones son suficientes PARA la
replicación
+ -replication CONCEDERÁ PRIVILEGIOS DE REPRODUCCIÓN AL USUARIO
Crear un directorio de archivo en el directorio de datos
mkdir $PGDATA/archivo
Edite el archivo pg_hba.conf
Este es el archivo de autenticación base del host, contiene la configuración para la autenticación del
cliente. Agregue la siguiente entrada:
#Tipo de nombre_base_d nombre_usua nombre de método
host e_datos rio host/IP
md5
host replicación replicación <IP-
esclavo>/32
Edite el archivo [Link]
Este es el archivo de configuración de PostgreSQL.
wal_level = hot_standby
Este parámetro decide el comportamiento del servidor esclavo.
`hot_standby` registra lo que SE REQUIERE PARA ACEPTAR CONSULTAS DE SOLO LECTURA EN
EL SERVIDOR esclavo.
`streaming` logs lo que se requiere para aplicar los WAL's en el esclavo.
`archive` que registra lo necesario para archivar.
archive_mode=ON
Este parámetro permite enviar segmentos de WAL a la ubicación de archivo utilizando el parámetro
archive_command.
archive_command = '¡prueba! -f /ruta/a/archivo/%f && cp %p /ruta/a/archivo/%f'
[Link] - Apuntes de PostgreSQL® para 74
profesionales
Básicamente lo que hace archive_command es copiar los segmentos WAL al directorio archive.
wal_senders = 5 Este es el número máximo de procesos WAL sender.
Ahora reinicie el servidor primario.
[Link] - Apuntes de PostgreSQL® para 75
profesionales
Copia de seguridad del servidor primario en el servidor esclavo
Antes de realizar cambios en el servidor, detenga el servidor primario.
Importante: No vuelva a iniciar el servicio hasta que haya completado todos los pasos de configuración y copia
de seguridad. Debe poner el servidor en espera en un estado en el que esté listo para ser un servidor
de copia de seguridad. Esto significa que todos los ajustes de configuración deben estar en su lugar y las
bases de datos deben estar ya sincronizadas. De lo contrario, la replicación de streaming no se iniciará`.
Ahora ejecute la utilidad pg_basebackup
La utilidad pg_basebackup copia los datos del directorio de datos del servidor primario al directorio de datos del
esclavo.
$ pg_basebackup -h <PRIMARY IP> -D /var/lib/postgresql/<VERSION>/main -U replication -v -P --
xlog-method=stream
-D: Esto le dice a pg_basebackup DONDE HACER la copia de seguridad inicial
-h: Especifica el SISTEMA DONDE BUSCAR el SERVIDOR PRIMARIO
-xlog-method=stream: Esto FORZARÁ a pg_basebackup A abrir otra CONEXIÓN Y transmitir
suficiente xlog MIENTRAS se ejecuta la copia de seguridad.
Garantiza TAMBIÉN que se pueda iniciar una nueva copia de seguridad SIN
fallar a
USAR un archivo.
Configuración del servidor en espera
Para configurar el servidor en espera, editarás [Link] y crearás un nuevo archivo de configuración
llamado [Link].
hot_standby = ON
Especifica si se le permite ejecutar consultas durante la recuperación.
Creación del archivo [Link]
standby_mode = ON
Establezca la cadena de conexión con el servidor primario. Sustituir por la dirección IP externa del servidor
primario. Sustituir por la contraseña del usuario denominado replicación.
`primary_conninfo = 'host= port=5432 user=replication password='
(Opcional) Establezca la ubicación del archivo de activación:
trigger_file = '/tmp/[Link].5432'
La ruta trigger_file que especifique es la ubicación donde puede añadir un archivo cuando desee
que el sistema conmute por error al servidor en espera. La presencia del archivo "dispara" la
[Link] - Apuntes de PostgreSQL® para 76
profesionales
conmutación por error. Alternativamente, puede utilizar el comando pg_ctl promote para activar la
conmutación por error.
[Link] - Apuntes de PostgreSQL® para 77
profesionales
Iniciar el servidor en espera
Ya tiene todo en su sitio y está listo para activar el servidor en espera.
Atribución
Este artículo se deriva sustancialmente y se atribuye a How to Set Up PostgreSQL for High Availability and
Replication with Hot Standby, con cambios menores en el formato y los ejemplos y algún texto eliminado. La
fuente fue publicada bajo la Licencia Pública Creative Commons 3.0, que se mantiene aquí.
[Link] - Apuntes de PostgreSQL® para 78
profesionales
Capítulo 28: EXTENSIÓN dblink y
postgres_fdw
Sección 28.1: Extensión FDW
FDW es un implimentation de dblink es más útil, por lo que utilizarlo:
1. Crear una extensión:
CREAR EXTENSIÓN postgres_fdw;
2. Crear SERVIDOR:
CREATE SERVER name_srv FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'hostname',
dbname 'bd_name', port '5432');
3. Crear mapeo de usuarios para el servidor postgres
CREATE USER MAPPING FOR postgres SERVER name_srv OPTIONS(USER 'postgres', PASSWORD 'password');
4. Crear tabla externa:
CREATE FOREIGN TABLE table_foreign (id INTEGER, code CHARACTER VARYING)
SERVER name_srv OPTIONS(schema_name 'esquema', table_name 'tabla');
5. utilice esta tabla externa como si estuviera en su base de datos:
SELECT * FROM tabla_foreign;
Sección 28.2: Envoltura de datos ajenos
Para acceder al esquema completo de la base de datos del servidor en lugar de a una sola tabla. Siga los siguientes
pasos:
1. Crear EXTENSIÓN :
CREAR EXTENSIÓN postgres_fdw;
2. Crear SERVIDOR :
CREATE SERVER server_name FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'host_ip',
dbname 'db_name', port 'port_number');
3. Crear MAPA DE USUARIOS:
CREAR ASIGNACIÓN DE USUARIO PARA USUARIO_ACTUAL
SERVER nombre_servidor
OPTIONS (USUARIO 'nombre_usuario', CONTRASEÑA 'contraseña');
4. Crear nuevo esquema para acceder al esquema de la BD del servidor:
CREAR ESQUEMA nombre_esquema;
[Link] - Apuntes de PostgreSQL® para 79
profesionales
5. Importar el esquema del servidor:
IMPORTAR ESQUEMA FOREIGN nombre_esquema_para_importar_desde_db_remota
FROM SERVIDOR nombre_servidor
INTO nombre_esquema;
6. Acceder a cualquier tabla del esquema del servidor:
SELECT * FROM nombre_esquema.nombre_tabla;
Puede utilizarse para acceder a varios esquemas de una base de datos remota.
Sección 28.3: Extensión dblink
dblink EXTENSION es una técnica para conectar otra base de datos y hacer operación de esta base de datos así
que para hacer eso necesitas:
1- Crear una extensión dblink:
CREAR EXTENSIÓN dblink;
2- Haga su operación:
Por ejemplo Seleccionar algún atributo de otra tabla en otra base de datos:
SELECT * FROM
dblink ('dbname = bd_distance port = 5432 host = [Link] user = username
password = passw@rd', 'SELECT id, code FROM [Link]')
AS newTable(id INTEGER, code CHARACTER VARYING);
[Link] - Apuntes de PostgreSQL® para 80
profesionales
Capítulo 29: Trucos y consejos para Postgres
Sección 29.1: Alternativa DATEADD en Postgres
SELECT FECHA_ACtual + '1 día'::INTERVALO
SELECT '1999-12-11'::TIMESTAMP + '19 days'::INTERVAL
SELECT '1 month'::INTERVAL + '1 month 3 days'::INTERVAL
Sección 29.2: Valores de una columna separados por comas
SELECCIONE
STRING_AGG(<NOMBRE_TABLA>.<NOMBRE_COLUMNA>, ',')
DESDE
<NOMBRE_ESQUEMA>.<NOMBRE_TABLA> T
Sección 29.3: Eliminar registros duplicados de la tabla postgres
BORRAR
FROM <NOMBRE_ESQUEMA>.<NOMBRE_Tabla>
DONDE
ctid NOT IN
(
SELECCIONE
MAX(ctid)
FROM
<NOMBRE_ESQUEMA>.<NOMBRE_TABLA>
GRUPO POR
<NOMBRE_ESQUEMA>.<NOMBRE_TABLA>.*
)
;
Apartado 29.4: Consulta de actualización con join entre dos
tablas alternativa ya que Postresql no soporta join en
consulta de actualización
UPDATE <NOMBRE_DEL_ESQUEMA>.<NOMBRE_DE_TABLA_1> AS A
SET <COLUMNA_1> = TRUE
FROM <NOMBRE_ESQUEMA>.<NOMBRE_TABLA_2> AS B
DONDE
A.<COLUMNA_2> = B.<COLUMNA_2> Y
A.<COLUMNA_3> = B.<COLUMNA_3>
Sección 29.5: Diferencia entre dos marcas de fecha, mes y año
Diferencia mensual entre dos fechas(timestamp)
SELECCIONE
(
(DATE_PART('año', AgeonDate) - DATE_PART('año', tmpdate)) * 12
+
(DATE_PART('mes', AgeonDate) - DATE_PART('mes', tmpdate))
)
FROM dbo. "Tabla1"
[Link] - Apuntes de PostgreSQL® para 81
profesionales
Diferencia anual entre dos fechas(timestamp)
SELECT (DATE_PART('año', AgeonDate) - DATE_PART('año', tmpdate)) FROM dbo. "Tabla1"
Sección 29.6: Consulta para copiar/mover/transferir datos de
una tabla de una base de datos a otra tabla de otra base de
datos con el mismo esquema
Primera ejecución
CREAR EXTENSIÓN DBLINK;
Entonces
INSERTAR EN
<NOMBRE_ESQUEMA>.<NOMBRE_TABLA_1>
SELECCIONAR *
DESDE
DBLINK(
'HOST=<DIRECCIÓN IP> USER=<NOMBRE_USUARIO> PASSWORD=<CONTRASEÑA>
DBNAME=<BASE_DE_DATOS>', 'SELECT * FROM
<NOMBRE_DE_ESQUEMA>.<NOMBRE_DE_TABLA_2>')
AS
<NOMBRE_TABLA>
(
<COLUMNA_1> <TIPO_DE_DATO_1>,
<COLUMNA_1> <TIPO_DE_DATO_2>,
<COLUMNA_1> <TIPO_DE_DATO_3>
);
[Link] - Apuntes de PostgreSQL® para 82
profesionales
Créditos
Muchas gracias a todas las personas de Stack Overflow Documentation que ayudaron a proporcionar
este contenido, más cambios pueden ser enviados a web@[Link] para que el nuevo
contenido sea publicado o actualizado.
Alison S Capítulos 1 y 11
AndrewCichocki Capítulos 1 y 15
ankidaemon Capítulo 23
AstraSerg Capítulo 25
Ben Capítulos 1, 20 y 22
Ben H Capítulos 1, 2, 14, 15, 20, 21, 23 y 29
bignose Capitulo 1
bilelovitch Capítulos 20 y 24
Blackus Capítulo 20
brichines Capítulo 25
chalitha geekiyanage Capítulos 8 y 18
commonSenseCode Capítulo
10 Dakota Wagner Capítulo 1
Daniel Lyons Capítulos 20 y 23
Demircan Celebi Capítulo 1
Dmitri Goldring Capítulo 1
e4c5 Capítulos 1, 4, 20 y 23
evuez Capitulo 16
Goerman Capítulo 15
gpdude_ Capítulos 8 y 27
greg Capítulos 20 y 25
Jakub Fedyczak Capítulo 12
jasonszhao Capítulo 1
Jefferson Capitulo 4
jgm Capítulo 10
joseph Capítulo 11
Kevin Sylvestre Capítulo 12
KIM Capítulos 3, 4, 8 y 20
KIRAN KUMAR MATAM Capítulo 22
Kirill Sokolov Capítulo 11
Kirk Roybal Capítulo 1
Laurenz Albe Capítulos 15, 25 y 26
leeor Capítulos 4, 8 y 9
Mohamed Navas Capítulo 6
Mokadillion Capítulos 1 y 7
Nathaniel Waisbrot Capítulo 8
Nuri Tasdemir Capítulo 3
Patrick Capítulos 3, 11 y 27
Reiniciar Capítulo 20
Riya Bansal Capítulo 28
skj123 Capítulos 21 y 29
Tajinder Capítulo 19
Tom Gerken Capítulo 3
Udlei Nati Capítulo 18
usuario_0 Capitulo 2
Vao Tsun Capítulos 8, 13, 15 y 17
wOwhOw Capítulo 17
[Link] - Apuntes de PostgreSQL® para 83
profesionales
YCF_L Capítulos 5 y 28
[Link] - Apuntes de PostgreSQL® para 84
profesionales
También le puede interesar