DBA: ๋™๊ธฐํ™” ๋ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ๋ณต์žกํ•œ ์ฒ˜๋ฆฌ์šฉ(๋‹ค์–‘ํ•œ ETL ํ”„๋กœ์„ธ์Šค: ์™ธ๋ถ€ ์†Œ์Šค์™€์˜ ๊ฐ€์ ธ์˜ค๊ธฐ, ๋ณ€ํ™˜ ๋ฐ ๋™๊ธฐํ™”)๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ผ์‹œ์ ์œผ๋กœ โ€œ๊ธฐ์–ตโ€ํ•˜๊ณ  ์ฆ‰์‹œ ์‹ ์†ํ•˜๊ฒŒ ์ฒ˜๋ฆฌ ๋ญ”๊ฐ€ ๋ฐฉ๋Œ€ํ•œ ๊ฒƒ.

์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์ผ๋ฐ˜์ ์ธ ์ž‘์—…์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. "๋ฐ”๋กœ ์—ฌ๊ธฐ์— ๊ณ ๊ฐ ์€ํ–‰์—์„œ ํšŒ๊ณ„ ๋ถ€์„œ๊ฐ€ ์–ธ๋กœ๋“œ๋จ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐ›์€ ์ง€๋ถˆ๊ธˆ์„ ์‹ ์†ํ•˜๊ฒŒ ์›น์‚ฌ์ดํŠธ์— ์—…๋กœ๋“œํ•˜๊ณ  ๊ณ„์ •์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.โ€

๊ทธ๋Ÿฌ๋‚˜ ์ด "๋ฌด์–ธ๊ฐ€"์˜ ์–‘์ด ์ˆ˜๋ฐฑ ๋ฉ”๊ฐ€๋ฐ”์ดํŠธ๋กœ ์ธก์ •๋˜๊ธฐ ์‹œ์ž‘ํ•˜๊ณ  ์„œ๋น„์Šค๊ฐ€ ์—ฐ์ค‘๋ฌดํœด 24์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๊ณ„์† ์ž‘๋™ํ•ด์•ผ ํ•˜๋ฉด ์ธ์ƒ์„ ๋ง์น˜๋Š” ๋งŽ์€ ๋ถ€์ž‘์šฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
DBA: ๋™๊ธฐํ™” ๋ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
PostgreSQL๋ฟ๋งŒ ์•„๋‹ˆ๋ผ PostgreSQL์—์„œ๋„ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด ๋ชจ๋“  ๊ฒƒ์„ ๋” ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฆฌ์†Œ์Šค๋ฅผ ๋œ ์†Œ๋น„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ตœ์ ํ™”๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1. ์–ด๋””๋กœ ๋ฐฐ์†ก๋˜๋‚˜์š”?

๋จผ์ €, "์ฒ˜๋ฆฌ"ํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋””์— ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒฐ์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1.1. ์ž„์‹œ ํ…Œ์ด๋ธ”(TEMPORARY TABLE)

์›์น™์ ์œผ๋กœ PostgreSQL์˜ ๊ฒฝ์šฐ ์ž„์‹œ ํ…Œ์ด๋ธ”์€ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฏธ์‹ ์€ "๊ฑฐ๊ธฐ์˜ ๋ชจ๋“  ๊ฒƒ์€ ๋ฉ”๋ชจ๋ฆฌ์—๋งŒ ์ €์žฅ๋˜๋ฉฐ ๋๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.". ๊ทธ๋Ÿฌ๋‚˜ ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ฐจ์ด์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ๋งˆ๋‹ค ๊ณ ์œ ํ•œ "๋„ค์ž„์ŠคํŽ˜์ด์Šค"

๋‘ ๊ฐœ์˜ ์—ฐ๊ฒฐ์ด ๋™์‹œ์— ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋Š” ๊ฒฝ์šฐ CREATE TABLE x, ๊ทธ๋Ÿฌ๋ฉด ๋ˆ„๊ตฐ๊ฐ€๋Š” ํ™•์‹คํžˆ ์–ป์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค ๋น„๊ณ ์œ ์„ฑ ์˜ค๋ฅ˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ์ฒด.

๊ทธ๋Ÿฌ๋‚˜ ๋‘˜ ๋‹ค ์‹คํ–‰์„ ์‹œ๋„ํ•˜๋ฉด CREATE TEMPORARY TABLE x, ๊ทธ๋Ÿฌ๋ฉด ๋‘˜ ๋‹ค ์ •์ƒ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋ชจ๋‘๊ฐ€ ๋‹น์‹ ์˜ ์‚ฌ๋ณธ ํ…Œ์ด๋ธ”. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋“ค ์‚ฌ์ด์—๋Š” ๊ณตํ†ต์ ์ด ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ์„ ๋Š์„ ๋•Œ "์ž๊ธฐ ํŒŒ๊ดด"

์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜๋ฉด ๋ชจ๋“  ์ž„์‹œ ํ…Œ์ด๋ธ”์ด ์ž๋™์œผ๋กœ ์‚ญ์ œ๋˜๋ฏ€๋กœ ์ˆ˜๋™์œผ๋กœ DROP TABLE x ๊ทธ๊ฑฐ ๋นผ๊ณค ์•„๋ฌด ์˜๋ฏธ๊ฐ€ ์—†์–ด...

