Skip to content

ARRAY数据类型

ARRAY简介

ARRAY类型允许将表的的列定义为可变长多维数组,数组允许在单个数据库字段中存储多个值,ARRAY类型支持虚谷数据库基本数据类型。

由于ARRAY数组类型的特性,在利用数据库处理列表或数据集等场景中,ARRAY类型可以发挥良好的作用,高效的实现场景下的特定需求。

ARRAY类型在数据库中的实现

ARRAY数据类型在虚谷数据库中有两种使用方式,分别为字符串类型的数组与ARRAY关键字数组,两种输入使用方式通过不同的逻辑统一转换为由BLOB大对象管理结构管理的ArrayType,最大支持2GB输入文本。

ARRAY数据类型是数据库内置的基础类型,支持在表、视图中创建ARRAY类型字段,也支持创建ARRAY类型的常量与变量,两者之间的声明方式略有不同。

ARRAY数据类型相关系统函数的详细信息请参见《系统函数参考指南》的数组类型函数章节。

ARRAY类型声明

在非字段中声明ARRAY

ARRAY类型结构在非字段中有两种声明方式,分别是关键字声明和字符串声明。

  • 关键字声明:

    sql
    -- 一维数组
    ARRAY[v1, v2, v3...];
    -- 多维数组,以三维数组为例
    ARRAY[[[v1, v2, v3...]]];
  • 字符串声明:

    sql
    -- 一维数组
    '{v1, v2, v3}';
    -- 多维数组,以三维数组为例
    '{{{v1, v2, v3}}}';

在使用方式上,两者的区别有以下几点:

  • 由ARRAY关键字声明的数组,维度是用成对的方括号进行标识的;字符串声明方式下的数组,是以大括号进行数组维度标识的。最大支持六维数组的声明与使用。
  • 字符串类型的数组由于设计原因,一些本身存在大括号的数据类型暂时不支持以此方式使用。
  • 字符串类型的数组的使用仅支持一些明确类型的场景,例如字段插入、更新、删除,并且不支持通过类型强制转换的方式转为数组类型;
  • ARRAY类型数组当成员为字符串类型时需要添加成对单引号进行包裹,声明为特定类型时,需要指明具体的数据类型,例如:
    sql
    -- CHAR类型数组
    SELECT ARRAY['aaa', 'bbb']; 
    
    -- DATE类型数组
    SELECT ARRAY['2024-01-01'::DATE, '2024-12-31'::DATE];

在表字段中声明ARRAY

ARRAY类型结构在字段中可通过在数据类型后添加方括号[]的方式进行声明。

sql
column_name type_name[]
  • column_name:字段的名称。
  • type_name:基础数据类型的名称。
  • []:表示这是一个数组类型。可以根据需要添加多个方括号来声明多维数组。数组维度与类型名后的方括号对数量相同,例如VARCHAR[][][]表示三维数组。

ARRAY类型支持多种基础类型作为成员数据,支持的基础类型如下表所示:

