PostgreSQL 14 ๋ฆด๋ฆฌ์Šค

14๋…„๊ฐ„์˜ ๊ฐœ๋ฐœ ๋์— PostgreSQL 2026 DBMS์˜ ์ƒˆ๋กœ์šด stable ๋ธŒ๋žœ์น˜๊ฐ€ ๊ณต๊ฐœ๋˜์—ˆ์œผ๋ฉฐ, ์ƒˆ๋กœ์šด ๋ธŒ๋žœ์น˜์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋Š” XNUMX๋…„ XNUMX์›”๊นŒ์ง€ XNUMX๋…„์— ๊ฑธ์ณ ์ถœ์‹œ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ํ˜์‹ :

  • ๋ฐฐ์—ด๊ณผ ๊ฐ™์€ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ JSON ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•œ ์ง€์›์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. SELECT ('{ "postgres": { "release": 14 }}'::jsonb)['postgres']['release']; SELECT * FROM test WHERE ์„ธ๋ถ€์ •๋ณด['attributes']['size'] = '"medium"';

    hstore ์œ ํ˜•์—์„œ ์ œ๊ณตํ•˜๋Š” ํ‚ค/๊ฐ’ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์ด ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์ด ๊ตฌ๋ฌธ์€ ์ฒ˜์Œ์— ๋ฒ”์šฉ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋˜์—ˆ์œผ๋ฉฐ ๋‚˜์ค‘์— ๋‹ค๋ฅธ ์œ ํ˜•์—๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. hstore ์œ ํ˜•์˜ ์˜ˆ: INSERT INTO mytable VALUES ('a=>b, c=>d'); SELECT h['a'] FROM mytable; UPDATE mytable SET h['c'] = 'new';

  • ๋ฒ”์œ„๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ ์œ ํ˜• ๊ณ„์—ด์ด ์ƒˆ๋กœ์šด "๋‹ค์ค‘ ๋ฒ”์œ„" ์œ ํ˜•์œผ๋กœ ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒน์น˜์ง€ ์•Š๋Š” ๊ฐ’ ๋ฒ”์œ„์˜ ์ •๋ ฌ๋œ ๋ชฉ๋ก์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ ๊ฐ ๋ฒ”์œ„ ์œ ํ˜• ์™ธ์—๋„ ์ž์ฒด ๋‹ค์ค‘ ๋ฒ”์œ„ ์œ ํ˜•์ด ์ œ์•ˆ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "int4range" ์œ ํ˜•์€ "int4multirange"์— ํ•ด๋‹นํ•˜๊ณ  "daterange" ์œ ํ˜•์€ "datemultirange"์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ๋ฒ”์œ„ ์‹œํ€€์Šค๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์ฟผ๋ฆฌ ๋””์ž์ธ์ด ๋‹จ์ˆœํ™”๋ฉ๋‹ˆ๋‹ค. SELECT '{[3,7), [8,9)}'::int4multirange; SELECT nummultirange(์ˆซ์ž ๋ฒ”์œ„(1.0, 14.0), ์ˆซ์ž ๋ฒ”์œ„(20.0, 25.0));
  • ๋‹ค์ˆ˜์˜ ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณ ๋ถ€ํ•˜ ์‹œ์Šคํ…œ์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ตœ์ ํ™”๊ฐ€ ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ํ…Œ์ŠคํŠธ์—์„œ๋Š” ์„ฑ๋Šฅ์ด 2๋ฐฐ ์ฆ๊ฐ€ํ•œ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค.
  • B-ํŠธ๋ฆฌ ์ธ๋ฑ์Šค์˜ ํšจ์œจ์„ฑ์ด ํ–ฅ์ƒ๋˜์—ˆ์œผ๋ฉฐ, ํ…Œ์ด๋ธ”์ด ์ž์ฃผ ์—…๋ฐ์ดํŠธ๋  ๋•Œ ์ธ๋ฑ์Šค๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์š”์ฒญ ํŒŒ์ดํ”„๋ผ์ธ ์ „์†ก์˜ ํด๋ผ์ด์–ธํŠธ ์ธก(libpq ์ˆ˜์ค€์—์„œ ๊ตฌํ˜„๋จ) ๋ชจ๋“œ์— ๋Œ€ํ•œ ์ง€์›์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ „ ์š”์ฒญ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค์Œ ์š”์ฒญ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ๋ชจ๋“œ๋Š” ํŒจํ‚ท ์ „๋‹ฌ ์ง€์—ฐ์ด ๊ธด ์—ฐ๊ฒฐ ์ž‘์—… ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฐ๋„ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.
  • ์—ฌ๋Ÿฌ PostgreSQL ์„œ๋ฒ„์™€ ๊ด€๋ จ๋œ ๋ถ„์‚ฐ ๊ตฌ์„ฑ์„ ์œ„ํ•œ ํ–ฅ์ƒ๋œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๋…ผ๋ฆฌ์  ๋ณต์ œ ๊ตฌํ˜„์—์„œ๋Š” ์ด์ œ ์ง„ํ–‰ ์ค‘์ธ ํŠธ๋žœ์žญ์…˜์„ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ชจ๋“œ๋กœ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ด์ง€๋ฉฐ, ์ด๋Š” ๋Œ€๊ทœ๋ชจ ํŠธ๋žœ์žญ์…˜์˜ ๋ณต์ œ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋…ผ๋ฆฌ์  ๋ณต์ œ ์ค‘์— ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ์˜ ๋…ผ๋ฆฌ์  ๋””์ฝ”๋”ฉ์ด ์ตœ์ ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์™ธ๋ถ€ ํ…Œ์ด๋ธ” ์—ฐ๊ฒฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ ๋ž˜ํผ(postgres_fdw)์— ๋ณ‘๋ ฌ ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ์ง€์›์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ˜„์žฌ ๋‹ค๋ฅธ PostgreSQL ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•  ๋•Œ๋งŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. postgres_fdw๋Š” ๋˜ํ•œ ๋ฐฐ์น˜ ๋ชจ๋“œ์—์„œ ์™ธ๋ถ€ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ "IMPORT FOREIGN SCHEMA" ์ง€์‹œ๋ฌธ์„ ์ง€์ •ํ•˜์—ฌ ๋ถ„ํ• ๋œ ํ…Œ์ด๋ธ”์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • VACUUM ์ž‘์—…(๋””์Šคํฌ ์Šคํ† ๋ฆฌ์ง€์˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘ ๋ฐ ํŒจํ‚ค์ง•) ๊ตฌํ˜„์ด ์ตœ์ ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜ ID ๋žฉ์–ด๋ผ์šด๋“œ ์กฐ๊ฑด์ด ์ƒ์„ฑ๋˜๋ฉด ํ•„์ˆ˜์ ์ด์ง€ ์•Š์€ ์ •๋ฆฌ ์ž‘์—…์„ ๊ฑด๋„ˆ๋›ฐ๋Š” ๊ธด๊ธ‰ ์ •๋ฆฌ ๋ชจ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. B-Tree ํ˜•์‹์˜ ์ธ๋ฑ์Šค ์ฒ˜๋ฆฌ ์‹œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๊ฐ์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์šด์˜์— ๋Œ€ํ•œ ํ†ต๊ณ„๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” 'ANALYZE' ์ž‘์—…์˜ ์‹คํ–‰ ์†๋„๊ฐ€ ๋Œ€ํญ ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.
  • ํ…์ŠคํŠธ ๋ธ”๋ก์ด๋‚˜ ๊ธฐํ•˜ํ•™์  ์ •๋ณด์™€ ๊ฐ™์€ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” TOAST ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์••์ถ• ๋ฐฉ๋ฒ•์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. TOAST์—์„œ๋Š” pglz ์••์ถ• ๋ฐฉ๋ฒ• ์™ธ์—๋„ LZ4 ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • DBMS ์šด์˜์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. COPY ๋ช…๋ น(pg_stat_progress_copy)์˜ ์ง„ํ–‰ ์ƒํ™ฉ, ๋ณต์ œ ์Šฌ๋กฏ์— ๋Œ€ํ•œ ํ†ต๊ณ„(pg_stat_replication_slots) ๋ฐ WAL ํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ์™€ ๊ด€๋ จ๋œ ํ™œ๋™(pg_stat_wal)์„ ์ถ”์ ํ•˜๋Š” ๋ทฐ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. pg_stat_activity ๋ฐ EXPLAIN VERBOSE์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ํ•˜์œ„ ์‹œ์Šคํ…œ์ด ๊ฐ ์š”์ฒญ์— ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ํ• ๋‹นํ•˜์—ฌ ์š”์ฒญ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” Compute_query_id ํ•จ์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์ฟผ๋ฆฌ์˜ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ์ˆœ์ฐจ ๋ ˆ์ฝ”๋“œ ์Šค์บ” ์ž‘์—…์˜ ๋™์‹œ ์‹คํ–‰ ์„ฑ๋Šฅ, "RETURN QUERY" ๋ช…๋ น์„ ์‚ฌ์šฉํ•œ PL/pgSQL์˜ ์ฟผ๋ฆฌ ๋ณ‘๋ ฌ ์‹คํ–‰ ๋ฐ "์—์„œ ์ฟผ๋ฆฌ์˜ ๋ณ‘๋ ฌ ์‹คํ–‰ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ฟผ๋ฆฌ ํ”Œ๋ž˜๋„ˆ์— ์ตœ์ ํ™”๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์ฒดํ™”๋œ ๋ณด๊ธฐ๋ฅผ ์ƒˆ๋กœ ๊ณ ์นฉ๋‹ˆ๋‹ค.โ€ ์ˆœํ™˜ ์ค‘์ฒฉ ๋ณ‘ํ•ฉ(์กฐ์ธ)์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ์บ์‹ฑ์— ๋Œ€ํ•œ ์ง€์›์ด ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์ด์ œ ๊ณ ๊ธ‰ ํ†ต๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„์‹์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ฆ๋ถ„ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฐฝ ๊ธฐ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ๋ธ”๋ก์—์„œ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ €์žฅ ํ”„๋กœ์‹œ์ €๋Š” ์ด์ œ "OUT" ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜ํ™˜ ๋ฐ์ดํ„ฐ ์ •์˜๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ์ง€์ •๋œ ๊ฐ„๊ฒฉ์— ๋”ฐ๋ผ ํƒ€์ž„์Šคํƒฌํ”„ ๊ฐ’์„ ๋ฐ˜์˜ฌ๋ฆผํ•˜๋Š” date_bin ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. SELECT date_bin('15๋ถ„', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); 2020-02-11 15:30:00
  • ์žฌ๊ท€ ๊ณตํ†ต ํ…Œ์ด๋ธ” ํ‘œํ˜„์‹(CTE)์—์„œ ์ฃผ๊ธฐ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ •๋ ฌํ•˜๊ณ  ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋„๋ก SQL ํ‘œ์ค€์— ์ •์˜๋œ SEARCH ๋ฐ CYCLE ํ‘œํ˜„์‹์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. WITH RECURSIVE search_tree(id, link, data) AS ( SELECT t.id, t.link, t.data FROM tree t UNION ALL SELECT t.id, t.link, t.data FROM tree t, search_tree st WHERE t. id = st.link ) ๊ฒ€์ƒ‰ ๊นŠ์ด ์šฐ์„  id SET ordercol SELECT * FROM search_tree ORDER BY ordercol;
  • psql ์œ ํ‹ธ๋ฆฌํ‹ฐ์—์„œ๋Š” ํƒญ์ด ์žˆ๋Š” ๋ช…๋ น์˜ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์ด ๊ฐœ์„ ๋˜์—ˆ๊ณ , ํ•จ์ˆ˜ ์ธ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์ด "\df" ๋ช…๋ น์— ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฉฐ, ํ‘œ์‹œ๋˜๋Š” ํ†ต๊ณ„๊ฐ€ "\dX" ๋ช…๋ น์œผ๋กœ ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ์ฝ๊ธฐ ์ „์šฉ ๋˜๋Š” ์“ฐ๊ธฐ ์ „์šฉ ๊ถŒํ•œ์„ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. pg_read_all_data ๋ฐ pg_write_all_data ์‚ฌ์ „ ์ •์˜๋œ ์—ญํ• ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ณ„ ํ…Œ์ด๋ธ”, ๋ทฐ ๋ฐ ์Šคํ‚ค๋งˆ์— ๊ถŒํ•œ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. user1์—๊ฒŒ pg_read_all_data๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒˆ๋กœ์šด ์„ค์น˜์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ md256 ๋Œ€์‹  SCRAM-SHA-5์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค(postgresql.conf ์ƒ์„ฑ ์‹œ "password_encryption" ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ด์ œ 'scram-sha-256'์œผ๋กœ ์„ค์ •๋จ).

์ถœ์ฒ˜ : opennet.ru

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€