๋‹น์‹ ์ด ํ†ตํ•ด ์ผํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ํŠธ๋žœ์žญ์…˜ ๋ชจ๋“œ์˜ pgbouncer, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ด ์—ฐ๊ฒฐ์ด ์—ฌ์ „ํžˆ ํ™œ์„ฑ ์ƒํƒœ๋ผ๊ณ  ๊ณ„์† ๋ฏฟ๊ณ  ์žˆ์œผ๋ฉฐ ์ด ์ž„์‹œ ํ…Œ์ด๋ธ”์ด ์—ฌ์ „ํžˆ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ์—ฐ๊ฒฐ์—์„œ pgbouncer๋กœ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CREATE TEMPORARY TABLE IF NOT EXISTS x.

์‚ฌ์‹ค, ์–ด์จŒ๋“  ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด "์ด์ „ ์†Œ์œ ์ž"์˜ ๋‚จ์€ ๋ฐ์ดํ„ฐ๋ฅผ "๊ฐ‘์ž๊ธฐ" ์ฐพ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹ , ๋งค๋‰ด์–ผ์„ ์ฝ๊ณ  ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•  ๋•Œ ์ถ”๊ฐ€๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค. ON COMMIT DROP - ์ฆ‰, ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋˜๋ฉด ํ…Œ์ด๋ธ”์ด ์ž๋™์œผ๋กœ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

๋น„๋ณต์ œ

์ž„์‹œ ํ…Œ์ด๋ธ”์€ ํŠน์ • ์—ฐ๊ฒฐ์—๋งŒ ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ด์ค‘์œผ๋กœ ๊ธฐ๋กํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํž™ + WAL์— ์žˆ์œผ๋ฏ€๋กœ INSERT/UPDATE/DELETE๊ฐ€ ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ž„์‹œ ํ…Œ์ด๋ธ”์€ ์—ฌ์ „ํžˆ โ€‹โ€‹"๊ฑฐ์˜ ์ผ๋ฐ˜์ ์ธ" ํ…Œ์ด๋ธ”์ด๋ฏ€๋กœ ๋ณต์ œ๋ณธ์—๋„ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ํ˜„์žฌ๋กœ์„œ๋Š” ํ•ด๋‹น ํŒจ์น˜๊ฐ€ ์˜ค๋žซ๋™์•ˆ ๋ฐฐํฌ๋˜์–ด ์™”์Šต๋‹ˆ๋‹ค.

1.2. ๊ธฐ๋ก๋˜์ง€ ์•Š์€ ํ…Œ์ด๋ธ”

ํ•˜์ง€๋งŒ ์˜ˆ๋ฅผ ๋“ค์–ด ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†๋Š” ์ผ์ข…์˜ ๋ฒˆ๊ฑฐ๋กœ์šด ETL ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ํŠธ๋žœ์žญ์…˜ ๋ชจ๋“œ์˜ pgbouncer? ..

๋˜๋Š” ๋ฐ์ดํ„ฐ ํ๋ฆ„์ด ๋„ˆ๋ฌด ์ปค์„œ ํ•˜๋‚˜์˜ ์—ฐ๊ฒฐ์— ๋Œ€์—ญํญ์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ(์ฝ๊ธฐ, CPU๋‹น ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค)?..

์•„๋‹ˆ๋ฉด ์ผ๋ถ€ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋‹ค๋ฅธ ์—ฐ๊ฒฐ์—์„œ?..

์—ฌ๊ธฐ์—๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž„์‹œ๊ฐ€ ์•„๋‹Œ ํ…Œ์ด๋ธ”์„ ์ž„์‹œ๋กœ ์ƒ์„ฑ. ๋ง์žฅ๋‚œ, ์‘. ๊ทธ๊ฑด:

  • ๋ˆ„๊ตฌ์™€๋„ ๊ต์ฐจํ•˜์ง€ ์•Š๋„๋ก ์ตœ๋Œ€ํ•œ ๋ฌด์ž‘์œ„ ์ด๋ฆ„์œผ๋กœ "๋‚˜๋งŒ์˜" ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐœ์ทŒ: ์™ธ๋ถ€ ์†Œ์Šค์˜ ๋ฐ์ดํ„ฐ๋กœ ์ฑ„์› ์Šต๋‹ˆ๋‹ค.
  • ๋ณ€ํ™˜: ๋ณ€ํ™˜๋˜์–ด ํ‚ค ์—ฐ๊ฒฐ ํ•„๋“œ๊ฐ€ ์ฑ„์›Œ์ง
  • ํ•˜์ค‘: ์ค€๋น„๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ๋ถ“์Šต๋‹ˆ๋‹ค.
  • "๋‚ด" ํ…Œ์ด๋ธ”์„ ์‚ญ์ œํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ง€๊ธˆ - ์—ฐ๊ณ ์— ํŒŒ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค์€, PostgreSQL์˜ ๋ชจ๋“  ์“ฐ๊ธฐ๋Š” ๋‘ ๋ฒˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. - WAL์—์„œ ์ฒ˜์Œ์œผ๋กœ, ๊ทธ๋Ÿฐ ๋‹ค์Œ ํ…Œ์ด๋ธ”/์ธ๋ฑ์Šค ๋ณธ๋ฌธ์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ์ž‘์—…์€ ACID๋ฅผ ์ง€์›ํ•˜๊ณ  ์‚ฌ์ด์˜ ์˜ฌ๋ฐ”๋ฅธ ๋ฐ์ดํ„ฐ ๊ฐ€์‹œ์„ฑ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. COMMIT'๊ณ ์•ฝํ•˜๊ณ  ROLLBACK'๋„ ๊ฑฐ๋ž˜.

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค! ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ๊ณผ์ •์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค ์™„์ „ํžˆ ์„ฑ๊ณตํ–ˆ๊ฑฐ๋‚˜ ๊ทธ๋ ‡์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ๋‘˜ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.. ์ค‘๊ฐ„ ํŠธ๋žœ์žญ์…˜์ด ์–ผ๋งˆ๋‚˜ ๋งŽ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๊ทธ๊ฒƒ์ด ์–ด๋””์— ์žˆ์—ˆ๋Š”์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ "์ค‘๊ฐ„์—์„œ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ณ„์†"ํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด PostgreSQL ๊ฐœ๋ฐœ์ž๋Š” ๋ฒ„์ „ 9.1์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ๋˜์ง€ ์•Š์€ ํ…Œ์ด๋ธ”:

