Hemos tenido discusiones sobre esto muchas veces. El esquema de información sirve para ciertos propósitos. Si conoce los catálogos del sistema, estos sirven mejor para la mayoría de los propósitos , IMO. Los catálogos del sistema son la fuente real de toda la información.
El esquema de información proporciona vistas estandarizadas que ayudan con la portabilidad, principalmente en las principales versiones de Postgres, porque la portabilidad en diferentes plataformas RDBMS generalmente es una ilusión una vez que sus consultas son lo suficientemente sofisticadas como para necesitar buscar catálogos de sistemas. Y, en particular, Oracle todavía no es compatible con el esquema de información.
Las vistas en el esquema de información deben saltar a través de muchos aros para lograr un formato que cumpla con el estándar. Esto los hace lentos, a veces muy lentos. Compare los planes y el rendimiento de estos objetos básicos:
EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;
La diferencia es notable. Realmente depende de lo que estés buscando.
Su ejemplo
Para su ejemplo SELECT * from tbl
, compare las dos consultas a continuación para esta tabla simple:
CREATE TEMP TABLE foo(
A numeric(12,3)
, b timestamp(0)
);
Utilizando pg_attribute
:
SELECT attname, format_type(atttypid, atttypmod) AS type
FROM pg_attribute
WHERE attrelid = 'foo'::regclass
AND attnum > 0
AND NOT attisdropped
ORDER BY attnum;
format_type()
devuelve el tipo completo con todos los modificadores:
attname | type
--------+-------------------------------
a | numeric(12,3)
b | timestamp(0) without time zone
También tenga en cuenta que el reparto para regclass
resuelve el nombre de la tabla de manera algo inteligente de acuerdo con el actual search_path
. También genera una excepción si el nombre no es válido. Detalles:
Utilizando information_schema.columns
:
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'foo'
ORDER BY ordinal_position;
La información está estandarizada, pero incompleta :
column_name | data_type
------------+----------------------------
a | numeric
b | timestamp without time zone
Para obtener información completa sobre el tipo de datos, debe considerar todas estas columnas además:
character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision
Respuestas relacionadas:
Una lista de pros y contras , los mayores pros (IMO) en negrita:
Vistas del esquema de información
- a menudo más simple (depende)
- lento
- preprocesado, que puede o no satisfacer sus necesidades
- selectiva (los usuarios solo ven los objetos para los que tienen privilegios)
- conforme a un estándar SQL (implementado por algunos de los principales RDBMS)
- mayormente portátil en las principales versiones de Postgres
- no requieren mucho conocimiento específico sobre Postgres
- los identificadores son descriptivos, largos y a veces incómodos
Catálogos del sistema
- a menudo más complejo (depende), más cerca de la fuente
- rápido
- completo (columnas del sistema como
oid
incluidas)
- no cumple con un estándar SQL
- menos portátil en las principales versiones de Postgres (pero lo básico no va a cambiar)
- requieren un conocimiento más específico sobre Postgres
- los identificadores son concisos, menos descriptivos pero convenientemente cortos
Consulta arbitraria
Para obtener la misma lista de nombres y tipos de columnas de una consulta, puede usar un simple truco: CREAR una tabla temporal a partir de la salida de la consulta, luego use las mismas técnicas que anteriormente.
Puede agregar LIMIT 0
, ya que no necesita datos reales:
CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT 0;
Para obtener el tipo de datos de columnas individuales, también puede usar la función pg_typeof()
:
SELECT pg_typeof(1);