SlideShare a Scribd company logo
예제로 살펴보는
포스트그레스큐엘의 독특한
SQL
다른 데이터베이스랑 호환되지 않아요
PgDay.Seoul 2021, 김상기
PgDay.Seoul 2021
Ver. 14 새 SQL
● WITH RECURSIVE ... (...)
SEARCH DEPTH FIRST BY order_column SET column_name
SELECT … ORDER BY column_name
● WITH RECURSIVE ... (...)
CYCLE cycle_check_column SET is_cycle USING column_name
SELECT … WHERE is_cycle = false ORDER BY column_name
● jsonb_data['key1']['subkey2']::int + 1
● SELECT range_agg(range_type_column) FROM table
2
PgDay.Seoul 2021
Ver. 14 새 SQL - WITH RECURSIVE
3
WITH RECURSIVE t AS (
SELECT *, addrname AS conname
FROM addrcodes
WHERE addrid = '380704'
UNION ALL
SELECT a.*, a.addrname || ' ' || t.conname
FROM addrcodes a, t
WHERE a.addrid = t.upaddr
)
SEARCH DEPTH FIRST BY addrname SET path
CYCLE addrname SET is_cycle USING path2
SELECT conname
FROM t
WHERE is_cycle = false
ORDER BY path DESC
FETCH FIRST 1 ROW ONLY
PgDay.Seoul 2021
Ver. 14 새 SQL - jsonb Subscripting
"public.t_jsonb" 테이블
필드명 | 종류 | NULL허용 | 초기값
--------------+-------+----------+--------
jsonb_column | jsonb | |
postgres=# SELECT jsonb_pretty(jsonb_column)
FROM t_jsonb
jsonb_pretty
{
"key1": {
"subkey1": 1,
"subkey2": 3
}
}
4
postgres=# SELECT
jsonb_column['key1']['subkey2'] FROM t_jsonb;
jsonb_column
--------------
3
postgres=# UPDATE t_jsonb SET
jsonb_column['key1']['subkey2'] =
to_jsonb((jsonb_column['key1']['subkey2'])::in
t + 1) where jsonb_column['key1']['subkey1'] =
'1'; -- 문자열은 '문자열'(X), '"문자열"'(O)
postgres=# select ...;
jsonb_pretty
{
"key1": {
"subkey1": 1,
"subkey2": 4
}
}
PgDay.Seoul 2021
Ver. 14 새 SQL - multirange 자료형 1
5
이 초록 영역을 어떻게 구할 것인가? multirange!
dTS *multirange
PgDay.Seoul 2021
Ver. 14 새 SQL - multirange 자료형 2
6
postgres=# SELECT lower(unnest), upper(unnest) - 1
FROM (SELECT unnest(
'{[2021-08-01, 2021-10-01)}'::datemultirange
- range_agg(daterange(startdate, enddate, '[]')))
FROM place_term
WHERE startdate > '2021-08-01' AND enddate < '2021-09-30') AS t;
lower | ?column?
------------+------------
2021-08-01 | 2021-08-03
2021-09-27 | 2021-09-30
(2개 행)
PgDay.Seoul 2021
대한민국 구석구석 자료 소개
7
● 한국관광공사에서 제공하는 공공 그래프 데이터베이스 자료
출처: http://data.visitkorea.or.kr/linked_open_data
● 이것을 PostgreSQL용으로 변환하고, 관계형 데이터베이스 모델로 바꿨다.
● 엔터티 관계도:
https://github.com/i0seph/visitkorea_for_pg/blob/master/graph2rdbms/visitkor
ea-erd.pdf
● flask 로 만든 샘플 코드는 그 위에
PgDay.Seoul 2021
예제 구성 - 첫화면
8
검색: 인덱스를 사용하는 %검색%
분류 검색: 계층형 쿼리와 그 외
추천 장소: 임의 뽑기 최적화
오늘 행사 중인 축제: 범위 자료형 검색
PgDay.Seoul 2021
예제 구성 - 설명 화면
9
분류와 지역: 계층형 쿼리
각 항목: key-value 자료 구조처리
인근 추천 장소: 위경도 인덱스 탐색 및 거리
계산
PgDay.Seoul 2021
SQL 1: DISTINCT ON
10
● 1:N 관계에서 N 자료 가운데 하나만 뽑기
○ 전통적으로 row_number() 윈도우 함수를 이용한 인라인뷰를 만들고, 그 값이 1인 것을 뽑음
SELECT …. FROM (
SELECT …, row_number() OVER (PARTITION BY … ORDER BY …) as no
FROM …) AS t WHERE no = 1
○ 이 복잡한 쿼리가 DISTINCT ON으로 해결 가능함 (sql_search_list.py)
SELECT DISTINCT ON (a.place_name, a.place_id)
a.place_id, a.place_name, b.imgurl
FROM place a LEFT JOIN place_images b ON a.place_id = b.place_id
WHERE place_name ~* to_regexp('자연 휴양림')
ORDER BY a.place_name, a.place_id, b.imgurl
FETCH FIRST 50 ROWS ONLY
PgDay.Seoul 2021
SQL 2: 문자열 검색
11
● 전통 기법: LIKE, ILIKE
○ 인덱스를 사용하지 않아 테이블 전체 탐색을 함, WHERE place_name LIKE %자연휴양림%
○ 단어 분리 상황에서 AND 연산 중복 비용 발생, WHERE place_name LIKE %자연% AND place_name
LIKE %휴양림%
● pg_trgm 확장 모듈과 정규식을 이용한 문제 풀기 (sql_search_list.py)
1. CREATE EXTENSION pg_trgm
2. CREATE INDEX place_name_i ON place USING gist_trgm_ops (place_name)
3. CREATE OR REPLACE FUNCTION to_regexp(text) RETURNS text LANGUAGE sql
IMMUTABLE AS $function$
SELECT string_agg('(?=.*' || a || ')','') FROM
UNNEST(tsvector_to_array(to_tsvector('simple', $1))) a
$function$
4. SELECT ...
FROM place a LEFT JOIN place_images b ON a.place_id = b.place_id
WHERE a.place_name ~* to_regexp('자연 휴양림')
...
PgDay.Seoul 2021
SQL 3: 배열 검색
12
● 전통 기법: IN
○ WHERE col IN (1,2,3,4)
● pg의 또 다른 문법: ANY
○ WHERE col = ANY(ARRAY[1,2,3,4])
○ 더 복잡한 문법을 왜 쓰지? SQLAlchemy 모듈에서 변수 바인딩이 쉬워짐
○ sql_place_list.py 참조
SELECT addrid FROM addrcodes WHERE upaddr = ANY(:locastr)
query_string으로 받은 문자열 loca 값을 loca.split() 함수로 배열 locastr 으로 바꾸고
그것을 그대로 쿼리로 넘겨 넘겨주면, SQLAlchemy 모듈이 알아서 처리해줌
○ 대부분 응용 프로그램 pg용 DB 드라이버들이 이 배열처리를 편하게 쓸 수 있도록
각자의 방법을 제공함
PgDay.Seoul 2021
SQL 4: 실무 예제와 쿼리 최적화
13
SELECT DISTINCT ON (a.place_id, a.place_name)
a.place_id, a.place_name, c.imgurl
FROM place a,
(SELECT place_id FROM place
WHERE loca IN (SELECT addrid FROM addrcodes WHERE upaddr = ANY (ARRAY['380300']))
AND cate IN ( WITH RECURSIVE t AS (
SELECT * FROM tourism WHERE uptour = ANY (ARRAY['A05', 'B02'])
UNION ALL
SELECT a.* FROM tourism a, t WHERE a.uptour = t.tourid)
SELECT tourid FROM t WHERE length(tourid) = 9)
ORDER BY place_name FETCH FIRST 50 ROWS ONLY) b
LEFT JOIN place_images c ON b.place_id = c.place_id
WHERE a.place_id = b.place_id
ORDER BY a.place_name, a.place_id, c.imgurl;
● 전라남도 곡성군 음식점과 숙박 시설 찾는 쿼리
PgDay.Seoul 2021
SQL 5: TABLESAMPLE - 임의 자료 탐색
14
● 전통적인 ORDER BY random() LIMIT 10 구문은 테이블 전체를 탐색한다.
● TABLESAMPLE {SYSTEM|BERNOULLI} (퍼센트)
○ SYSTEM: 임의 블록으로 가서 그 해당 자료 수 만큼 추출 (퍼센트 값이 아주 작다면 하나의
블록 읽기만 하는데, 그 안에 비슷한 자료들이 몰려 있으면 임의 추출의 의미가 퇴색함)
○ BERNOULLI: 블록 기준으로 해당 퍼센트 확률만큼 블록을 선택하고 거기서 자료를 추출
(확률값이 낮을 수록 더 많은 블록을 뒤지게 된다. 반면 임의 추출 품질은 좋아짐)
● place_images 테이블(블록수: 약 1,400개) 대상 베르누이 샘풀링 확률 보면,
○ 1% = 18, 0.1% = 43, 0.01% = 600 정도의 블록을 읽음으로 예제 코드에서는 0.05로 설정함
○ 이처럼 베르누이 확률을 사용할 경우는 비용과 품질 사이 적정값을 찾아야 함
SELECT DISTINCT ON (place_id) place_id, imgurl
FROM ( SELECT place_id, imgurl FROM place_images
TABLESAMPLE BERNOULLI (0.05) LIMIT 20
) a ORDER BY place_id, imgurl LIMIT 10
PgDay.Seoul 2021
SQL 6: 범위 자료형 탐색 - 오늘 방문하면 되는 곳
15
● 전통적인 범위, 기간 검색은 시작값(lower)과 마침값(upper)을 저장하고, >=,
<, BETWEEN 연산으로 처리 함.
○ 시작날짜가 오늘보다 작거나 같고, 마침날짜가 오늘보다 크거나 같은 것
startdate <= current_date and enddate >= current_date
● 범위자료형을 쓰면
○ 행사기간들 중에 오늘이 포함된 것
term @> current_date
● 전통적인 모델링을 바꿀 수 없다면 (sql_festa_list.py)
○ 범위자료형 변환 함수를 사용하는 함수 기반 인덱스를 만들어 쓴다
CREATE INDEX term_range_i ON place_term USING gist (daterange(startdate, enddate, '[]'));
SELECT * FROM place_term
WHERE daterange(startdate, enddate, '[]') @> CURRENT_DATE
AND daterange(date_trunc('month' , current_timestamp)::date, (date_trunc('month' ,
current_timestamp) + interval '1 month')::date) @> daterange(startdate, enddate, '[]')
PgDay.Seoul 2021
SQL 7: key-value 자료 처리 - json
16
● 처음부터 jsonb, json 자료형으로 DB에 넣고 꺼내기
○ json 양식 검사 문제
○ jsonb 인 경우 key 정렬 문제
○ 해당 칼럼이 toast에 저장되는 문제
● DB에는 관계형으로 저장되고, 응용프로그램에서 json으로 다루기
○ 어디서 json으로 변환할 것인가?
■ DB측: json_build_*(), json_agg() 함수를 사용
■ APP측: DB result row의 유연한 json 변환 작업을 제공해야함
PgDay.Seoul 2021
SQL 7: key-value 자료 처리 - 예제
17
● 예제에서는 N:N 관계형 모델링 자료에 대한 처리를 다룬다.
● DB 측 ● 응용프로그램 측(python flask)
SELECT b.attname, a.v
FROM place_attrib a JOIN attnames b ON a.attid = b.attid
WHERE place_id = 130679;
attname | v
----------------------+------------------------------------
규모 | 지상 3층
신용카드사용여부 | 불가능
전화번호 | 033-462-2303
유모차대여서비스 | 불가능
주소 | 강원도 인제군 북면 만해로 91
이용요금 | 무료
애완동물동반가능여부 | 불가능
우편번호 | 24606
이용시간 | 09:00~17:00
쉬는날 | 매주 월요일, 1월 1일, 설/추석 당일
주차시설 | 주차 가능
@app.route('/ajax/getattrib/<int:place_id>')
def get_attribute(place_id):
mod = __import__('sql_get_attribute')
d = sql(mod.query, {'place_id': place_id})
return jsonify([dict(row) for row in d.fetchall()])
PgDay.Seoul 2021
SQL 8: 위경도 처리
18
● 위경도값 처리를 위한 작업
○ WGS84 좌표계를 사용하는 위경도값이라면,
가장 단순한 방법으로 earthdistance 확장 모듈을 사용하는 것이다.
CREATE EXTENSION earthdistance CASCADE;
ALTER TABLE place ADD position earth GENERATED ALWAYS AS (ll_to_earth(lat, long)) STORED;
-- INSERT 작업에서는 이 position 칼럼의 값으로 default를 쓴다
CREATE INDEX CONCURRENTLY place_position_i ON place USING gist (position);
-- 자료 찾기, :y1 = 현재 위도, :x1 = 현재 경도, :place_id = 현재 장소번호
-- 현재 위치에서 2Km 안에 있는 다른 장소들 찾기
SELECT place_id,
round((earth_distance(position, ll_to_earth(:y1, :x1))::numeric / 1000)::numeric, 2)::float as
distance
FROM place
WHERE earth_box(ll_to_earth(:y1, :x1), 2000) @> position AND a.place_id <> :place_id
PgDay.Seoul 2021
그 외 SQL 들
19
● 형변환자: ::
● {INSERT|UPDATE|DELETE} … RETURNING …
● JOIN UPDATE: UPDATE … FROM
● JOIN DELETE: DELETE FROM … USING …
● INSERT or UPDATE: INSERT INTO … ON CONFLICT …
● 명령어 VAULES: SELECT * FROM (VALUES(1,2,3)) t
● LATERAL 예약어: SELECT … FROM a, LATERAL (SELECT * FROM b where b.col =
a.col) …
● LISTEN & NOTIFY
PgDay.Seoul 2021
참고 자료
20
● python flask
○ flask.palletsprojects.com
● jquery
○ jquery.com
● PostgreSQL
○ postgresql.org & postgresql.kr
● 발표를 위한 샘플 코드
○ https://github.com/i0seph/visitkorea_for_pg
● PostgreSQL 한국 사용자 모임
○ https://www.facebook.com/groups/postgres.kr

