Back to blog

PostgreSQL JSON 스키마 검증: json_schema_validate 사용법과 성능 비교

August 05, 2026

작성자: Andrew Dunstan

작성일: 2026년 3월 10일

PostgreSQL jsonb 타입은 열(Column)을 미리 정의하지 않고도 다양한 구조의 데이터를 저장할 수 있다는 장점이 있습니다. 하지만 유연성이 큰 만큼, 잘못된 데이터가 입력되지 않도록 구조를 검증하는 방법도 필요합니다. jsonb 컬럼에 CHECK 제약 조건(CHECK constraint)을 적용할 수 있지만, 복잡한 검증 로직을 SQL이나 PL/pgSQL로 구현하면 코드가 빠르게 복잡해질 수 있습니다.

이 글에서는 PostgreSQL 안에서 JSON 및 JSONB 데이터를 JSON 스키마(JSON Schema) 규격에 따라 검증하는 json_schema_validate 확장 모듈을 소개합니다. CHECK 제약 조건 적용 방법, JSON Schema Draft 7 지원 기능, 오류 상세 확인 방식과 pg_jsonschema 대비 성능 테스트 결과를 살펴봅니다.

PostgreSQL 데이터베이스에서 JSON 스키마를 검증해야 하는 이유

애플리케이션 수준의 검증도 유용하지만 한계가 있습니다. 여러 애플리케이션이 동일한 테이블에 데이터를 쓰거나, 누군가 수동으로 INSERT를 실행하거나, 마이그레이션 스크립트가 검증 레이어를 우회할 수 있기 때문입니다. 데이터베이스는 모든 데이터가 거쳐 가는 최종 지점이므로, 데이터 구조(Shape)를 일관되게 강제하기에 적합합니다.

이 확장 모듈을 사용하면 다음과 같이 CHECK 제약 조건 안에서 전체 JSON 스키마를 적용할 수 있습니다.

CREATE TABLE events (
    id serial PRIMARY KEY,
    data jsonb NOT NULL CHECK (
        jsonschema_is_valid(data, '{
            "type": "object",
            "required": ["event_type", "timestamp"],
            "properties": {
                "event_type": {"type": "string", "enum": ["click", "view", "purchase"]},
                "timestamp": {"type": "string", "format": "date-time"},
                "user_id": {"type": "integer", "minimum": 1},
                "metadata": {"type": "object"}
            },
            "additionalProperties": false
        }'::jsonschema_compiled)
    )
);

여기서 ::jsonschema_compiled 캐스팅이 중요합니다. PostgreSQL이 스키마를 행마다 다시 파싱하지 않고, 한 번 파싱한 결과를 캐싱하도록 지시하기 때문입니다.


JSON Schema Draft 7 지원 기능

json_schema_validate 확장 모듈은 JSON Schema Draft 7의 다양한 기능을 지원합니다. 타입 검증, 필수 속성(required), 열거형(enum), 상수(const)와 같은 기본 기능뿐 아니라 문자열, 숫자, 배열 및 객체를 위한 검증 기능도 포함합니다.

1. 문자열 검증(String validation)

minLength, maxLength, pattern(POSIX 정규식)을 지원하며, 날짜, 이메일, IP 주소, URI, UUID와 같은 공통 형식에 대한 format 검증을 제공합니다.

SELECT jsonschema_is_valid(
    '"2024-01-15T09:30:00Z"',
    '{"type": "string", "format": "date-time"}'
); -- 결과: true

2. 숫자 검증(Numeric validation)

minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf 등을 지원합니다.

SELECT jsonschema_is_valid(
    '{"price": 9.99}',
    '{
        "type": "object",
        "properties": {
            "price": {"type": "number", "exclusiveMinimum": 0, "multipleOf": 0.01}
        }
    }'
); -- 결과: true

3. 배열 및 객체 검증

배열의 요소 수 제한(minItems/maxItems), 중복 제거(uniqueItems), 객체의 속성 이름 패턴 매칭(patternProperties) 등을 지원합니다. if/then/else를 이용한 조건부 스키마도 사용할 수 있어 데이터 값에 따라 서로 다른 검증 로직을 적용할 수 있습니다.


JSON 스키마 검증의 두 가지 모드: 불리언과 오류 상세

단순 검증이나 CHECK 제약 조건에서는 jsonschema_is_valid()를 사용해 true 또는 false를 반환받습니다. 무엇이 잘못되었는지 구체적으로 확인하려면 jsonschema_validate() 함수를 사용할 수 있습니다. 이 함수는 오류가 발생한 경로(Path)와 설명을 담은 JSON 배열을 반환합니다.

