Postgres:使用 JSON 列与使用整数 [] 列有缺点吗?
Postgres: Are There Downsides to Using a JSON Column vs. an integer[] Column?
TLDR: 如果我想在 Postgres table 中保存整数数组,使用数组列 (integer[]
) 与使用 JSON 列(例如,一个比另一个表现更好)?
背景故事:
我正在使用 PostgreSQL 数据库,Node/Knex 来管理它。 Knex 没有任何方法可以直接定义 PostgreSQL integer[]
列类型,因此有人提交了一个 Knex 错误要求它......但是其中一位 Knex 开发人员关闭了票证,基本上说没有必要当任何人都可以使用 JSON 列类型时,支持 PostgreSQL 数组列类型。
我的问题是,使用 JSON 列类型来保存简单的整数数组有什么缺点(如果有的话)?使用真正的数组列是否有任何好处,例如提高性能,或者仅将我的数组存储在 JSON 列中是否同样好?
编辑: 明确地说,我要寻找的答案是以下之一:
A) 解释 PostgreSQL 中的 JSON 列和 integer[] 列如何工作,包括其中一个比另一个更好或者两者(至少大致)相等。
B) 没有解释,但至少参考了一些基准,表明一种列类型或另一种表现更好(或者两者相等)
int[]
就其所需的存储而言效率更高。考虑以下查询,其中 returns 具有 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;
returns:
array_size | jsonb_size | json_size
-----------+------------+----------
2024 | 6008 | 2396
(我很惊讶 JSON 的值比 JSONB 小很多,但那是另一个话题)
如果您总是将数组用作 单个 值,那么它在查询性能方面并不重要但是如果您 do 需要查看数组并搜索特定值,使用本机数组会更有效率。
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_single
和 json_single
。对于本机数组,您也可以改用 1 = any(int_array)
。
但是请检查数组是否包含列表中的所有值,或者列表中的任何值是否不适用于 JSON 数组。
以上测试查询returns:
id | array_single | json_single | array_all | json_all | array_any | json_any
---+--------------+-------------+-----------+----------+-----------+---------
1 | true | true | true | false | true | false
TLDR: 如果我想在 Postgres table 中保存整数数组,使用数组列 (integer[]
) 与使用 JSON 列(例如,一个比另一个表现更好)?
背景故事:
我正在使用 PostgreSQL 数据库,Node/Knex 来管理它。 Knex 没有任何方法可以直接定义 PostgreSQL integer[]
列类型,因此有人提交了一个 Knex 错误要求它......但是其中一位 Knex 开发人员关闭了票证,基本上说没有必要当任何人都可以使用 JSON 列类型时,支持 PostgreSQL 数组列类型。
我的问题是,使用 JSON 列类型来保存简单的整数数组有什么缺点(如果有的话)?使用真正的数组列是否有任何好处,例如提高性能,或者仅将我的数组存储在 JSON 列中是否同样好?
编辑: 明确地说,我要寻找的答案是以下之一:
A) 解释 PostgreSQL 中的 JSON 列和 integer[] 列如何工作,包括其中一个比另一个更好或者两者(至少大致)相等。
B) 没有解释,但至少参考了一些基准,表明一种列类型或另一种表现更好(或者两者相等)
int[]
就其所需的存储而言效率更高。考虑以下查询,其中 returns 具有 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;
returns:
array_size | jsonb_size | json_size
-----------+------------+----------
2024 | 6008 | 2396
(我很惊讶 JSON 的值比 JSONB 小很多,但那是另一个话题)
如果您总是将数组用作 单个 值,那么它在查询性能方面并不重要但是如果您 do 需要查看数组并搜索特定值,使用本机数组会更有效率。
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_single
和 json_single
。对于本机数组,您也可以改用 1 = any(int_array)
。
但是请检查数组是否包含列表中的所有值,或者列表中的任何值是否不适用于 JSON 数组。
以上测试查询returns:
id | array_single | json_single | array_all | json_all | array_any | json_any
---+--------------+-------------+-----------+----------+-----------+---------
1 | true | true | true | false | true | false