Arrays 如何获得数组列的维数?

Arrays 如何获得数组列的维数?,arrays,postgresql,information-schema,Arrays,Postgresql,Information Schema,我正在从事一个项目,该项目直接从数据库收集有关您的模式的信息。我可以使用information\u schema.columns获取列的数据类型,这将告诉我它是否是数组。我还可以通过查询信息\u架构来获取数组的底层类型(integer,bytea等)。元素类型如下所述: 我的问题是,我还需要知道数组有多少个维度,例如是integer[],还是integer[][]。有人知道这样做的方法吗?谷歌在这方面帮不了什么忙,希望更熟悉Postgres规范的人能给我指引正确的方向。对于初学者来说,数组的维

我正在从事一个项目,该项目直接从数据库收集有关您的模式的信息。我可以使用
information\u schema.columns
获取列的
数据类型
,这将告诉我它是否是
数组
。我还可以通过查询
信息\u架构来获取
数组的底层类型(
integer
bytea
等)。元素类型如下所述:


我的问题是,我还需要知道数组有多少个维度,例如是
integer[]
,还是
integer[][]
。有人知道这样做的方法吗?谷歌在这方面帮不了什么忙,希望更熟悉Postgres规范的人能给我指引正确的方向。

对于初学者来说,数组的维数并没有反映在Postgres中的数据类型中。允许使用语法
integer[][]
,但实际上它只是
integer[]
内部语法。

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

要获取特定数组值的实际维数

SELECT array_dims(my_arr);  -- [1:2][1:3]
或者仅获取维度的数量:

SELECT array_ndims(my_arr);  -- 2
有更多的数组函数用于类似的需求。看

相关的:

如果需要在列中强制执行特定尺寸标注,请添加。要强制使用二维数组,请执行以下操作:

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

首先,数组的维数不会反映在Postgres中的数据类型中。允许使用语法
integer[][]
,但实际上它只是
integer[]
内部语法。

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

要获取特定数组值的实际维数

SELECT array_dims(my_arr);  -- [1:2][1:3]
或者仅获取维度的数量:

SELECT array_ndims(my_arr);  -- 2
有更多的数组函数用于类似的需求。看

相关的:

如果需要在列中强制执行特定尺寸标注,请添加。要强制使用二维数组,请执行以下操作:

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)
可以在数组类型的列中存储不同维度的数组:

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_属性
中找到尺寸数:

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)
目前尚不清楚您是否可以依赖此数字,例如:

attndims—如果列是数组类型,则为维度数;否则为0。(目前,数组的维数没有强制执行,因此任何非零值实际上意味着“它是一个数组”。)


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)
可以在数组类型的列中存储不同维度的数组:

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_属性
中找到尺寸数:

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)
目前尚不清楚您是否可以依赖此数字,例如:

attndims—如果列是数组类型,则为维度数;否则为0。(目前,数组的维数没有强制执行,因此任何非零值实际上意味着“它是一个数组”。)


“数组的维数不反映在Postgres中的数据类型中”这并不完全正确。Postgres将定义的维度存储在
pg\u属性.attndims
中。因此,重建原始定义是可能的。我不知道为什么,例如,
psql
不能做到这一点。@horse\u没有名称,但数组值的维数没有反映在数据类型中——至少我是这样理解的。因为柱的实际尺寸是不存在的;它随价值而变化。声明的维度可能可以在
pg_attribute.attndims
中访问,但不可能重构原始定义,因为长度“约束”会以任何方式丢失(例如
create table t(col int[3][4])
无法以任何方式重构)
pg_属性。attndims
更像是一个注释,而不是一个可靠的值。“数组的维度没有反映在Postgres中的数据类型中”这并不完全正确。Postgres将定义的维度存储在
pg\u属性.attndims
中。因此,重建原始定义是可能的。我不知道为什么,例如,
psql
不能做到这一点。@horse\u没有名称,但数组值的维数没有反映在数据类型中——至少我是这样理解的。因为柱的实际尺寸是不存在的;它随价值而变化。声明的维度可能可以在
pg_attribute.attndims
中访问,但不可能重构原始定义,因为长度“约束”会以任何方式丢失(例如
create table t(col int[3][4])
无法以任何方式重构)
pg_属性。attndims
更像是一个注释,而不是一个可靠的值。“不能从表结构中确定数组列的维度”这并不完全正确。信息记录在
pg_属性中。attndims
@a_horse_with_no_name-谢谢,我在答案中添加了您的提示。“您无法从表结构确定数组列的维度”这并不完全是一个问题