如何获取 ARRAY 列的维度?

How to get the dimensionality of an ARRAY column?

我正在从事一个直接从数据库中收集有关您的模式的信息的项目。我可以使用 information_schema.columns 获取列的 data_type,这将告诉我它是否是 ARRAY。我还可以通过查询 information_schema.element_types 来获取 ARRAY 的基础类型(integerbytea 等),如下所述:

https://www.postgresql.org/docs/9.1/static/infoschema-element-types.html

我的问题是我还需要知道数组有多少维度,例如是 integer[] 还是 integer[][]。有谁知道这样做的方法吗? Google 在这里不是很有帮助,希望更熟悉 Postgres 规范的人可以引导我朝着正确的方向前进。

对于初学者来说,数组的维数并不反映在 Postgres 的数据类型中。语法 integer[][] 是可以容忍的,但实际上它在内部只是 integer[]
Read the manual here.

这意味着,同一数据类型(同一 table 列)中的维度可以不同。

获取特定数组的实际维度value:

SELECT array_dims(my_arr);  -- [1:2][1:3]

或者只获取维数:

SELECT array_ndims(my_arr);  -- 2

类似需求还有更多数组函数。参见 table of array functions in the manual.

相关:

如果您需要在列中强制执行特定维度,请添加 CHECK constraint。要强制执行二维数组:

ALTER TABLE tbl ADD CONSTRAINT tbl_arr_col_must_have_2_dims
CHECK (array_ndims(arr_col) = 2);

Postgres 中的多维数组支持非常具体。多维数组类型不存在。如果将数组声明为多维数组,Postgres 会自动将其转换为简单数组类型:

create table test(a integer[][]);
\d test

      Table "public.test"
 Column |   Type    | Modifiers 
--------+-----------+-----------
 a      | integer[] |     

您可以在数组类型的列中存储不同维度的数组:

insert into test values
    (array[1,2]),
    (array[array[1,2], array[3,4]]);

select a, a[1] a1, a[2] a2, a[1][1] a11, a[2][2] a22
from test;

       a       | a1 | a2 | a11 | a22 
---------------+----+----+-----+-----
 {1,2}         |  1 |  2 |     |    
 {{1,2},{3,4}} |    |    |   1 |   4
(2 rows)

这是 Postgres 与 C、python 等编程语言之间的主要区别。该功能有其优点和缺点,但通常会给新手带来各种问题。

您可以在系统目录中找到维数pg_attribute:

select attname, typname, attndims
from pg_class c
join pg_attribute a on c.oid = attrelid
join pg_type t on t.oid = atttypid
where relname = 'test'
and attnum > 0;

 attname | typname | attndims 
---------+---------+----------
 a       | _int4   |        2
(1 row)

不清楚这个数能不能靠,至于the documentation:

attndims - Number of dimensions, if the column is an array type; otherwise 0. (Presently, the number of dimensions of an array is not enforced, so any nonzero value effectively means "it's an array".)