SlideShare une entreprise Scribd logo
1  sur  20
Télécharger pour lire hors ligne
예제로 살펴보는
포스트그레스큐엘의 독특한
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

Contenu connexe

Tendances

[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PGPgDay.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
 
Postgresql database administration volume 1
Postgresql database administration volume 1Postgresql database administration volume 1
Postgresql database administration volume 1Federico Campoli
 
Linux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performanceLinux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performancePostgreSQL-Consulting
 
[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 CloudPgDay.Seoul
 
Mongodb 특징 분석
Mongodb 특징 분석Mongodb 특징 분석
Mongodb 특징 분석Daeyong Shin
 
[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기NHN FORWARD
 
Mastering PostgreSQL Administration
Mastering PostgreSQL AdministrationMastering PostgreSQL Administration
Mastering PostgreSQL AdministrationEDB
 
MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바NeoClova
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxNeoClova
 
PostgreSQL WAL for DBAs
PostgreSQL WAL for DBAs PostgreSQL WAL for DBAs
PostgreSQL WAL for DBAs PGConf APAC
 
PostgreSQL Deep Internal
PostgreSQL Deep InternalPostgreSQL Deep Internal
PostgreSQL Deep InternalEXEM
 
PostgreSQL 공간관리 살펴보기 이근오
PostgreSQL 공간관리 살펴보기 이근오PostgreSQL 공간관리 살펴보기 이근오
PostgreSQL 공간관리 살펴보기 이근오PgDay.Seoul
 
MySQL_SQL_Tunning_v0.1.3.docx
MySQL_SQL_Tunning_v0.1.3.docxMySQL_SQL_Tunning_v0.1.3.docx
MySQL_SQL_Tunning_v0.1.3.docxNeoClova
 
What is new in PostgreSQL 14?
What is new in PostgreSQL 14?What is new in PostgreSQL 14?
What is new in PostgreSQL 14?Mydbops
 
PostGreSQL Performance Tuning
PostGreSQL Performance TuningPostGreSQL Performance Tuning
PostGreSQL Performance TuningMaven Logix
 
PostgreSQL and Benchmarks
PostgreSQL and BenchmarksPostgreSQL and Benchmarks
PostgreSQL and BenchmarksJignesh Shah
 
MySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestMySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestI Goo Lee
 

Tendances (20)

[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
 
[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 인덱스 이야기 - 박진우
 
Postgresql database administration volume 1
Postgresql database administration volume 1Postgresql database administration volume 1
Postgresql database administration volume 1
 
Linux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performanceLinux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performance
 
[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
 
Mongodb 특징 분석
Mongodb 특징 분석Mongodb 특징 분석
Mongodb 특징 분석
 
[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기[2018] MySQL 이중화 진화기
[2018] MySQL 이중화 진화기
 
Mastering PostgreSQL Administration
Mastering PostgreSQL AdministrationMastering PostgreSQL Administration
Mastering PostgreSQL Administration
 
MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바MySQL Administrator 2021 - 네오클로바
MySQL Administrator 2021 - 네오클로바
 
MySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptxMySQL8.0_performance_schema.pptx
MySQL8.0_performance_schema.pptx
 
PostgreSQL WAL for DBAs
PostgreSQL WAL for DBAs PostgreSQL WAL for DBAs
PostgreSQL WAL for DBAs
 
PostgreSQL Deep Internal
PostgreSQL Deep InternalPostgreSQL Deep Internal
PostgreSQL Deep Internal
 
PostGIS 시작하기
PostGIS 시작하기PostGIS 시작하기
PostGIS 시작하기
 
PostgreSQL 공간관리 살펴보기 이근오
PostgreSQL 공간관리 살펴보기 이근오PostgreSQL 공간관리 살펴보기 이근오
PostgreSQL 공간관리 살펴보기 이근오
 
MySQL_SQL_Tunning_v0.1.3.docx
MySQL_SQL_Tunning_v0.1.3.docxMySQL_SQL_Tunning_v0.1.3.docx
MySQL_SQL_Tunning_v0.1.3.docx
 
What is new in PostgreSQL 14?
What is new in PostgreSQL 14?What is new in PostgreSQL 14?
What is new in PostgreSQL 14?
 
PostGreSQL Performance Tuning
PostGreSQL Performance TuningPostGreSQL Performance Tuning
PostGreSQL Performance Tuning
 
Get to know PostgreSQL!
Get to know PostgreSQL!Get to know PostgreSQL!
Get to know PostgreSQL!
 
PostgreSQL and Benchmarks
PostgreSQL and BenchmarksPostgreSQL and Benchmarks
PostgreSQL and Benchmarks
 
MySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software TestMySQL/MariaDB Proxy Software Test
MySQL/MariaDB Proxy Software Test
 

Similaire à [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
회사에서 써보는 SQLAlchemyJc 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
 
Fundamentals of Oracle SQL
Fundamentals of Oracle SQLFundamentals of Oracle SQL
Fundamentals of Oracle SQLJAEGEUN YU
 
R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1happychallenge
 
[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
 
개발자들이 흔히 실수하는 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
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]MongoDB
 
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
 

Similaire à [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 새 기능 소개
 
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
 
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
 
개발자들이 흔히 실수하는 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탄
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
 
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)
 

Plus de 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 FDWPgDay.Seoul
 
[Pgday.Seoul 2018] PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
[Pgday.Seoul 2018]  PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha[Pgday.Seoul 2018]  PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposha
[Pgday.Seoul 2018] PostgreSQL 성능을 위해 개발된 라이브러리 OS 소개 apposhaPgDay.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 FreeIPAPgDay.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 postgresPgDay.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
 
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱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
 
Pgday bdr 천정대
Pgday bdr 천정대Pgday bdr 천정대
Pgday bdr 천정대PgDay.Seoul
 
Pg report 20161010_02
Pg report 20161010_02Pg report 20161010_02
Pg report 20161010_02PgDay.Seoul
 

Plus de PgDay.Seoul (17)

[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] 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 - 이근오
 
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
[Pgday.Seoul 2017] 2. PostgreSQL을 위한 리눅스 커널 최적화 - 김상욱
 
PostgreSQL 9.6 새 기능 소개
PostgreSQL 9.6 새 기능 소개PostgreSQL 9.6 새 기능 소개
PostgreSQL 9.6 새 기능 소개
 
pg_hba.conf 이야기
pg_hba.conf 이야기pg_hba.conf 이야기
pg_hba.conf 이야기
 
Pgday bdr 천정대
Pgday bdr 천정대Pgday bdr 천정대
Pgday bdr 천정대
 
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