답변:
정규화 된 스키마에 값을 저장하는 것이 훨씬 더 효율적입니다. 즉, 현재 설정에서 작동하도록 할 수도 있습니다.
이 테이블 정의를 가정하면 :
CREATE TABLE tbl (tbl_id int, usr jsonb);
"user"는 예약어 이며 열 이름으로 큰 따옴표를 사용해야합니다. 그렇게하지 마십시오. usr
대신에 사용 합니다.
쿼리는 (현재 삭제 된) 의견처럼 보이지 않습니다.
SELECT t.tbl_id, obj.val->>'count' AS count
FROM tbl t
JOIN LATERAL jsonb_array_elements(t.usr) obj(val) ON obj.val->>'_id' = '1'
WHERE t.usr @> '[{"_id":"1"}]';
있다 3 가지 기본 단계 :
WHERE t.usr @> '[{"_id":"1"}]'
JSON 배열에서 일치하는 객체로 행을 식별합니다. 표현식은에 일반적인 GIN 인덱스를 사용하여 jsonb
열 또는 더 전문 연산자 클래스 하나 jsonb_path_ops
:
CREATE INDEX tbl_usr_gin_idx ON tbl USING gin (usr jsonb_path_ops);
추가 된 WHERE
절은 논리적으로 중복 되지만 색인을 사용해야합니다. join 절의 표현식은 지금까지 자격을 갖춘 모든 행에서 배열을 중첩 해제 한 후에 만 동일한 조건을 적용합니다 . 인덱스 지원을 통해 Postgres는 한정 객체가 포함 된 행만 처리합니다. 작은 테이블의 경우 큰 문제가되지 않으며 큰 테이블과 큰 차이 가있는 한정된 행과 큰 차이가 있습니다.
관련 :
와 Unnest jsonb_array_elements()
. ( unnest()
Postgres 배열 유형에만 유용합니다.) 실제로 일치하는 객체에만 관심이 있으므로 결합 조건을 즉시 필터링하십시오.
관련 :
'count'
적격 객체가 추출 된 후 간단히 다음을 수행하십시오 obj.val->>'count'
.
JOIN LATERAL jsonb_array_elements(t.usr) obj(value) is short for JOIN LATERAL jsonb_array_elements(t.usr) AS obj(value)
와 그 obj(value)
테이블 및 열 별칭입니다? 이 예에서 obj
테이블 별칭 인 경우 별칭은 무엇입니까? 세트가 jsonb_array_elements
? 에서 반환되었습니다 .
JOIN LATERAL jsonb_array_elements(t.usr) obj ON obj->>'_id' = '1'
에서 같은 효과가있었습니다 (한 번 select 문을 업데이트하여 value
대신 사용하십시오 val
). jsonb_array_elements(t.usr)
열이 하나만있는 테이블 을 반환하는 것으로 나타납니다 . postgres는 똑똑하고 실현되는 obj ->>
것과 동일 obj.val ->>
합니까?
obj(value)
왔습니까? 그것은에LATERAL JOIN
는,jsonb_array_elements
또는 다른 곳?