【问题标题】:How to get the dimensionality of an ARRAY column?如何获得 ARRAY 列的维度?
【发布时间】:2017-01-19 01:22:52
【问题描述】:

我正在开展一个项目,该项目直接从数据库中收集有关您的架构的信息。我可以使用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[][]。有谁知道这样做的方法?谷歌在这里不是很有帮助,希望更熟悉 Postgres 规范的人可以引导我朝着正确的方向前进。

【问题讨论】:

    标签: arrays postgresql information-schema


    【解决方案1】:

    对于初学者来说,数组的维数不会反映在 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);
    

    【讨论】:

    • 数组的维数不会反映在 Postgres 中的数据类型中”这并不完全正确。 Postgres 确实将定义的维度存储在pg_attribute.attndims 中。因此可以重建原始定义。我不知道为什么,例如psql 不会那样做。
    • @a_horse_with_no_name 但数组的维度并没有反映在数据类型中——至少,我是这么读的。因为 column 的实际维度是不存在的;它因价值而异。声明的维度可能在pg_attribute.attndims 中可访问,但可以重建原始定义 是不正确的,因为长度“约束”无论哪种方式都会丢失(例如@987654334 @ 不能以任何方式重构)。 pg_attribute.attndims 更像是一个评论而不是一个可靠的值。
    【解决方案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。(目前,数组的维数未强制执行,因此任何非零值实际上都意味着“它是一个数组”。)

    【讨论】:

    • 您无法从表结构中确定数组列的维度”这并不完全正确。信息记录在pg_attribute.attndims
    • @a_horse_with_no_name - 谢谢,我已将您的提示添加到答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多