如何获得ARRAY列的维度?

时间:2016-09-11 12:38:56

标签: arrays postgresql information-schema

我正在开发一个项目,该项目直接从数据库收集有关您的架构的信息。我可以使用data_type获取该列的information_schema.columns,这将告诉我它是否为ARRAY。我也可以通过查询integer来获取bytea的基础类型(ARRAYinformation_schema.element_types等),如下所述:

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

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

2 个答案:

答案 0 :(得分:2)

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

这意味着,维度可以在同一数据类型(同一表格列)中变化。

获取特定数组的实际尺寸

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);

答案 1 :(得分: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 - 如果列是数组类型,则维数;否则为0.(目前,没有强制执行数组的维数,因此任何非零值都有效地表示"它是一个数组"。)