์ด ํ‘œ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ…Œ์ด๋ธ”์ด ๊ธฐ๋ก๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ก๋˜์ง€ ์•Š์€ ํ…Œ์ด๋ธ”์— ๊ธฐ๋ก๋œ ๋ฐ์ดํ„ฐ๋Š” ๋ฏธ๋ฆฌ ์“ฐ๊ธฐ ๋กœ๊ทธ(29์žฅ ์ฐธ์กฐ)๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ‰์†Œ๋ณด๋‹ค ํ›จ์”ฌ ๋นจ๋ฆฌ ์ผํ•ด. ๊ทธ๋Ÿฌ๋‚˜ ์‹คํŒจ๋กœ๋ถ€ํ„ฐ ๋ฉด์—ญ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์žฅ์•  ๋˜๋Š” ๊ธด๊ธ‰ ์ข…๋ฃŒ ์‹œ ๋กœ๊ทธ๋˜์ง€ ์•Š์€ ํ…Œ์ด๋ธ” ์ž๋™์œผ๋กœ ์ž˜๋ฆผ. ๋˜ํ•œ ๊ธฐ๋ก๋˜์ง€ ์•Š์€ ํ…Œ์ด๋ธ”์˜ ๋‚ด์šฉ ๋ณต์ œ๋˜์ง€ ์•Š์Œ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์—. ๊ธฐ๋ก๋˜์ง€ ์•Š์€ ํ…Œ์ด๋ธ”์— ์ƒ์„ฑ๋œ ๋ชจ๋“  ์ธ๋ฑ์Šค๋Š” ์ž๋™์œผ๋กœ ๊ธฐ๋ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์š”์ปจ๋Œ€, ํ›จ์”ฌ ๋” ๋น ๋ฅผ ๊ฑฐ์˜ˆ์š”, ๊ทธ๋Ÿฌ๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„๊ฐ€ "๋–จ์–ด์ง€๋ฉด" ๋ถˆ์พŒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฐ ์ผ์ด ์–ผ๋งˆ๋‚˜ ์ž์ฃผ ๋ฐœ์ƒํ•˜๋ฉฐ, ETL ํ”„๋กœ์„ธ์Šค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ "ํ™œ์„ฑํ™”"ํ•œ ํ›„ "์ค‘๊ฐ„์—์„œ" ์ด๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?..

๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์œ„์˜ ๊ฒฝ์šฐ๊ฐ€ ๊ท€ํ•˜์˜ ๊ฒฝ์šฐ์™€ ์œ ์‚ฌํ•˜๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. UNLOGGEDํ•˜์ง€๋งŒ ๊ฒฐ์ฝ” ์‹ค์ œ ํ…Œ์ด๋ธ”์—์„œ๋Š” ์ด ์†์„ฑ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค., ๊ท€ํ•˜์—๊ฒŒ ์†Œ์ค‘ํ•œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

1.3. ์ปค๋ฐ‹ ์‹œ { ํ–‰ ์‚ญ์ œ | ๋–จ์–ด์ง€๋‹ค}

์ด ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ…Œ์ด๋ธ” ์ƒ์„ฑ ์‹œ ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ ์ž๋™ ๋™์ž‘์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ฝ ON COMMIT DROP ์œ„์—์„œ ์ด๋ฏธ ์ผ๋Š”๋ฐ, ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. DROP TABLE, ํ•˜์ง€๋งŒ ํ•จ๊ป˜ ON COMMIT DELETE ROWS ์ƒํ™ฉ์ด ๋” ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. TRUNCATE TABLE.

์ž„์‹œ ํ…Œ์ด๋ธ”์˜ ๋ฉ”ํƒ€ ์„ค๋ช…์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ „์ฒด ์ธํ”„๋ผ๋Š” ์ผ๋ฐ˜ ํ…Œ์ด๋ธ”๊ณผ ์™„์ „ํžˆ ๋™์ผํ•˜๋ฏ€๋กœ ์ž„์‹œ ํ…Œ์ด๋ธ”์˜ ์ง€์†์ ์ธ ์ƒ์„ฑ ๋ฐ ์‚ญ์ œ๋กœ ์ธํ•ด ์‹œ์Šคํ…œ ํ…Œ์ด๋ธ”์ด ์‹ฌ๊ฐํ•˜๊ฒŒ "๋ถ€ํ’€์–ด ์˜ค๋ฆ„" pg_class, pg_attribute, pg_attrdef, pg_dependent,โ€ฆ

