我们对此进行了多次讨论。信息模式用于某些目的。如果您了解系统目录的方法,那么IMO 可以更好地满足大多数目的。系统目录是所有信息的实际来源。
该信息架构提供了标准化的意见,帮助与便携性,主要是跨主要的Postgres版本,因为在不同的关系型数据库平台的可移植性通常是一种假象,一旦你的查询是复杂的,足以需要查找系统目录。而且,值得注意的是,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);