Ми багато разів про це дискутували. Інформаційна схема служить певним цілям. Якщо ви знаєте, як обходитись системними каталогами, вони краще служать більшості цілей , IMO. Системні каталоги - це фактичне джерело всієї інформації.
Інформація схема забезпечує стандартизоване думку , які допомагають з мобільністю, в основному через велику Postgres версію, тому що портативність на різні платформах RDBMS , як правило , є ілюзією , як тільки ваші запити досить складні для необхідності шукати системні каталоги. І, зокрема, Oracle досі не підтримує інформаційну схему.
Перегляди в інформаційній схемі повинні стрибати через безліч обручів, щоб досягти формату, відповідного стандарту. Це робить їх повільними, іноді дуже повільними. Порівняйте плани та ефективність цих основних об'єктів:
EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;
Різниця помітна. Це дійсно залежить від того, що ви шукаєте.
Ваш приклад
Для вашого прикладу SELECT * from tbl
порівняйте два запити нижче для цієї простої таблиці:
CREATE TEMP TABLE foo(
A numeric(12,3)
, b timestamp(0)
);
Використання 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()
повертає повний тип із усіма модифікаторами:
attname | type
--------+-------------------------------
a | numeric(12,3)
b | timestamp(0) without time zone
Також зауважте, що команда для regclass
вирішення назви таблиці дещо розумно відповідає поточному search_path
. Він також створює виняток, якщо ім'я недійсне. Деталі:
Використання information_schema.columns
:
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'foo'
ORDER BY ordinal_position;
Інформація стандартизована, але неповна :
column_name | data_type
------------+----------------------------
a | numeric
b | timestamp without time zone
Щоб отримати повну інформацію про тип даних, потрібно додатково врахувати всі ці стовпці:
character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision
Відповідні відповіді:
Список плюсів і мінусів , найбільші плюси (IMO), виділені жирним шрифтом:
Перегляди інформаційної схеми
- часто простіше (залежить)
- повільний
- попередньо оброблена, що може відповідати вашим потребам
- вибірковий (користувачі бачать лише об'єкти, на які мають привілеї)
- відповідність стандарту SQL (це реалізовано деякими основними RDBMS)
- в основному портативні в основних версіях Postgres
- не вимагають багато конкретних знань про Postgres
- ідентифікатори описові, довгі та іноді незручні
Системні каталоги
- часто складніші (залежить), ближче до джерела
- швидко
- повна (стовпці системи, як
oid
включені)
- не відповідає стандарту SQL
- менш портативний для основних версій Postgres (але основні зміни не збираються)
- вимагають більш конкретних знань про Postgres
- ідентифікатори є короткими, менш описовими, але зручно короткими
Довільний запит
Щоб отримати той самий список назв та типів стовпців із запиту, ви можете скористатися простим фокусом: Створіть тимчасову таблицю з виводу запиту, а потім використовуйте ті самі методи, що і вище.
Ви можете додати LIMIT 0
, оскільки фактичні дані вам не потрібні:
CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT 0;
Щоб отримати тип даних для окремих стовпців, ви також можете скористатися функцією pg_typeof()
:
SELECT pg_typeof(1);