์ด์ œ ๋งค์ดˆ๋งˆ๋‹ค ์ƒˆ ํŠธ๋žœ์žญ์…˜์„ ์—ด๊ณ  ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑ, ์ฑ„์šฐ๊ธฐ, ์ฒ˜๋ฆฌ ๋ฐ ์‚ญ์ œํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ง์ ‘ ์—ฐ๊ฒฐ๋œ ์ž‘์—…์ž๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค. ์‹œ์Šคํ…œ ํ…Œ์ด๋ธ”์— ๊ณผ๋„ํ•œ ์“ฐ๋ ˆ๊ธฐ๊ฐ€ ์ถ•์ ๋  ๊ฒƒ์ด๋ฉฐ, ์ด๋กœ ์ธํ•ด ๊ฐ ์ž‘์—…๋งˆ๋‹ค ์ถ”๊ฐ€ ๋ธŒ๋ ˆ์ดํฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ๋งˆ์„ธ์š”! ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ํ›จ์”ฌ ๋” ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. CREATE TEMPORARY TABLE x ... ON COMMIT DELETE ROWS ํŠธ๋žœ์žญ์…˜ ์ฃผ๊ธฐ์—์„œ ๋ฒ—์–ด๋‚˜์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋ฉด ๊ฐ๊ฐ์˜ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋  ๋•Œ๋งˆ๋‹ค ํ…Œ์ด๋ธ”์ด ์ด๋ฏธ ์กด์žฌํ•  ๊ฒƒ์ด๋‹ค (ํ†ตํ™” ์ €์žฅ CREATE),ํ•˜์ง€๋งŒ ๋น„์–ด์žˆ์„ ๊ฒƒ์ด๋‹ค, ๋•๋ถ„์— TRUNCATE (์ €ํฌ๋Š” ํ•ด๋‹น ํ˜ธ์ถœ๋„ ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค) ์ด์ „ ๊ฑฐ๋ž˜๋ฅผ ์™„๋ฃŒํ•  ๋•Œ.

1.4. ๋‹ค์Œ์„ ํฌํ•จํ•˜์—ฌ...

๋‚˜๋Š” ์ฒ˜์Œ์— ์ž„์‹œ ํ…Œ์ด๋ธ”์˜ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๊ฐ€์ ธ์˜ค๊ธฐ๋ผ๊ณ  ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ง€์ณ์„œ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์˜ ํ•„๋“œ ๋ชฉ๋ก์„ ์ž„์‹œ ํ…Œ์ด๋ธ” ์„ ์–ธ์— ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ฒŒ์œผ๋ฆ„์€ ๋ฐœ์ „์˜ ์›๋™๋ ฅ์ž…๋‹ˆ๋‹ค! ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— "์ƒ˜ํ”Œ์„ ๊ธฐ๋ฐ˜์œผ๋กœ" ์ƒˆ ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CREATE TEMPORARY TABLE import_table(
  LIKE target_table
);

๊ทธ๋Ÿฌ๋ฉด ์ด ํ…Œ์ด๋ธ”์— ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฒ€์ƒ‰ ์†๋„๊ฐ€ ๊ฒฐ์ฝ” ๋นจ๋ผ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์— ๋Œ€ํ•œ ์ „ํ†ต์ ์ธ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์ธ๋ฑ์Šค์ž…๋‹ˆ๋‹ค! ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์ž„์‹œ ํ…Œ์ด๋ธ”์—๋„ ์ธ๋ฑ์Šค๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ์ธ๋ฑ์Šค๊ฐ€ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์˜ ์ธ๋ฑ์Šค์™€ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„๋‹จํžˆ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. LIKE target_table INCLUDING INDEXES.

๋‹น์‹ ๋„ ํ•„์š”ํ•˜๋‹ค๋ฉด DEFAULT-๊ฐ’(์˜ˆ: ๊ธฐ๋ณธ ํ‚ค ๊ฐ’์„ ์ž…๋ ฅํ•˜๊ธฐ ์œ„ํ•ด)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. LIKE target_table INCLUDING DEFAULTS. ์•„๋‹ˆ๋ฉด ๊ฐ„๋‹จํžˆ - LIKE target_table INCLUDING ALL โ€” ๊ธฐ๋ณธ๊ฐ’, ์ธ๋ฑ์Šค, ์ œ์•ฝ ์กฐ๊ฑด ๋“ฑ์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋‹น์‹ ์ด ๋งŒ๋“  ๊ฒฝ์šฐ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฆ‰์‹œ ํ…Œ์ด๋ธ”์„ ๊ฐ€์ ธ์˜ค๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.๋จผ์ € ๋ชจ๋“  ๊ฒƒ์„ ์ฑ„์šด ๋‹ค์Œ ์ธ๋ฑ์Šค๋ฅผ ๋กค์—…ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค - ์˜ˆ๋ฅผ ๋“ค์–ด ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์ˆ˜ํ–‰๋˜๋Š”์ง€ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค. pg_dump.

์ผ๋ฐ˜์ ์œผ๋กœ, RTFM!

2. ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•˜๋‚˜์š”?