基础数据类型分类类型名称
数值数据类型
  • TINYINT
  • SMALLINT
  • INTEGER
  • BIGINT
  • NUMERIC
  • FLOAT
  • DOUBLE
  • 字符数据类型
  • CHAR
  • VARCHAR
  • 时间数据类型
  • DATE
  • TIME
  • TIME WITH TIME ZONE
  • DATETIME
  • DATETIME WITH TIME ZONE
  • 时间间隔类型
  • INTERVAL YEAR
  • INTERVAL MONTH
  • INTERVAL DAY
  • INTERVAL HOUR
  • INTERVAL MINUTE
  • INTERVAL SECOND
  • INTERVAL YEAR TO MONTH
  • INTERVAL DAY TO HOUR
  • INTERVAL DAY TO MINUTE
  • INTERVAL DAY TO SECOND
  • INTERVAL HOUR TO MINUTE
  • INTERVAL HOUR TO SECOND
  • INTERVAL MINUTE TO SECOND
  • 大对象数据类型
  • BLOB
  • CLOB
  • 基础几何类型
  • POINT
  • LINE
  • LSEG
  • BOX
  • PATH
  • POLYGON
  • CIRCLE
  • XML数据类型XML

    为了更好的说明ARRAY类型在字段上的用法,以数据库中建表为例:

    • 示例1
      创建一个名为array_types的表,包含一个VARCHAR类型的name列,一个INTEGER一维数组类型的int_arr列,以及一个VARCHAR二维数组类型的var_arr_2列。

      sql
      CREATE TABLE array_types (
       var VARCHAR,
       int_arr INTEGER[],
       var_arr_2 VARCHAR[][]
      );
    • 示例2
      在声明数组类型时,方括号中可以添加指定大小的参数,但当前实现忽略了任何指定数组大小的操作,即添加参数的声明行为与未指定大小时相同。

      sql
      -- 同int_arr INTEGER[][]
      CREATE TABLE array_params (
       int_arr INTEGER[3][3] 
      );
    • 示例3
      若声明一维数组,还提供另外关键字的声明方式。

      sql
      -- 添加大小参数
      int_arr INTEGER ARRAY[4]
      
      -- []中不添加参数时不单独使用[]
      int_arr INTEGER ARRAY

    ARRAY类型输入

    ARRAY类型结构支持两种输入方式,分别是使用关键字ARRAY和使用{}字符串。

    以输入二维数组为例,更高维度的插入同样遵循此原则。

    • 关键字ARRAY输入:
      sql
      INSERT INTO array_types VALUES('int', '{1, 2, 3}', '{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}');
    • {}字符串输入:
      sql
      INSERT INTO array_types VALUES('int', ARRAY[1, 2, 3], ARRAY[[1, 2, 3], [4, 5, 6], [7, 8, 9]]);

    ARRAY类型查询

    本小节以一维数组表和三维数组表为例进行说明:

    sql
    -- 创建一维数组表并插入数据
    SQL> CREATE TABLE test_arr (a int[]);
    SQL> INSERT INTO test_arr VALUES ('{1, 2, 3}');
    
    -- 创建三维数组表并插入2x2x3的三维数组
    SQL> CREATE TABLE test_arr_3 (a int[][][]);
    SQL> INSERT INTO test_arr_3 VALUES ('{{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}}}');

    查询整组字段

    直接查询字段名即可查询整组字段信息。

    • 查询一维数组:

      sql
      SQL> SELECT a FROM test_arr;
      
      A | 
      ------------------------------------------------------------------------------
      {1,2,3}|
    • 查询多维数组:

      sql
      SQL> SELECT a FROM test_arr_3;
      
      A | 
      ------------------------------------------------------------------------------
      {{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}}}|

    查询数组某个下标代表的元素

    通过字段名[数组下标]的方式进行查询。

    • 查询一维数组的1号元素:

      sql
      SQL> SELECT a[1] FROM test_arr;
      
      EXPR1 | 
      ------------------------------------------------------------------------------
      1 |
    • 查询多维数组,a[1][2][3]访问的是第一个维度的第一个元素(即第一个2x3的二维数组[[1, 2, 3], [4, 5, 6]]),第二个维度的第二个元素(即第二行[4, 5, 6]),第三个维度的第三个元素(即 6)。

      sql
      SQL> SELECT a[1][2][3] FROM test_arr_3;
      
      EXPR1 | 
      ------------------------------------------------------------------------------
      6 |

    说明:

    更高维的数组元素查询方式与之类似,方括号的数量需要与表中数据的维度匹配。

    查询数组字段中的切片数据

    以切片字段名[起始下标:结束下标]的方式查询数组字段中的部分数据。

    • 查询一维数组中第1到第2个元素:

      sql
      SQL> SELECT a[1:2] FROM test_arr;
      
      EXPR1 | 
      ------------------------------------------------------------------------------
      {1,2}|
    • 查询多维数组,a[1:2][1:2][1:2]表示查询第一个维度的第1到第2个元素、第二个维度的第1到第2个元素以及第三个维度的第1到第2个元素。

      sql
      SQL> SELECT a[1:2][1:2][1:2] FROM test_arr_3;
      
      EXPR1 | 
      ------------------------------------------------------------------------------
      {{{1,2},{4,5}},{{7,8},{10,11}}}|

    说明:

    多维数组的切片查询也应当与表中字段的维度匹配。当切片查询的结束下标超过当前字段中数组的个数时,数据库将以最大的元素个数修正结束下标。

    ARRAY类型更新

    在更新指定下标位置的元素需要在字段名后添加想要修改元素的位置下标。

    • 一维数组。

      sql
      UPDATE test_arr SET a[1] = 4;
    • 多维数组。

      sql
      UPDATE test_arr_3 SET a[1][1][1] = 4;
    • 使用切片更新。

      sql
      UPDATE test_arr_3 SET a[1:1][1:1][1:2] = '{{{4, 5}}}';

    通过以上方式,可以对指定位置的元素进行更新。