#title JSON [[TableOfContents]] ==== JSON 데이터 타입 ==== {{{ CREATE TABLE posts ( id serial NOT NULL, meta JSON ); }}} 입력은 valid한? well-formed? json 타입이어야 입력된다. {{{ INSERT INTO posts (id, meta) VALUES ( 1, '{ "author": "outsider", "authorId": 43434, "sns": { "facebook": "https://facebook.com", "twitter": "https://twitter.com" }, "createAt": "2014-06-14", "category": ["pg", "tech", "dev"] }' ); }}} ==== json vs jsonb ==== * json 자료형은 9.2 버전, 입력된 그 자료 그대로 저장 * jsonb 자료형은 9.4 버전, 의미단위(key-value 기준)로 선처리를 해서 저장하므로 입력부하 있음. * 공백문자를 무시하며, * value 값은 적당한 형변환을 하며, * 그 key 이름이 중복될 경우는 마지막 것을 사용하며, * '''key는 정렬'''되며, * @> 등과 같은 jsonb 데이터 타입에만 사용할 수 있는 부가 연산자들이 있음. ==== 조회 ==== {{{ SELECT meta->'author' FROM posts; -- "outsider" SELECT meta->'sns'->'facebook' FROM posts; -- "https://facebook.com" SELECT meta->'sns'->>'facebook' FROM posts; -- https://facebook.com SELECT meta#>'{category, 2}' FROM posts; -- "dev" }}} * -> 는 json 배열이나 객체를 반환 * ->> 는 문자열 반환(meta->'sns'->>'facebook'는 가능, meta->>'sns'->'facebook'는 불가능) * #> 는 배열값 반환(meta#>'{category, 2}'는 category 키의 3번째값) * 이런 연산자들은 where column1 ->>'hostname' = 'myhost' 과 같이 여러 절에 그대로 사용 가능 ==== JSON 키에 대한 인덱스 ==== 괄호가 2개 들어간 것을 주의 깊게 봐라. 문법이다. {{{ CREATE INDEX posts_idx1 ON posts((meta->>'authorId')); CREATE INDEX posts_idx2 ON posts((meta->'sns'->>'facebook')); }}} ==== 참고자료 ==== * http://blog.outsider.ne.kr/1061 * http://postgresql.kr/blog/postgresql_jsonb.html * http://www.postgresql.org/docs/9.4/static/functions-json.html