๊ทธ๋ƒฅ ๋งํ•ด๋‘์ฃ  - ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š” COPY- "ํŒฉ" ๋Œ€์‹  ํ๋ฆ„ INSERT, ๋•Œ๋•Œ๋กœ ๊ฐ€์†. ๋ฏธ๋ฆฌ ์ƒ์„ฑ๋œ ํŒŒ์ผ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด์ œ ์†Œ๊ฐœ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด๋ณด์ž.

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํด๋ผ์ด์–ธํŠธ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ ํ…Œ์ด๋ธ”์ด ์žˆ์Šต๋‹ˆ๋‹ค. 1๋งŒ ๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ
  • ๋งค์ผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‹น์‹ ์—๊ฒŒ ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค ์ „์ฒด "์ด๋ฏธ์ง€"
  • ๊ฒฝํ—˜์„ ํ†ตํ•ด ๋‹น์‹ ์€ ๋•Œ๋•Œ๋กœ ๊ทธ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค 10๊ฐœ ์ดํ•˜์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌํ•œ ์ƒํ™ฉ์˜ ์ „ํ˜•์ ์ธ ์˜ˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. KLADR ๋ฒ ์ด์Šค โ€” ์ „์ฒด์ ์œผ๋กœ ์ฃผ์†Œ๋Š” ๋งŽ์ง€๋งŒ ๋งค์ฃผ ์—…๋กœ๋“œํ•  ๋•Œ๋งˆ๋‹ค ์ „๊ตญ ๊ทœ๋ชจ์—์„œ๋„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ(์ •์ฐฉ์ง€ ์ด๋ฆ„ ๋ณ€๊ฒฝ, ๊ฑฐ๋ฆฌ ๊ฒฐํ•ฉ, ์ƒˆ ์ง‘ ์ถœํ˜„)์ด ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค.

3.1. ์ „์ฒด ๋™๊ธฐํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋‹จ์ˆœํ™”๋ฅผ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์žฌ๊ตฌ์„ฑํ•  ํ•„์š”์กฐ์ฐจ ์—†๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์„ ์›ํ•˜๋Š” ํ˜•์‹์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ๋ฉ๋‹ˆ๋‹ค.

  • ์ œ๊ฑฐํ•˜๋‹ค ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ชจ๋“  ๊ฒƒ
  • ์ƒˆ๋กœ ๊ณ ์นจ ์ด๋ฏธ ์กด์žฌํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ
  • ์‚ฝ์ž… ์•„์ง ์ผ์–ด๋‚˜์ง€ ์•Š์€ ๋ชจ๋“  ์ผ

์™œ ์ด ์ˆœ์„œ๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ…Œ์ด๋ธ” ํฌ๊ธฐ๊ฐ€ ์ตœ์†Œํ•œ์œผ๋กœ ์ปค์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(MVCC๋ฅผ ๊ธฐ์–ตํ•˜์„ธ์š”!).

dst์—์„œ ์‚ญ์ œ

์•„๋‹ˆ์š”. ๋ฌผ๋ก  ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ž‘์—…๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

  • ์ œ๊ฑฐํ•˜๋‹ค (DELETE) ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ
  • ์‚ฝ์ž… ๋ชจ๋‘ ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€์—์„œ

ํ•˜์ง€๋งŒ ๋™์‹œ์— MVCC ๋•๋ถ„์— ํ…Œ์ด๋ธ” ํฌ๊ธฐ๊ฐ€ ์ •ํ™•ํžˆ ๋‘ ๋ฐฐ๋กœ ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค.! 1K ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด ํ…Œ์ด๋ธ”์— ์žˆ๋Š” ๋ ˆ์ฝ”๋“œ์˜ +10M ์ด๋ฏธ์ง€๋ฅผ ์–ป๋Š” ๊ฒƒ์€ ๋„ˆ๋ฌด๋‚˜ ์ค‘๋ณต๋ฉ๋‹ˆ๋‹ค...

TRUNCATE dst

๊ฒฝํ—˜์ด ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋Š” ์ „์ฒด ํƒœ๋ธ”๋ฆฟ์„ ๋งค์šฐ ์ €๋ ดํ•˜๊ฒŒ ์ฒญ์†Œํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ถ„๋ช…ํžˆํ•˜๋‹ค (TRUNCATE) ์ „์ฒด ํ…Œ์ด๋ธ”
  • ์‚ฝ์ž… ๋ชจ๋‘ ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€์—์„œ

๋ฐฉ๋ฒ•์€ ํšจ๊ณผ์ ์ด๋ฉฐ, ๋•Œ๋กœ๋Š” ๊ฝค ์ ์šฉ ๊ฐ€๋Šฅ, ํ•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค... ์˜ค๋žซ๋™์•ˆ 1๋งŒ ๊ฐœ์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์˜ˆ์ •์ด๋ฏ€๋กœ ์ด ์‹œ๊ฐ„ ๋™์•ˆ ํ…Œ์ด๋ธ”์„ ๋น„์›Œ ๋‘˜ ์—ฌ์œ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค(๋‹จ์ผ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ž˜ํ•‘ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐœ์ƒํ•จ).

์ด๋Š” ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  • ์šฐ๋ฆฌ๋Š” ์‹œ์ž‘ํ•ด์š” ์žฅ๊ธฐ ์‹คํ–‰ ํŠธ๋žœ์žญ์…˜
  • TRUNCATE ๋ถ€๊ณผํ•˜๋‹ค ์•ก์„ธ์Šค ๋…์ -๋ธ”๋กœํ‚น
  • ์šฐ๋ฆฌ๋Š” ์˜ค๋žซ๋™์•ˆ ์‚ฝ์ž…์„ ํ•˜๊ณ , ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ์ด ์‹œ๊ฐ„์— ์‹ฌ์ง€์–ด ํ•  ์ˆ˜ ์—†๋‹ค SELECT

๋ญ”๊ฐ€ ์ž˜ ์•ˆ๋˜๋„ค์š”...

ํ…Œ์ด๋ธ” ๋ณ€๊ฒฝโ€ฆ ์ด๋ฆ„ ๋ฐ”๊พธ๊ธฐโ€ฆ / ํ…Œ์ด๋ธ” ์‚ญ์ œโ€ฆ