More Related Content

What's hot

MySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxMySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptx
NeoClova
 
[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자
[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자
[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자
PgDay.Seoul
 
오라클 DB 아키텍처와 튜닝
오라클 DB 아키텍처와 튜닝오라클 DB 아키텍처와 튜닝
오라클 DB 아키텍처와 튜닝
철민 권
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교
Woo Yeong Choi
 
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
PgDay.Seoul
 
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
Amazon Web Services Korea
 
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
PgDay.Seoul
 
Getting started with postgresql
Getting started with postgresqlGetting started with postgresql
Getting started with postgresql
botsplash.com
 
[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화
NAVER D2
 
SQL serverのデータ破損に備える
SQL serverのデータ破損に備えるSQL serverのデータ破損に備える
SQL serverのデータ破損に備える
okumar savurou
 
Pgday bdr 천정대
Pgday bdr 천정대Pgday bdr 천정대
Pgday bdr 천정대
PgDay.Seoul
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
MongoDB
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴
Terry Cho
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
Tomoya Kawanishi
 
MySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestMySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software Test
I Goo Lee
 
MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용
I Goo Lee
 
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
PgDay.Seoul
 
Backup and-recovery2
Backup and-recovery2Backup and-recovery2
Backup and-recovery2
Command Prompt., Inc
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptx
NeoClova
 
Get to know PostgreSQL!
Get to know PostgreSQL!Get to know PostgreSQL!
Get to know PostgreSQL!
Oddbjørn Steffensen
 

What's hot (20)

MySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxMySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptx
 
[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자
[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자
[Pgday.Seoul 2017] 7. PostgreSQL DB Tuning 기업사례 - 송춘자
 
오라클 DB 아키텍처와 튜닝
오라클 DB 아키텍처와 튜닝오라클 DB 아키텍처와 튜닝
오라클 DB 아키텍처와 튜닝
 
mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교
 
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
 
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
 
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
 
Getting started with postgresql
Getting started with postgresqlGetting started with postgresql
Getting started with postgresql
 
[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화
 
SQL serverのデータ破損に備える
SQL serverのデータ破損に備えるSQL serverのデータ破損に備える
SQL serverのデータ破損に備える
 
Pgday bdr 천정대
Pgday bdr 천정대Pgday bdr 천정대
Pgday bdr 천정대
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
 
MySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestMySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software Test
 
MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용
 
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
[Pgday.Seoul 2019] Citus를 이용한 분산 데이터베이스
 
Backup and-recovery2
Backup and-recovery2Backup and-recovery2
Backup and-recovery2
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptx
 
Get to know PostgreSQL!
Get to know PostgreSQL!Get to know PostgreSQL!
Get to know PostgreSQL!
 

Similar to [Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL

효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차
희동 강
 
PostgreSQL로 배우는 SQL 기초
PostgreSQL로 배우는 SQL 기초PostgreSQL로 배우는 SQL 기초
PostgreSQL로 배우는 SQL 기초
Jiho Lee
 
Webframeworks angular js 세미나
Webframeworks angular js 세미나Webframeworks angular js 세미나
Webframeworks angular js 세미나
WebFrameworks
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트
[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트
[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트
S.O.P.T - Shout Our Passion Together
 
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
Kenu, GwangNam Heo
 
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
엑셈
 
회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemy회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemy
Jc Kim
 
R 스터디 세번째
R 스터디 세번째R 스터디 세번째
R 스터디 세번째
Jaeseok Park
 
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
PgDay.Seoul
 
PostGIS 시작하기
PostGIS 시작하기PostGIS 시작하기
PostGIS 시작하기
Byeong-Hyeok Yu
 
Fundamentals of Oracle SQL
Fundamentals of Oracle SQLFundamentals of Oracle SQL
Fundamentals of Oracle SQL
JAEGEUN YU
 
R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1
happychallenge
 
개발자들이 흔히 실수하는 SQL 7가지
개발자들이 흔히 실수하는 SQL 7가지개발자들이 흔히 실수하는 SQL 7가지
개발자들이 흔히 실수하는 SQL 7가지
JungGeun Lee
 
파이썬 데이터 분석 3종세트
파이썬 데이터 분석 3종세트파이썬 데이터 분석 3종세트
파이썬 데이터 분석 3종세트
itproman35
 
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
JiandSon
 
파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄
SeongHyun Ahn
 
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracleTABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
엑셈
 
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracleSQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
엑셈
 
공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)
H.J. SIM
 
MySQL과 PHP
MySQL과 PHPMySQL과 PHP
MySQL과 PHP
Yoonwhan Lee
 

Similar to [Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL (20)

효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차
 
PostgreSQL로 배우는 SQL 기초
PostgreSQL로 배우는 SQL 기초PostgreSQL로 배우는 SQL 기초
PostgreSQL로 배우는 SQL 기초
 
Webframeworks angular js 세미나
Webframeworks angular js 세미나Webframeworks angular js 세미나
Webframeworks angular js 세미나
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트
[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트
[SOPT] 데이터 구조 및 알고리즘 스터디 - #01 : 개요, 점근적 복잡도, 배열, 연결리스트
 
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
 
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
 
회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemy회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemy
 
R 스터디 세번째
R 스터디 세번째R 스터디 세번째
R 스터디 세번째
 
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개[Pgday.Seoul 2018]  PostgreSQL 11 새 기능 소개
[Pgday.Seoul 2018] PostgreSQL 11 새 기능 소개
 
PostGIS 시작하기
PostGIS 시작하기PostGIS 시작하기
PostGIS 시작하기
 
Fundamentals of Oracle SQL
Fundamentals of Oracle SQLFundamentals of Oracle SQL
Fundamentals of Oracle SQL
 
R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1
 
개발자들이 흔히 실수하는 SQL 7가지
개발자들이 흔히 실수하는 SQL 7가지개발자들이 흔히 실수하는 SQL 7가지
개발자들이 흔히 실수하는 SQL 7가지
 
파이썬 데이터 분석 3종세트
파이썬 데이터 분석 3종세트파이썬 데이터 분석 3종세트
파이썬 데이터 분석 3종세트
 
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
 
파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄파이썬 데이터베이스 연결 2탄
파이썬 데이터베이스 연결 2탄
 
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracleTABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
TABLE ACCESS 패턴을 이용한 SQL 튜닝_Wh oracle
 
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracleSQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
 
공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)
 
MySQL과 PHP
MySQL과 PHPMySQL과 PHP
MySQL과 PHP
 

More from PgDay.Seoul

[pgday.Seoul 2022] PostgreSQL with Google Cloud
[pgday.Seoul 2022] PostgreSQL with Google Cloud[pgday.Seoul 2022] PostgreSQL with Google Cloud
[pgday.Seoul 2022] PostgreSQL with Google Cloud
PgDay.Seoul
 
[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기
[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기
[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기
PgDay.Seoul
 
[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기
[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기
[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기
PgDay.Seoul
 
[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDW[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDW
PgDay.Seoul
 
[Pgday.Seoul 2018] PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
[Pgday.Seoul 2018]  PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha[Pgday.Seoul 2018]  PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
[Pgday.Seoul 2018] PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
PgDay.Seoul
 
[Pgday.Seoul 2018] PostgreSQL Authentication with FreeIPA
[Pgday.Seoul 2018]  PostgreSQL Authentication with FreeIPA[Pgday.Seoul 2018]  PostgreSQL Authentication with FreeIPA
[Pgday.Seoul 2018] PostgreSQL Authentication with FreeIPA
PgDay.Seoul
 
[Pgday.Seoul 2018] AWS Cloud 환경에서 PostgreSQL 구축하기
[Pgday.Seoul 2018]  AWS Cloud 환경에서 PostgreSQL 구축하기[Pgday.Seoul 2018]  AWS Cloud 환경에서 PostgreSQL 구축하기
[Pgday.Seoul 2018] AWS Cloud 환경에서 PostgreSQL 구축하기
PgDay.Seoul
 
[Pgday.Seoul 2018] Greenplum의 노드 분산 설계
[Pgday.Seoul 2018]  Greenplum의 노드 분산 설계[Pgday.Seoul 2018]  Greenplum의 노드 분산 설계
[Pgday.Seoul 2018] Greenplum의 노드 분산 설계
PgDay.Seoul
 
[Pgday.Seoul 2018] replacing oracle with edb postgres
[Pgday.Seoul 2018] replacing oracle with edb postgres[Pgday.Seoul 2018] replacing oracle with edb postgres
[Pgday.Seoul 2018] replacing oracle with edb postgres
PgDay.Seoul
 
[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우
[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우
[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우
PgDay.Seoul
 
[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종
[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종
[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종
PgDay.Seoul
 
[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진
[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진
[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진
PgDay.Seoul
 
[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명
[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명
[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명
PgDay.Seoul
 
[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오
[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오
[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오
PgDay.Seoul
 
PostgreSQL 9.6 새 기능 소개
PostgreSQL 9.6 새 기능 소개PostgreSQL 9.6 새 기능 소개
PostgreSQL 9.6 새 기능 소개
PgDay.Seoul
 
pg_hba.conf 이야기
pg_hba.conf 이야기pg_hba.conf 이야기
pg_hba.conf 이야기
PgDay.Seoul
 
Pg report 20161010_02
Pg report 20161010_02Pg report 20161010_02
Pg report 20161010_02
PgDay.Seoul
 

More from PgDay.Seoul (17)

[pgday.Seoul 2022] PostgreSQL with Google Cloud
[pgday.Seoul 2022] PostgreSQL with Google Cloud[pgday.Seoul 2022] PostgreSQL with Google Cloud
[pgday.Seoul 2022] PostgreSQL with Google Cloud
 
[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기
[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기
[Pgday.Seoul 2020] 포스트그레스큐엘 자국어화 이야기
 
[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기
[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기
[Pgday.Seoul 2019] AppOS 고성능 I/O 확장 모듈로 성능 10배 향상시키기
 
[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDW[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDW
 
[Pgday.Seoul 2018] PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
[Pgday.Seoul 2018]  PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha[Pgday.Seoul 2018]  PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
[Pgday.Seoul 2018] PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
 
[Pgday.Seoul 2018] PostgreSQL Authentication with FreeIPA
[Pgday.Seoul 2018]  PostgreSQL Authentication with FreeIPA[Pgday.Seoul 2018]  PostgreSQL Authentication with FreeIPA
[Pgday.Seoul 2018] PostgreSQL Authentication with FreeIPA
 
[Pgday.Seoul 2018] AWS Cloud 환경에서 PostgreSQL 구축하기
[Pgday.Seoul 2018]  AWS Cloud 환경에서 PostgreSQL 구축하기[Pgday.Seoul 2018]  AWS Cloud 환경에서 PostgreSQL 구축하기
[Pgday.Seoul 2018] AWS Cloud 환경에서 PostgreSQL 구축하기
 
[Pgday.Seoul 2018] Greenplum의 노드 분산 설계
[Pgday.Seoul 2018]  Greenplum의 노드 분산 설계[Pgday.Seoul 2018]  Greenplum의 노드 분산 설계
[Pgday.Seoul 2018] Greenplum의 노드 분산 설계
 
[Pgday.Seoul 2018] replacing oracle with edb postgres
[Pgday.Seoul 2018] replacing oracle with edb postgres[Pgday.Seoul 2018] replacing oracle with edb postgres
[Pgday.Seoul 2018] replacing oracle with edb postgres
 
[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우
[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우
[Pgday.Seoul 2017] 6. GIN vs GiST 인덱스 이야기 - 박진우
 
[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종
[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종
[Pgday.Seoul 2017] 5. 테드폴허브(올챙이) PostgreSQL 확장하기 - 조현종
 
[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진
[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진
[Pgday.Seoul 2017] 1. PostGIS의 사례로 본 PostgreSQL 확장 - 장병진
 
[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명
[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명
[Pgday.Seoul 2017] 4. Composite Type/JSON 파라미터를 활용한 TVP구현(with C#, JAVA) - 지현명
 
[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오
[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오
[Pgday.Seoul 2017] 3. PostgreSQL WAL Buffers, Clog Buffers Deep Dive - 이근오
 
PostgreSQL 9.6 새 기능 소개
PostgreSQL 9.6 새 기능 소개PostgreSQL 9.6 새 기능 소개
PostgreSQL 9.6 새 기능 소개
 
pg_hba.conf 이야기
pg_hba.conf 이야기pg_hba.conf 이야기
pg_hba.conf 이야기
 
Pg report 20161010_02
Pg report 20161010_02Pg report 20161010_02
Pg report 20161010_02
 

[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL

  • 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL 다른 데이터베이스랑 호환되지 않아요 PgDay.Seoul 2021, 김상기
  • 2. PgDay.Seoul 2021 Ver. 14 새 SQL ● WITH RECURSIVE ... (...) SEARCH DEPTH FIRST BY order_column SET column_name SELECT … ORDER BY column_name ● WITH RECURSIVE ... (...) CYCLE cycle_check_column SET is_cycle USING column_name SELECT … WHERE is_cycle = false ORDER BY column_name ● jsonb_data['key1']['subkey2']::int + 1 ● SELECT range_agg(range_type_column) FROM table 2
  • 3. PgDay.Seoul 2021 Ver. 14 새 SQL - WITH RECURSIVE 3 WITH RECURSIVE t AS ( SELECT *, addrname AS conname FROM addrcodes WHERE addrid = '380704' UNION ALL SELECT a.*, a.addrname || ' ' || t.conname FROM addrcodes a, t WHERE a.addrid = t.upaddr ) SEARCH DEPTH FIRST BY addrname SET path CYCLE addrname SET is_cycle USING path2 SELECT conname FROM t WHERE is_cycle = false ORDER BY path DESC FETCH FIRST 1 ROW ONLY
  • 4. PgDay.Seoul 2021 Ver. 14 새 SQL - jsonb Subscripting "public.t_jsonb" 테이블 필드명 | 종류 | NULL허용 | 초기값 --------------+-------+----------+-------- jsonb_column | jsonb | | postgres=# SELECT jsonb_pretty(jsonb_column) FROM t_jsonb jsonb_pretty { "key1": { "subkey1": 1, "subkey2": 3 } } 4 postgres=# SELECT jsonb_column['key1']['subkey2'] FROM t_jsonb; jsonb_column -------------- 3 postgres=# UPDATE t_jsonb SET jsonb_column['key1']['subkey2'] = to_jsonb((jsonb_column['key1']['subkey2'])::in t + 1) where jsonb_column['key1']['subkey1'] = '1'; -- 문자열은 '문자열'(X), '"문자열"'(O) postgres=# select ...; jsonb_pretty { "key1": { "subkey1": 1, "subkey2": 4 } }
  • 5. PgDay.Seoul 2021 Ver. 14 새 SQL - multirange 자료형 1 5 이 초록 영역을 어떻게 구할 것인가? multirange! dTS *multirange
  • 6. PgDay.Seoul 2021 Ver. 14 새 SQL - multirange 자료형 2 6 postgres=# SELECT lower(unnest), upper(unnest) - 1 FROM (SELECT unnest( '{[2021-08-01, 2021-10-01)}'::datemultirange - range_agg(daterange(startdate, enddate, '[]'))) FROM place_term WHERE startdate > '2021-08-01' AND enddate < '2021-09-30') AS t; lower | ?column? ------------+------------ 2021-08-01 | 2021-08-03 2021-09-27 | 2021-09-30 (2개 행)
  • 7. PgDay.Seoul 2021 대한민국 구석구석 자료 소개 7 ● 한국관광공사에서 제공하는 공공 그래프 데이터베이스 자료 출처: http://data.visitkorea.or.kr/linked_open_data ● 이것을 PostgreSQL용으로 변환하고, 관계형 데이터베이스 모델로 바꿨다. ● 엔터티 관계도: https://github.com/i0seph/visitkorea_for_pg/blob/master/graph2rdbms/visitkor ea-erd.pdf ● flask 로 만든 샘플 코드는 그 위에
  • 8. PgDay.Seoul 2021 예제 구성 - 첫화면 8 검색: 인덱스를 사용하는 %검색% 분류 검색: 계층형 쿼리와 그 외 추천 장소: 임의 뽑기 최적화 오늘 행사 중인 축제: 범위 자료형 검색
  • 9. PgDay.Seoul 2021 예제 구성 - 설명 화면 9 분류와 지역: 계층형 쿼리 각 항목: key-value 자료 구조처리 인근 추천 장소: 위경도 인덱스 탐색 및 거리 계산
  • 10. PgDay.Seoul 2021 SQL 1: DISTINCT ON 10 ● 1:N 관계에서 N 자료 가운데 하나만 뽑기 ○ 전통적으로 row_number() 윈도우 함수를 이용한 인라인뷰를 만들고, 그 값이 1인 것을 뽑음 SELECT …. FROM ( SELECT …, row_number() OVER (PARTITION BY … ORDER BY …) as no FROM …) AS t WHERE no = 1 ○ 이 복잡한 쿼리가 DISTINCT ON으로 해결 가능함 (sql_search_list.py) SELECT DISTINCT ON (a.place_name, a.place_id) a.place_id, a.place_name, b.imgurl FROM place a LEFT JOIN place_images b ON a.place_id = b.place_id WHERE place_name ~* to_regexp('자연 휴양림') ORDER BY a.place_name, a.place_id, b.imgurl FETCH FIRST 50 ROWS ONLY
  • 11. PgDay.Seoul 2021 SQL 2: 문자열 검색 11 ● 전통 기법: LIKE, ILIKE ○ 인덱스를 사용하지 않아 테이블 전체 탐색을 함, WHERE place_name LIKE %자연휴양림% ○ 단어 분리 상황에서 AND 연산 중복 비용 발생, WHERE place_name LIKE %자연% AND place_name LIKE %휴양림% ● pg_trgm 확장 모듈과 정규식을 이용한 문제 풀기 (sql_search_list.py) 1. CREATE EXTENSION pg_trgm 2. CREATE INDEX place_name_i ON place USING gist_trgm_ops (place_name) 3. CREATE OR REPLACE FUNCTION to_regexp(text) RETURNS text LANGUAGE sql IMMUTABLE AS $function$ SELECT string_agg('(?=.*' || a || ')','') FROM UNNEST(tsvector_to_array(to_tsvector('simple', $1))) a $function$ 4. SELECT ... FROM place a LEFT JOIN place_images b ON a.place_id = b.place_id WHERE a.place_name ~* to_regexp('자연 휴양림') ...
  • 12. PgDay.Seoul 2021 SQL 3: 배열 검색 12 ● 전통 기법: IN ○ WHERE col IN (1,2,3,4) ● pg의 또 다른 문법: ANY ○ WHERE col = ANY(ARRAY[1,2,3,4]) ○ 더 복잡한 문법을 왜 쓰지? SQLAlchemy 모듈에서 변수 바인딩이 쉬워짐 ○ sql_place_list.py 참조 SELECT addrid FROM addrcodes WHERE upaddr = ANY(:locastr) query_string으로 받은 문자열 loca 값을 loca.split() 함수로 배열 locastr 으로 바꾸고 그것을 그대로 쿼리로 넘겨 넘겨주면, SQLAlchemy 모듈이 알아서 처리해줌 ○ 대부분 응용 프로그램 pg용 DB 드라이버들이 이 배열처리를 편하게 쓸 수 있도록 각자의 방법을 제공함
  • 13. PgDay.Seoul 2021 SQL 4: 실무 예제와 쿼리 최적화 13 SELECT DISTINCT ON (a.place_id, a.place_name) a.place_id, a.place_name, c.imgurl FROM place a, (SELECT place_id FROM place WHERE loca IN (SELECT addrid FROM addrcodes WHERE upaddr = ANY (ARRAY['380300'])) AND cate IN ( WITH RECURSIVE t AS ( SELECT * FROM tourism WHERE uptour = ANY (ARRAY['A05', 'B02']) UNION ALL SELECT a.* FROM tourism a, t WHERE a.uptour = t.tourid) SELECT tourid FROM t WHERE length(tourid) = 9) ORDER BY place_name FETCH FIRST 50 ROWS ONLY) b LEFT JOIN place_images c ON b.place_id = c.place_id WHERE a.place_id = b.place_id ORDER BY a.place_name, a.place_id, c.imgurl; ● 전라남도 곡성군 음식점과 숙박 시설 찾는 쿼리
  • 14. PgDay.Seoul 2021 SQL 5: TABLESAMPLE - 임의 자료 탐색 14 ● 전통적인 ORDER BY random() LIMIT 10 구문은 테이블 전체를 탐색한다. ● TABLESAMPLE {SYSTEM|BERNOULLI} (퍼센트) ○ SYSTEM: 임의 블록으로 가서 그 해당 자료 수 만큼 추출 (퍼센트 값이 아주 작다면 하나의 블록 읽기만 하는데, 그 안에 비슷한 자료들이 몰려 있으면 임의 추출의 의미가 퇴색함) ○ BERNOULLI: 블록 기준으로 해당 퍼센트 확률만큼 블록을 선택하고 거기서 자료를 추출 (확률값이 낮을 수록 더 많은 블록을 뒤지게 된다. 반면 임의 추출 품질은 좋아짐) ● place_images 테이블(블록수: 약 1,400개) 대상 베르누이 샘풀링 확률 보면, ○ 1% = 18, 0.1% = 43, 0.01% = 600 정도의 블록을 읽음으로 예제 코드에서는 0.05로 설정함 ○ 이처럼 베르누이 확률을 사용할 경우는 비용과 품질 사이 적정값을 찾아야 함 SELECT DISTINCT ON (place_id) place_id, imgurl FROM ( SELECT place_id, imgurl FROM place_images TABLESAMPLE BERNOULLI (0.05) LIMIT 20 ) a ORDER BY place_id, imgurl LIMIT 10
  • 15. PgDay.Seoul 2021 SQL 6: 범위 자료형 탐색 - 오늘 방문하면 되는 곳 15 ● 전통적인 범위, 기간 검색은 시작값(lower)과 마침값(upper)을 저장하고, >=, <, BETWEEN 연산으로 처리 함. ○ 시작날짜가 오늘보다 작거나 같고, 마침날짜가 오늘보다 크거나 같은 것 startdate <= current_date and enddate >= current_date ● 범위자료형을 쓰면 ○ 행사기간들 중에 오늘이 포함된 것 term @> current_date ● 전통적인 모델링을 바꿀 수 없다면 (sql_festa_list.py) ○ 범위자료형 변환 함수를 사용하는 함수 기반 인덱스를 만들어 쓴다 CREATE INDEX term_range_i ON place_term USING gist (daterange(startdate, enddate, '[]')); SELECT * FROM place_term WHERE daterange(startdate, enddate, '[]') @> CURRENT_DATE AND daterange(date_trunc('month' , current_timestamp)::date, (date_trunc('month' , current_timestamp) + interval '1 month')::date) @> daterange(startdate, enddate, '[]')
  • 16. PgDay.Seoul 2021 SQL 7: key-value 자료 처리 - json 16 ● 처음부터 jsonb, json 자료형으로 DB에 넣고 꺼내기 ○ json 양식 검사 문제 ○ jsonb 인 경우 key 정렬 문제 ○ 해당 칼럼이 toast에 저장되는 문제 ● DB에는 관계형으로 저장되고, 응용프로그램에서 json으로 다루기 ○ 어디서 json으로 변환할 것인가? ■ DB측: json_build_*(), json_agg() 함수를 사용 ■ APP측: DB result row의 유연한 json 변환 작업을 제공해야함
  • 17. PgDay.Seoul 2021 SQL 7: key-value 자료 처리 - 예제 17 ● 예제에서는 N:N 관계형 모델링 자료에 대한 처리를 다룬다. ● DB 측 ● 응용프로그램 측(python flask) SELECT b.attname, a.v FROM place_attrib a JOIN attnames b ON a.attid = b.attid WHERE place_id = 130679; attname | v ----------------------+------------------------------------ 규모 | 지상 3층 신용카드사용여부 | 불가능 전화번호 | 033-462-2303 유모차대여서비스 | 불가능 주소 | 강원도 인제군 북면 만해로 91 이용요금 | 무료 애완동물동반가능여부 | 불가능 우편번호 | 24606 이용시간 | 09:00~17:00 쉬는날 | 매주 월요일, 1월 1일, 설/추석 당일 주차시설 | 주차 가능 @app.route('/ajax/getattrib/<int:place_id>') def get_attribute(place_id): mod = __import__('sql_get_attribute') d = sql(mod.query, {'place_id': place_id}) return jsonify([dict(row) for row in d.fetchall()])
  • 18. PgDay.Seoul 2021 SQL 8: 위경도 처리 18 ● 위경도값 처리를 위한 작업 ○ WGS84 좌표계를 사용하는 위경도값이라면, 가장 단순한 방법으로 earthdistance 확장 모듈을 사용하는 것이다. CREATE EXTENSION earthdistance CASCADE; ALTER TABLE place ADD position earth GENERATED ALWAYS AS (ll_to_earth(lat, long)) STORED; -- INSERT 작업에서는 이 position 칼럼의 값으로 default를 쓴다 CREATE INDEX CONCURRENTLY place_position_i ON place USING gist (position); -- 자료 찾기, :y1 = 현재 위도, :x1 = 현재 경도, :place_id = 현재 장소번호 -- 현재 위치에서 2Km 안에 있는 다른 장소들 찾기 SELECT place_id, round((earth_distance(position, ll_to_earth(:y1, :x1))::numeric / 1000)::numeric, 2)::float as distance FROM place WHERE earth_box(ll_to_earth(:y1, :x1), 2000) @> position AND a.place_id <> :place_id
  • 19. PgDay.Seoul 2021 그 외 SQL 들 19 ● 형변환자: :: ● {INSERT|UPDATE|DELETE} … RETURNING … ● JOIN UPDATE: UPDATE … FROM ● JOIN DELETE: DELETE FROM … USING … ● INSERT or UPDATE: INSERT INTO … ON CONFLICT … ● 명령어 VAULES: SELECT * FROM (VALUES(1,2,3)) t ● LATERAL 예약어: SELECT … FROM a, LATERAL (SELECT * FROM b where b.col = a.col) … ● LISTEN & NOTIFY
  • 20. PgDay.Seoul 2021 참고 자료 20 ● python flask ○ flask.palletsprojects.com ● jquery ○ jquery.com ● PostgreSQL ○ postgresql.org & postgresql.kr ● 발표를 위한 샘플 코드 ○ https://github.com/i0seph/visitkorea_for_pg ● PostgreSQL 한국 사용자 모임 ○ https://www.facebook.com/groups/postgres.kr