SELECT jsonschema_validate(
    '{"name": 123, "tags": "not-an-array"}',
    '{
        "properties": {
            "name": {"type": "string"},
            "tags": {"type": "array", "items": {"type": "string"}}
        }
    }'
);
-- 결과: 
-- [{"path": "name", "message": "Expected type string but got number"},
--  {"path": "tags", "message": "Expected type array but got string"}]

이 방식은 상세한 오류 메시지를 사용자에게 전달해야 하는 트리거 함수나 애플리케이션 로직을 작성할 때 유용합니다.


성능 테스트: json_schema_validate와 pg_jsonschema 비교

PostgreSQL에서 JSON 스키마를 검증하는 또 다른 옵션으로는 Supabase가 개발한 Rust 기반의 pg_jsonschema가 있습니다. 필자는 PostgreSQL 17.2 환경에서 10만 행의 데이터를 대상으로 두 확장 모듈의 성능을 비교했습니다.

테스트 시나리오json_schema_validatepg_jsonschema성능 차이
속성 및 타입 검증(jsonb)59 ms348 ms5.9배 빠름
속성 및 타입 검증(json)80 ms334 ms4.2배 빠름
정규식(Regex) 패턴 매칭(jsonb)48 ms3,502 ms73배 빠름
검증 실패 케이스(jsonb)16 ms148 ms9배 빠름

성능 차이가 발생하는 이유

  1. C 기반 네이티브 처리: json_schema_validate는 C로 작성되어 PostgreSQL 내부 데이터 표현 방식을 직접 다룹니다. Rust/serde 구조체로 변환하는 오버헤드가 없습니다.
  2. 정규식 캐싱: 정규식 테스트에서 73배 빠른 결과가 나온 이유는 컴파일된 정규식 패턴을 세션 수준의 해시 테이블에 캐싱하기 때문입니다. 이를 통해 패턴을 매번 다시 컴파일하는 비용을 줄였습니다.

json_schema_validate 지원 범위와 향후 계획

json_schema_validate는 현재 Draft 7 사양의 핵심 기능을 대부분 지원하며, 향후 prefixItems와 외부 참조($ref) 기능 등을 추가할 예정입니다. PostgreSQL의 jsonb를 활용하면서 데이터 무결성을 유지하려는 엔지니어에게 유용한 선택지가 될 수 있습니다.

이 모듈의 소스 코드는 PostgreSQL 라이선스에 따라 GitHub에서 확인할 수 있으며, PostgreSQL 14 이상의 환경에서 빌드해 사용할 수 있습니다.


PostgreSQL JSON 스키마 검증 FAQ

PostgreSQL에서 JSON Schema 검증이 필요한 이유는 무엇인가요?

여러 애플리케이션, 수동 SQL 또는 마이그레이션 스크립트가 동일한 테이블에 데이터를 쓸 수 있기 때문입니다. 데이터베이스에서 스키마를 검증하면 입력 경로와 관계없이 JSON 및 JSONB 데이터 구조를 일관되게 관리할 수 있습니다.

jsonschema_is_valid()와 jsonschema_validate()의 차이는 무엇인가요?

jsonschema_is_valid()는 검증 결과를 true 또는 false로 반환하므로 CHECK 제약 조건에 적합합니다. jsonschema_validate()는 오류가 발생한 경로와 설명이 포함된 JSON 배열을 반환하므로 상세한 오류 처리가 필요할 때 유용합니다.

jsonschema_compiled 캐스팅은 어떤 역할을 하나요?

::jsonschema_compiled 캐스팅은 PostgreSQL이 JSON 스키마를 행마다 다시 파싱하지 않도록 합니다. 스키마를 한 번 파싱한 뒤 캐싱해 반복 검증 과정의 비용을 줄이는 역할을 합니다.

json_schema_validate는 어떤 JSON Schema 버전을 지원하나요?

현재 JSON Schema Draft 7 사양의 핵심 기능을 대부분 지원합니다. 문자열, 숫자, 배열, 객체 검증과 if/then/else를 이용한 조건부 스키마를 사용할 수 있습니다.

json_schema_validate는 어떤 PostgreSQL 버전에서 사용할 수 있나요?

본문에 따르면 PostgreSQL 14 이상의 환경에서 빌드해 사용할 수 있습니다. 제시된 성능 테스트는 PostgreSQL 17.2 환경에서 10만 행의 데이터를 대상으로 진행되었습니다.


PostgreSQL의 복잡한 JSON 데이터를 더 안전하고 효율적으로 관리하고 싶으신가요? EDB 전문가가 데이터베이스 아키텍처 최적화를 지원합니다.

메일: salesinquiry@enterprisedb.com

Share this