๋Œ€์•ˆ์€ ๋ชจ๋“  ๊ฒƒ์„ ๋ณ„๋„์˜ ์ƒˆ ํ…Œ์ด๋ธ”์— ์ฑ„์šด ๋‹ค์Œ ์ด์ „ ํ…Œ์ด๋ธ” ๋Œ€์‹  ์ด๋ฆ„์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ๋ถˆ์พŒํ•œ ์ž‘์€ ๊ฒƒ๋“ค:

  • ์•„์ง๋„ ์•ก์„ธ์Šค ๋…์ , ๋น„๋ก ์‹œ๊ฐ„์€ ํ›จ์”ฌ ์งง์•˜์ง€๋งŒ
  • ์ด ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๋ชจ๋“  ์ฟผ๋ฆฌ ๊ณ„ํš/ํ†ต๊ณ„๊ฐ€ ์žฌ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ANALYZE๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
  • ๋ชจ๋“  ์™ธ๋ž˜ ํ‚ค๊ฐ€ ์†์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. (FK) ํ…Œ์ด๋ธ”๋กœ

Simon Riggs๊ฐ€ ์ œ์•ˆํ•œ WIP ํŒจ์น˜๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ALTER-ํ†ต๊ณ„ ๋ฐ FK๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ํŒŒ์ผ ์ˆ˜์ค€์—์„œ ํ…Œ์ด๋ธ” ๋ณธ๋ฌธ์„ ๋ฐ”๊พธ๋Š” ์ž‘์—…์ด์ง€๋งŒ ์ฟผ๋Ÿผ์„ ์ˆ˜์ง‘ํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์‚ญ์ œ, ์—…๋ฐ์ดํŠธ, ์‚ฝ์ž…

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ์„ธ ๊ฐ€์ง€ ์ž‘์—…์˜ ๋น„์ฐจ๋‹จ ์˜ต์…˜์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฑฐ์˜ XNUMX๊ฐœ... ์ด ์ž‘์—…์„ ๊ฐ€์žฅ ํšจ๊ณผ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

-- ะฒัะต ะดะตะปะฐะตะผ ะฒ ั€ะฐะผะบะฐั… ั‚ั€ะฐะฝะทะฐะบั†ะธะธ, ั‡ั‚ะพะฑั‹ ะฝะธะบั‚ะพ ะฝะต ะฒะธะดะตะป "ะฟั€ะพะผะตะถัƒั‚ะพั‡ะฝั‹ั…" ัะพัั‚ะพัะฝะธะน
BEGIN;

-- ัะพะทะดะฐะตะผ ะฒั€ะตะผะตะฝะฝัƒัŽ ั‚ะฐะฑะปะธั†ัƒ ั ะธะผะฟะพั€ั‚ะธั€ัƒะตะผั‹ะผะธ ะดะฐะฝะฝั‹ะผะธ
CREATE TEMPORARY TABLE tmp(
  LIKE dst INCLUDING INDEXES -- ะฟะพ ะพะฑั€ะฐะทัƒ ะธ ะฟะพะดะพะฑะธัŽ, ะฒะผะตัั‚ะต ั ะธะฝะดะตะบัะฐะผะธ
) ON COMMIT DROP; -- ะทะฐ ั€ะฐะผะบะฐะผะธ ั‚ั€ะฐะฝะทะฐะบั†ะธะธ ะพะฝะฐ ะฝะฐะผ ะฝะต ะฝัƒะถะฝะฐ

-- ะฑั‹ัั‚ั€ะพ-ะฑั‹ัั‚ั€ะพ ะฒะปะธะฒะฐะตะผ ะฝะพะฒั‹ะน ะพะฑั€ะฐะท ั‡ะตั€ะตะท COPY
COPY tmp FROM STDIN;
-- ...
-- .

-- ัƒะดะฐะปัะตะผ ะพั‚ััƒั‚ัั‚ะฒัƒัŽั‰ะธะต
DELETE FROM
  dst D
USING
  dst X
LEFT JOIN
  tmp Y
    USING(pk1, pk2) -- ะฟะพะปั ะฟะตั€ะฒะธั‡ะฝะพะณะพ ะบะปัŽั‡ะฐ
WHERE
  (D.pk1, D.pk2) = (X.pk1, X.pk2) AND
  Y IS NOT DISTINCT FROM NULL; -- "ะฐะฝั‚ะธะดะถะพะนะฝ"

-- ะพะฑะฝะพะฒะปัะตะผ ะพัั‚ะฐะฒัˆะธะตัั
UPDATE
  dst D
SET
  (f1, f2, f3) = (T.f1, T.f2, T.f3)
FROM
  tmp T
WHERE
  (D.pk1, D.pk2) = (T.pk1, T.pk2) AND
  (D.f1, D.f2, D.f3) IS DISTINCT FROM (T.f1, T.f2, T.f3); -- ะฝะตะทะฐั‡ะตะผ ะพะฑะฝะพะฒะปัั‚ัŒ ัะพะฒะฟะฐะดะฐัŽั‰ะธะต

-- ะฒัั‚ะฐะฒะปัะตะผ ะพั‚ััƒั‚ัั‚ะฒัƒัŽั‰ะธะต
INSERT INTO
  dst
SELECT
  T.*
FROM
  tmp T
LEFT JOIN
  dst D
    USING(pk1, pk2)
WHERE
  D IS NOT DISTINCT FROM NULL;

