Postgres:使用JSON列和整数[]列是否有缺点?

时间:2018-03-31 21:55:21

标签: postgresql knex.js

TLDR:如果我想在Postgres表中保存整数数组,使用数组列(integer[])与使用JSON列是否有任何利弊?例如,一个人的表现比另一个人好吗?

背景故事:

我使用PostgreSQL数据库和Node / Knex来管理它。 Knex没有任何方法可以直接定义PostgreSQL integer[]列类型,因此有人提出了一个Knex错误要求它......但其中一个Knex开发者关闭了该票,基本上说没有当任何人都可以改为使用JSON列类型时,需要支持PostgreSQL数组列类型。

我的问题是,使用JSON列类型来保存简单的整数数组有什么缺点(如果有的话)?使用真正的数组列是否有任何好处,例如提高性能,或者只是将我的数组存储在JSON列中,我是否同样富裕?

编辑:为了清楚起见,我在答案中寻找的是以下任何一种:

A)解释PostgreSQL中的JSON列和integer []列如何工作,包括一个如何比另一个更好或两者如何(至少大致)相等。

B)没有解释,但至少提到一些基准,表明一个列类型或另一个列表现更好(或两者相等)

1 个答案:

答案 0 :(得分:5)

int[]在所需的存储方面效率更高。请考虑以下查询,该查询返回具有500个元素的数组的大小

select pg_column_size(array_agg(i)) as array_size, 
       pg_column_size(jsonb_agg(i)) as jsonb_size,
       pg_column_size(json_agg(i)) as json_size
from  generate_series(1,500) i;

返回:

array_size | jsonb_size | json_size
-----------+------------+----------
      2024 |       6008 |      2396

(我很惊讶JSON值比JSONB小得多,但这是一个不同的主题)

如果你总是将数组用作单个值,那么在查询性能方面并不重要但是如果你需要查看数组并搜索特定值,使用本机数组会更高效。

native arrays可用的函数和运算符比JSON数组要多得多。您可以轻松地在JSON数组中搜索单个值,但搜索多个值需要解决方法。

以下查询演示了:

with array_test (id, int_array, json_array) as (
  values
    (1, array[1,2,3], '[1,2,3]'::jsonb)
)
select id, 
       int_array @> array[1] as array_single,
       json_array @> '1' json_single,
       int_array @> array[1,2] as array_all,
       json_array ?& array['1','2'] as json_all,
       int_array && array[1,2] as array_any,
       json_array ?| array['1','2'] as json_any
from array_test;

如果数组包含一个特定值,则可以轻松查询该数组。这也适用于JSON数组。这些是表达式array_singlejson_single。使用原生数组,您也可以使用1 = any(int_array)

但请检查数组是否包含列表中的所有值,否则列表中的任何值都不适用于JSON数组。

上述测试查询返回:

id | array_single | json_single | array_all | json_all | array_any | json_any
---+--------------+-------------+-----------+----------+-----------+---------
 1 | true         | true        | true      | false    | true      | false