pg_jsonschema
源代码: https://github.com/supabase/pg_jsonschema
概述
pg_jsonschema
是一个PostgreSQL扩展,为json
和jsonb
数据类型添加了JSON schema验证支持。
API
三个SQL函数:
- json_matches_schema
- jsonb_matches_schema(注意前面的jsonb)
- jsonschema_is_valid
函数签名如下:
-- 验证json *实例*是否符合*模式*
json_matches_schema(schema json, instance json) returns bool
以及
-- 验证jsonb *实例*是否符合*模式*
jsonb_matches_schema(schema json, instance jsonb) returns bool
以及
-- 验证json *模式*是否有效
jsonschema_is_valid(schema json) returns bool
使用方法
这些函数可用于限制json
和jsonb
列符合特定模式。
例如:
create extension pg_jsonschema;
create table customer(
id serial primary key,
metadata json,
check (
json_matches_schema(
'{
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string",
"maxLength": 16
}
}
}
}',
metadata
)
)
);
-- 示例:有效负载
insert into customer(metadata)
values ('{"tags": ["vip", "darkmode-ui"]}');
-- 结果:
-- INSERT 0 1
-- 示例:无效负载
insert into customer(metadata)
values ('{"tags": [1, 3]}');
-- 结果:
-- ERROR: 新行违反了关系"customer"的检查约束"customer_metadata_check"
-- DETAIL: 失败的行包含 (2, {"tags": [1, 3]})。
JSON Schema 支持
pg_jsonschema 是 jsonschema Rust crate 的一个(非常)薄的封装。访问他们的文档以获取有关支持哪些 JSON Schema 规范草案的完整详细信息。
试用
通过 docker-compose up
在 Docker 容器中启动安装了 pg_jsonschema 的 Postgres。数据库可在 postgresql://postgres:password@localhost:5407/app
访问。
安装
需要:
cargo pgrx run
这将进入 psql 提示符。
psql (13.6)
输入 "help" 获取帮助。
pg_jsonschema=# create extension pg_jsonschema;
CREATE EXTENSION
pg_jsonschema=# select json_matches_schema('{"type": "object"}', '{}');
json_matches_schema
---------------------
t
(1 行)
有关更完整的安装指南,请参阅 pgrx 文档。
先前工作
postgres-json-schema - 用 PL/pgSQL 编写的 JSON Schema PostgreSQL 扩展
is_jsonb_valid - 用 C 编写的 JSON Schema PostgreSQL 扩展
pgx_json_schema - 使用 pgrx + jsonschema 编写的 JSON Schema PostgreSQL 扩展
基准测试
系统
- 2021 MacBook Pro M1 Max (32GB)
- macOS 14.2
- PostgreSQL 16.2
设置
对 20k 个唯一插入验证以下模式
{
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "string"}
}
}
create table bench_test_pg_jsonschema(
meta jsonb,
check (
jsonb_matches_schema(
'{"type": "object", "properties": {"a": {"type": "number"}, "b": {"type": "string"}}}',
meta
)
)
);
insert into bench_test_pg_jsonschema(meta)
select
json_build_object(
'a', i,
'b', i::text
)
from
generate_series(1, 20000) t(i);
-- 查询在 351 毫秒内完成
作为比较,使用 postgres-json-schema 的 validate_json_schema
函数进行的等效测试用时 5.54 秒。在这个 JSON schema 示例中,pg_jsonschema 的速度提升了约 15 倍,随着 schema 变得更复杂,这种速度优势会迅速增加。