COMMIT;

3.2. ํ›„์ฒ˜๋ฆฌ ๊ฐ€์ ธ์˜ค๊ธฐ

๋™์ผํ•œ KLADR์—์„œ ๋ณ€๊ฒฝ๋œ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ๋Š” ์ •๊ทœํ™”, ํ‚ค์›Œ๋“œ ๊ฐ•์กฐ ํ‘œ์‹œ ๋ฐ ํ•„์š”ํ•œ ๊ตฌ์กฐ๋กœ ์ถ•์†Œ ๋“ฑ์˜ ์‚ฌํ›„ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€๋กœ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ด๋–ป๊ฒŒ ์•Œ์ฃ - ์ •ํ™•ํžˆ ๋ฌด์—‡์ด ๋ฐ”๋€Œ์—ˆ๋‚˜์š”?๋™๊ธฐํ™” ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ํ•˜์ง€ ์•Š๊ณ , ์ด์ƒ์ ์œผ๋กœ๋Š” ์ „ํ˜€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ ์š”?

๋™๊ธฐํ™” ์‹œ ํ”„๋กœ์„ธ์Šค์—๋งŒ ์“ฐ๊ธฐ ์•ก์„ธ์Šค ๊ถŒํ•œ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ˆ˜์ง‘ํ•˜๋Š” ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

-- ั†ะตะปะตะฒั‹ะต ั‚ะฐะฑะปะธั†ั‹
CREATE TABLE kladr(...);
CREATE TABLE kladr_house(...);

-- ั‚ะฐะฑะปะธั†ั‹ ั ะธัั‚ะพั€ะธะตะน ะธะทะผะตะฝะตะฝะธะน
CREATE TABLE kladr$log(
  ro kladr, -- ั‚ัƒั‚ ะปะตะถะฐั‚ ั†ะตะปั‹ะต ะพะฑั€ะฐะทั‹ ะทะฐะฟะธัะตะน ัั‚ะฐั€ะพะน/ะฝะพะฒะพะน
  rn kladr
);

CREATE TABLE kladr_house$log(
  ro kladr_house,
  rn kladr_house
);

-- ะพะฑั‰ะฐั ั„ัƒะฝะบั†ะธั ะปะพะณะธั€ะพะฒะฐะฝะธั ะธะทะผะตะฝะตะฝะธะน
CREATE OR REPLACE FUNCTION diff$log() RETURNS trigger AS $$
DECLARE
  dst varchar = TG_TABLE_NAME || '$log';
  stmt text = '';
BEGIN
  -- ะฟั€ะพะฒะตั€ัะตะผ ะฝะตะพะฑั…ะพะดะธะผะพัั‚ัŒ ะปะพะณะณะธั€ะพะฒะฐะฝะธั ะฟั€ะธ ะพะฑะฝะพะฒะปะตะฝะธะธ ะทะฐะฟะธัะธ
  IF TG_OP = 'UPDATE' THEN
    IF NEW IS NOT DISTINCT FROM OLD THEN
      RETURN NEW;
    END IF;
  END IF;
  -- ัะพะทะดะฐะตะผ ะทะฐะฟะธััŒ ะปะพะณะฐ
  stmt = 'INSERT INTO ' || dst::text || '(ro,rn)VALUES(';
  CASE TG_OP
    WHEN 'INSERT' THEN
      EXECUTE stmt || 'NULL,$1)' USING NEW;
    WHEN 'UPDATE' THEN
      EXECUTE stmt || '$1,$2)' USING OLD, NEW;
    WHEN 'DELETE' THEN
      EXECUTE stmt || '$1,NULL)' USING OLD;
  END CASE;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

์ด์ œ ๋™๊ธฐํ™”๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์ ์šฉํ•˜๊ฑฐ๋‚˜ ๋‹ค์Œ์„ ํ†ตํ•ด ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ALTER TABLE ... ENABLE TRIGGER ...):

CREATE TRIGGER log
  AFTER INSERT OR UPDATE OR DELETE
  ON kladr
    FOR EACH ROW
      EXECUTE PROCEDURE diff$log();

CREATE TRIGGER log
  AFTER INSERT OR UPDATE OR DELETE
  ON kladr_house
    FOR EACH ROW
      EXECUTE PROCEDURE diff$log();

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋กœ๊ทธ ํ…Œ์ด๋ธ”์—์„œ ํ•„์š”ํ•œ ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฐจ๋ถ„ํ•˜๊ฒŒ ์ถ”์ถœํ•˜๊ณ  ์ถ”๊ฐ€ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

3.3. ์—ฐ๊ฒฐ๋œ ์„ธํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ

์œ„์—์„œ๋Š” ์†Œ์Šค์™€ ๋Œ€์ƒ์˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ ๋™์ผํ•œ ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์™ธ๋ถ€ ์‹œ์Šคํ…œ์—์„œ ์—…๋กœ๋“œํ•œ ํŒŒ์ผ์˜ ํ˜•์‹์ด ์šฐ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ €์žฅ ๊ตฌ์กฐ์™€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

๊ณ ์ „์ ์ธ "๋‹ค๋Œ€์ผ" ์˜ต์…˜์ธ ํด๋ผ์ด์–ธํŠธ ๋ฐ ํ•ด๋‹น ๊ณ„์ •์˜ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

CREATE TABLE client(
  client_id
    serial
      PRIMARY KEY
, inn
    varchar
      UNIQUE
, name
    varchar
);

CREATE TABLE invoice(
  invoice_id
    serial
      PRIMARY KEY
, client_id
    integer
      REFERENCES client(client_id)
, number
    varchar
, dt
    date
, sum
    numeric(32,2)
);

๊ทธ๋Ÿฌ๋‚˜ ์™ธ๋ถ€ ์†Œ์Šค๋กœ๋ถ€ํ„ฐ์˜ ๋‹ค์šด๋กœ๋“œ๋Š” "์˜ฌ์ธ์›" ํ˜•ํƒœ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

CREATE TEMPORARY TABLE invoice_import(
  client_inn
    varchar
, client_name
    varchar
, invoice_number
    varchar
, invoice_dt
    date
, invoice_sum
    numeric(32,2)
);

๋ถ„๋ช…ํžˆ ์ด ๋ฒ„์ „์—์„œ๋Š” ๊ณ ๊ฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณต์ œ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ฃผ์š” ๊ธฐ๋ก์€ "๊ณ„์ •"์ž…๋‹ˆ๋‹ค.

0123456789;ะ’ะฐัั;A-01;2020-03-16;1000.00
9876543210;ะŸะตั‚ั;A-02;2020-03-16;666.00
0123456789;ะ’ะฐัั;B-03;2020-03-16;9999.00

๋ชจ๋ธ์˜ ๊ฒฝ์šฐ ๊ฐ„๋‹จํžˆ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•˜์ง€๋งŒ ๋‹ค์Œ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. COPY ๋” ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค!

INSERT INTO invoice_import
VALUES
  ('0123456789', 'ะ’ะฐัั', 'A-01', '2020-03-16', 1000.00)
, ('9876543210', 'ะŸะตั‚ั', 'A-02', '2020-03-16', 666.00)
, ('0123456789', 'ะ’ะฐัั', 'B-03', '2020-03-16', 9999.00);

๋จผ์ €, "์‚ฌ์‹ค"์ด ์ฐธ์กฐํ•˜๋Š” "์ปท"์„ ๊ฐ•์กฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ ์†ก์žฅ์€ ๊ณ ๊ฐ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

CREATE TEMPORARY TABLE client_import AS
SELECT DISTINCT ON(client_inn)
-- ะผะพะถะฝะพ ะฟั€ะพัั‚ะพ SELECT DISTINCT, ะตัะปะธ ะดะฐะฝะฝั‹ะต ะทะฐะฒะตะดะพะผะพ ะฝะตะฟั€ะพั‚ะธะฒะพั€ะตั‡ะธะฒั‹
  client_inn inn
, client_name "name"
FROM
  invoice_import;

๊ณ„์ •์„ ๊ณ ๊ฐ ID์™€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด ๋จผ์ € ์ด๋Ÿฌํ•œ ์‹๋ณ„์ž๋ฅผ ์ฐพ๊ฑฐ๋‚˜ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์•„๋ž˜์— ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ALTER TABLE invoice_import ADD COLUMN client_id integer;
ALTER TABLE client_import ADD COLUMN client_id integer;

์œ„์—์„œ ์„ค๋ช…ํ•œ ํ…Œ์ด๋ธ” ๋™๊ธฐํ™” ๋ฐฉ๋ฒ•์„ ์•ฝ๊ฐ„ ์ˆ˜์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๋ฅผ "์ถ”๊ฐ€ ์ „์šฉ"์œผ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์ƒ ํ…Œ์ด๋ธ”์˜ ์–ด๋–ค ๊ฒƒ๋„ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

-- ะฟั€ะพัั‚ะฐะฒะปัะตะผ ะฒ ั‚ะฐะฑะปะธั†ะต ะธะผะฟะพั€ั‚ะฐ ID ัƒะถะต ััƒั‰ะตัั‚ะฒัƒัŽั‰ะธั… ะทะฐะฟะธัะตะน
UPDATE
  client_import T
SET
  client_id = D.client_id
FROM
  client D
WHERE
  T.inn = D.inn; -- unique key

-- ะฒัั‚ะฐะฒะปัะตะผ ะพั‚ััƒั‚ัั‚ะฒะพะฒะฐะฒัˆะธะต ะทะฐะฟะธัะธ ะธ ะฟั€ะพัั‚ะฐะฒะปัะตะผ ะธั… ID
WITH ins AS (
  INSERT INTO client(
    inn
  , name
  )
  SELECT
    inn
  , name
  FROM
    client_import
  WHERE
    client_id IS NULL -- ะตัะปะธ ID ะฝะต ะฟั€ะพัั‚ะฐะฒะธะปัั
  RETURNING *
)
UPDATE
  client_import T
SET
  client_id = D.client_id
FROM
  ins D
WHERE
  T.inn = D.inn; -- unique key

-- ะฟั€ะพัั‚ะฐะฒะปัะตะผ ID ะบะปะธะตะฝั‚ะพะฒ ัƒ ะทะฐะฟะธัะตะน ัั‡ะตั‚ะพะฒ
UPDATE
  invoice_import T
SET
  client_id = D.client_id
FROM
  client_import D
WHERE
  T.client_inn = D.inn; -- ะฟั€ะธะบะปะฐะดะฝะพะน ะบะปัŽั‡

์‚ฌ์‹ค ๋‹ค ๋“ค์–ด์žˆ์–ด์š” invoice_import ์ด์ œ ์—ฐ๋ฝ์ฒ˜ ํ•„๋“œ๊ฐ€ ์ฑ„์›Œ์กŒ์Šต๋‹ˆ๋‹ค. client_id, ์†ก์žฅ์„ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

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