๋ฐ˜๋ณต๋ฌธ

๋ฐ˜๋ณต๋ฌธ ์˜์กด์ฆ

๋ชจ๋“  ์—”์ง€๋‹ˆ์–ด ๋˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๊ณตํ†ต์ ์ธ ๋ณ‘์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค ์กฐ๊ธˆ์€ ๊ณผ์žฅ๋œ ํ‘œํ˜„์ด์ง€๋งŒ ๋ชจ๋‘ ์ตœ์†Œํ•œ ํ•œ ๋ฒˆ์€ ๋ฐ˜๋ณต๋ฌธ ์˜์กด์ฆ์ด๋ผ๋Š” ๋ณ‘์„ ๊ฒฝํ—˜ํ•œ ์ ์ด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ SQL์—๋Š” ๋ฐ˜๋ณต๋ฌธ์ด ์—†๋‹ค. SQL์€ ์ผ๋ถ€๋Ÿฌ ๋ฐ˜๋ณต๋ฌธ์„ ์–ธ์–ด ์„ค๊ณ„์—์„œ ์ œ์™ธ ํ•˜์˜€๋‹ค. ์™œ๋ƒํ•˜๋ฉด โ€œ๋ฐ˜๋ณต๋ฌธ์€ ํ•„์š” ์—†๋‹คโ€๋ผ๋Š” ์ƒ๊ฐ ๋•Œ๋ฌธ์ด๋‹ค.

RDB๋ฅผ ์ฒ˜์Œ ์ƒ๊ฐํ•ด๋ƒˆ๋˜ Edgar F. Codd๋Š” ์ €์„œ Relational Database : a practical foundation for productivity (1989)์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งํ–ˆ๋‹ค.

๐Ÿ’ก ๊ด€๊ณ„ ์กฐ์ž‘์€ ๊ด€๊ณ„ ์ „์ฒด๋ฅผ ๋ชจ๋‘ ์กฐ์ž‘์˜ ๋Œ€์ƒ์œผ๋กœ ์‚ผ๋Š”๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒƒ์˜ ๋ชฉ์ ์€ ๋ฐ˜๋ณต์„ ์ œ์™ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ตœ์ข… ์‚ฌ์šฉ์ž์˜ ์ƒ์‚ฐ์„ฑ์„ ์ƒ๊ฐํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์•ผ๋งŒ ์‘์šฉ ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์ƒ์‚ฐ์„ฑ์—๋„ ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

โ€˜๊ด€๊ณ„ ์กฐ์ž‘โ€™์ด๋ผ๋Š” ๊ฒƒ์€ SQL์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ SQL์€ ์ฒ˜์Œ๋ถ€ํ„ฐ โ€˜๋ฐ˜๋ณต๋ฌธ์„ ์ œ์™ธโ€™ํ•˜๊ณ  ๋งŒ๋“ค์–ด์ง„ ์–ธ์–ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  Codd๋Š” ์ด๋Ÿฌํ•œ ์ด์œ ๋ฅผ โ€˜๊ทธ๊ฒŒ ํŽธํ•˜๋‹ˆ๊นŒโ€™๋ผ๊ณ  ์„ค๋ช…ํ•œ๋‹ค.

1. ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉ

์—…๊ณ„์— ์ข…์‚ฌํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ง„ ์‹œ์Šคํ…œ์„ ๋ณด์•˜์„ ๊ฒƒ์ด๋‹ค.

  • ์˜จ๋ผ์ธ ์ฒ˜๋ฆฌ์—์„œ ํ™”๋ฉด์— ๋ช…์„ธ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ ์ž ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜์”ฉ ์ ‘๊ทผํ•˜๋Š” SELECT๊ตฌ๋ฌธ์„ ๋ฐ˜๋ณต ์‚ฌ์šฉ
  • ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ์—์„œ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ํ˜ธ์ŠคํŠธ ์–ธ์–ด์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  ํ…Œ์ด๋ธ”์— ๊ฐฑ์‹ 

์ ์žฌ์ ์†Œ๋ผ๋Š” ๋ง์ฒ˜๋Ÿผ SQL์„ ์ ์šฉํ•˜๊ธฐ ํž˜๋“  ์ž‘์—…์— ๋ฌด๋ฆฌํ•˜๊ฒŒ SQL์„ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†๋‹ค. ๋˜ํ•œ ๋ฏธ๋“ค์›จ์–ด ๋˜๋Š” ORM๋“ฑ์˜ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐ˜๋ณต๊ณ„ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋”ฐ๋กœ ์„ ํƒ์˜ ์—ฌ์ง€๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์‹ค ๋ฐ˜๋ณต์ด ์—†์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์˜ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ ์™ธ์—๋„ Codd๊ฐ€ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š์€ ํฐ ์žฅ์ ์ด ์ƒ๊ธด๋‹ค. ๋ฐ˜๋Œ€๋กœ ๋งํ•˜๋ฉด ๋ฐ˜๋ณต๊ณ„ ์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํฐ ๋‹จ์ ์ด๋‹ค.

๋ฐ˜๋ณต๊ณ„์˜ ๊ณตํฌ

๋จผ์ € ๋‹ค์Œ๊ณผ ๊ฐ™์€ 2๊ฐœ์˜ ํ…Œ์ด๋ธ”์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด์ž

Sales

https://yongineer.duckdns.org/sql/092.png

Sales2

https://yongineer.duckdns.org/sql/093.png

Sales ํ…Œ์ด๋ธ”์€ ๊ฐ ๊ธฐ์—…์˜ ํšŒ๊ณ„์—ฐ๋„๋ณ„ ๋งค์ถœ์„ ๊ธฐ๋กํ•œ๋‹ค. ๋‹ค๋งŒ ์—ฐ๋„๊ฐ€ ์—ฐ์†๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. ์–ด์จŒ๊ฑฐ๋‚˜ ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ํŠน์ • ๊ธฐ์—…์˜ ๋งค์ถœ ๋ณ€ํ™”๋ฅผ ์กฐ์‚ฌํ• ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ณผ๋Š” varํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ Sales2 ํ…Œ์ด๋ธ”์— ๋“ฑ๋กํ•œ๋‹ค. ์ด๋•Œ varํ•„๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทœ์น™์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค.

  • ์ด์ „ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ : NULL
  • ์ด์ „ ๋ฐ์ดํ„ฐ๋ณด๋‹ค ๋งค์ถœ์ด ์˜ฌ๋ž์„ ๊ฒฝ์šฐ : +
  • ์ด์ „ ๋ฐ์ดํ„ฐ๋ณด๋‹ค ๋งค์ถœ์ด ๋‚ด๋ ธ์„ ๊ฒฝ์šฐ : -
  • ์ด์ „ ๋ฐ์ดํ„ฐ์™€ ๋งค์ถœ์ด ๋™์ผํ•œ ๊ฒฝ์šฐ : =

๋”ฐ๋ผ์„œ ์ตœ์ข…์ ์œผ๋กœ Sales2 ํ…Œ์ด๋ธ”์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค.

https://yongineer.duckdns.org/sql/094.png

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์ „ํ˜•์ ์ธ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ Oracle์˜ PL/SQL์ฝ”๋“œ์ด๋‹ค.

CREATE OR REPLACE PROCEDURE PROC_INSERT_VAR
IS
	/* ์ปค์„œ ์„ ์–ธ */
	CURSOR c_sales IS
		SELECT company, year, sale FROM Sales ORDER BY company, year;
	
	/* ๋ ˆ์ฝ”๋“œ ํƒ€์ž… ์„ ์–ธ */
	rec_sales c_sales %ROWTYPE;

	/* ์นด์šดํ„ฐ */
	i_pre_sale INTEGER :=0;
	c_company CHAR(1) :='*';
	c_var CHAR(1) :='*';

BEGIN

OPEN c_sales;
	LOOP
	/* ๋ ˆ์ฝ”๋“œ๋ฅผ ํŒจ์น˜ํ•ด์„œ ๋ณ€์ˆ˜์— ๋Œ€์ž… */
	fetch c_sales into rec_sales;
	/* ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—†๋‹ค๋ฉด ๋ฐ˜๋ณต์„ ์ข…๋ฃŒ */
	exit when c_sales%notfound;

	IF (c_company = rec_sales.company) THEN
		/* ์ง์ „ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๊ฐ™์€ ํšŒ์‚ฌ์˜ ๋ ˆ์ฝ”๋“œ ์ผ ๋•Œ */
		/* ์ง์ „ ๋ ˆ์ฝ”๋“œ์™€ ๋งค์ƒ์„ ๋น„๊ต */
		IF (i_pre_sale < rec_sales.sale) THEN
			c_var :='+';
		ELSEIF(i_pre_sale > rec_sales.sale) THEN
			c_var :='-';
		ELSE
			c_var :='=';
		END IF;
	
	ELSE
		c_var :=NULL;
	
	END IF;
	
	/* ๋“ฑ๋ก ๋Œ€์ƒ์ด ํ…Œ์ด๋ธ”์— ํ…Œ์ด๋ธ”์„ ๋“ฑ๋ก */
	INSERT INTO Sales2 (company, year, sale, var)
		VALUES (rec_sales.company, rec_sales.year, rec_sales.sale, c_var);
	
	c_company := rec_sales.company;
	i_pre_sale := rec_sales.sale;
	
	END LOOP;
	
	CLOSE c_sales;
	commit;

END;

ํŠน์ • ์—ฐ๋„์˜ ๋ ˆ์ฝ”๋“œ์™€ ์ง์ „ ์—ฐ๋„์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋น„๊ตํ•˜๋Š” ๋กœ์ง์„ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์€ ์ „ํ˜•์ ์ธ โ€˜record at a time (ํ•œ ๋ฒˆ์— ํ•œ ๋ ˆ์ฝ”๋“œ)โ€˜์  ์‚ฌ๊ณ ๋ฐฉ์‹์ด๋‹ค.

๋ฐ˜๋ฉด ์—ฌ๋Ÿฌ ํ–‰์„ ํ•œ๊บผ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋Š” SQL์„ ํฌ์žฅ๊ณ„๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ํฌ์žฅ๊ณ„ SQL์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ SQL์— ๋„ฃ์œผ๋ ค๋‹ค ๋ณด๋‹ˆ ๊ตฌ๋ฌธ์ด ๋ณต์žกํ•ด์ ธ์„œ ์œ ์ง€ ๋ณด์ˆ˜์„ฑ์ด ๋–จ์–ด์ง€๋Š” SQL ๊ตฌ๋ฌธ์ด ๋งŒ๋“ค์–ด์ง€๊ธฐ๋„ ํ•œ๋‹ค.

1. ๋ฐ˜๋ณต๊ณ„์˜ ๋‹จ์ 

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

https://yongineer.duckdns.org/sql/095.png

๋ฐ˜๋ณต๊ณ„์˜ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์ฒ˜๋ฆฌ ๋Œ€์ƒ ๋ ˆ์ฝ”๋“œ ์ˆ˜์— ๋Œ€ํ•ด ์„ ํ˜•์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋Š” ์ด์œ ๋Š” ๊ฐ„๋‹จํ•˜๋‹ค. ๋ฐ˜๋ณต๊ณ„์˜ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์€ <์ฒ˜๋ฆฌ ํšŸ์ˆ˜> * <ํ•œ ํšŒ์— ๊ฑธ๋ฆฌ๋Š” ์ฒ˜๋ฆฌ ์‹œ๊ฐ„>์ด๋ฏ€๋กœ <ํ•œ ํšŒ์— ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„>์ด ์ผ์ •ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ์ฒ˜๋ฆฌ ํšŸ์ˆ˜ (์ฒ˜๋ฆฌ ๋Œ€์ƒ ๋ ˆ์ฝ”๋“œ ์ˆ˜)์— ๋น„๋ก€ํ•  ๊ฒƒ์ด๋‹ค.

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

SQL์‹คํ–‰์˜ ์˜ค๋ฒ„ ํ—ค๋“œ

SQL์„ ์‹คํ–‰ ํ•  ๋•Œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ฑฐ๋‚˜ ์—ฐ์‚ฐํ•˜๋Š” ์‹ค์ œ์˜ SQL ์ฒ˜๋ฆฌ ์ด์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์ฒ˜๋ฆฌ๊ฐ€ ์ด๋ฃจ์–ด ์ง„๋‹ค.

  • ์ „์ฒ˜๋ฆฌ

    1๏ธโƒฃ SQL ๊ตฌ๋ฌธ์„ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†ก

    2๏ธโƒฃ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ

    3๏ธโƒฃ SQL ๊ตฌ๋ฌธ ํŒŒ์Šค

    4๏ธโƒฃ SQL ๊ตฌ๋ฌธ์˜ ์‹คํ–‰ ๊ณ„ํš ์ƒ์„ฑ ๋˜๋Š” ํ‰๊ฐ€

  • ํ›„์ฒ˜๋ฆฌ

    5๏ธโƒฃ ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†ก

1๏ธโƒฃ ๊ณผ 5๏ธโƒฃ ๋Š” SQL์„ ์‹คํ–‰ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ฐ™์€ ๋ณธ์ฒด์— ์žˆ๋‹ค๋ฉด ๋ฐœ์ƒํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ผ์ • ๊ทœ๋ชจ ์ด์ƒ์˜ ์‹œ์Šคํ…œ์—์„œ๋Š” ๋ณดํ†ต ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„๋ฅผ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ SQL ๊ตฌ๋ฌธ ๋˜๋Š” ๊ฒฐ๊ณผ ์ง‘ํ•ฉ์„ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†กํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด๋„ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‘ ๊ฐ€์ง€๋Š” ๊ฐ™์€ ๋ฐ์ดํ„ฐ์„ผํ„ฐ ๋‚ด๋ถ€์˜ ๋™์ผ LAN์œ„์— ์žˆ์œผ๋ฏ€๋กœ ์ „์†ก ์†๋„ ์ž์ฒด๋Š” ๊ณ ์†(๊ฑฐ์˜ ms) ์ธ ๋งŒํผ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋”ฑํžˆ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

2๏ธโƒฃ ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— SQL ๊ตฌ๋ฌธ์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ž‘์—…์ด๋‹ค. ์ผ๋‹จ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•ด์„œ ์„ธ์…˜์„ ์„ค์ •ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ฐœ์ƒํ•˜๋Š” ์ฒ˜๋ฆฌ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ตœ๊ทผ์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฏธ๋ฆฌ ์—ฐ๊ฒฐ์„ ์ผ์ • ์ˆ˜ ํ™•๋ณดํ•ด์„œ ์ด๋Ÿฐ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๊ฐ์†Œ์‹œํ‚ค๋Š” ์ปค๋„ฅ์…˜ ํ’€(Connection Pool)์ด๋ผ๋Š” ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•œ๋‹ค. ๋”ฐ๋ผ์„œ 2๏ธโƒฃ๋„ ๊ฑฐ์˜ ๋ฌธ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค.

์˜ค๋ฒ„ํ—ค๋“œ ์ค‘์—์„œ๋„ ๊ฐ€์žฅ ์˜ํ–ฅ์ด ํฐ ๊ฒƒ์€ 3๏ธโƒฃ๋˜๋Š”4๏ธโƒฃ์ด๋‹ค. ํŠนํžˆ ์กฐ๊ธˆ ์„ฑ๊ฐ€์‹ ๊ฒƒ์„ ๊ณ ๋ฅธ๋‹ค๋ฉด 3๏ธโƒฃ, SQL ํŒŒ์Šค(๊ตฌ๋ฌธ ๋ถ„์„)์ด๋‹ค. ํŒŒ์Šค๋Š” DBMS๋งˆ๋‹ค ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๋ฏธ๋ฌ˜ํ•˜๊ฒŒ ๋‹ค๋ฅด๊ณ  ์ข…๋ฅ˜๋„ ๊ต‰์žฅํžˆ ๋งŽ๋‹ค. ํŠนํžˆ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋А๋ฆฐ ๋ถ€๋ถ„์€ 0.1์ดˆ ~ 1์ดˆ ์ •๋„ ๊ฑธ๋ฆฐ๋‹ค. ์ด๋Š” ๋‹ค๋ฅธ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐ€๋ฆฌ ์ดˆ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒƒ์— ๋น„ํ•ด ๊ต‰์žฅํžˆ ํฌ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํŒŒ์Šค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ SQL์„ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋ฏ€๋กœ ์ž‘์€ SQL์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณตํ•˜๋Š” ๋ฐ˜๋ณต๊ณ„์—์„œ๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋†’์•„์งˆ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.

๋ณ‘๋ ฌ ๋ถ„์‚ฐ์ด ํž˜๋“ค๋‹ค

๋ฐ˜๋ณต๊ณ„๋Š” ๋ฐ˜๋ณต 1ํšŒ ๋งˆ๋‹ค์˜ ์ฒ˜๋ฆฌ๋ฅผ ๊ต‰์žฅํžˆ ๋‹จ์ˆœํ™” ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ถ„์‚ฐํ•ด์„œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌํ•˜๋Š” ์ตœ์ ํ™”๊ฐ€ ์•ˆ๋œ๋‹ค. CPU์˜ ๋ฉ€ํ‹ฐ ์ฝ”์–ด๋กœ ๋ถ„์‚ฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์€ ๋ฌผ๋ก  ์ €์žฅ์†Œ์˜ ๋ถ„์‚ฐ ํšจ์œจ์ด ๋‚ฎ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„ ์ €์žฅ์†Œ๋Š” ๋Œ€๋ถ€๋ถ„ RAID ๋””์Šคํฌ๋กœ ๊ตฌ์„ฑ๋˜์–ด I/O ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ˜๋ณต๊ณ„์—์„œ ์‹คํ–‰ํ•˜๋Š” SQL๊ตฌ๋ฌธ์€ ๋Œ€๋ถ€๋ถ„ ๋‹จ์ˆœํ•ด์„œ 1ํšŒ์˜ SQL๊ตฌ๋ฌธ์ด ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ์–‘์ด ์ ๋‹ค. ๋”ฐ๋ผ์„œ I/O๋ฅผ ๋ณ‘๋ ฌํ™” ํ•˜๊ธฐ ํž˜๋“ค๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ง„ํ™”๋กœ ์ธํ•œ ํ˜œํƒ์„ ๋ฐ›์„ ์ˆ˜ ์—†๋‹ค.

DBMS๋Š” ๋‹จ์ˆœํ•œ SQL ๊ตฌ๋ฌธ๊ณผ ๊ฐ™์€ โ€˜๊ฐ€๋ฒผ์šดโ€™์ฒ˜๋ฆฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค ์•ˆ์ค‘์—๋„ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ˜๋ณต๊ณ„๋Š” ๋ฏธ๋“ค์›จ์–ด ๋˜๋Š” ํ•˜๋“œ์›จ์–ด์˜ ์ง„ํ™”์— ๋”ฐ๋ฅธ ํ˜œํƒ์„ ๊ฑฐ์˜ ๋ฐ›์„ ์ˆ˜ ์—†๋‹ค. ์‹ค์ œ๋กœ ๋ฐ˜๋ณต๊ณ„์˜ ์ฒ˜๋ฆฌ๊ฐ€ ๋А๋ ค์„œ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ ๊ทธ๋ƒฅ ๋Œ€์ถฉ ์Šค์ผ€์ผ์—…์„ ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌผ๋ฆฌ ๋ฆฌ์†Œ์Šค๊ฐ€ bottle neck์ด ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์Šค์ผ€์ผ์—…์„ ํ•ด๋„ ์†๋„๊ฐ€ ๋นจ๋ผ์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋„ ๋งŽ๋‹ค.

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

์ด๋Ÿฌํ•œ ํฌ์žฅ๊ณ„์˜ ์žฅ์ ์€ ๋ฐ˜๋Œ€๋กœ ๋ฐ˜๋ณต๊ณ„์˜ ๋‹จ์ ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ˜๋ณต๊ณ„๋Š” ๋‹จ์ง€ ๋А๋ฆฌ๊ธฐ๋งŒ ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋А๋ฆฐ ๊ตฌ๋ฌธ์„ ํŠœ๋‹ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ๋„ ๊ฑฐ์˜ ์—†๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ณต๊ณ„๊ฐ€ ์ •๋ง ๋ฌด์„œ์šด ๊ฒƒ์€ ๋ฐ”๋กœ ์ด ๋‹จ์ ์ด๋‹ค.

2. ๋ฐ˜๋ณต๊ณ„๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์„๊นŒ?

๋ฐ˜๋ณต๊ณ„๋ฅผ ํฌ์žฅ๊ณ„๋กœ ๋‹ค์‹œ ์ž‘์„ฑ

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

๊ฐ๊ฐ์˜ SQL์„ ๋น ๋ฅด๊ฒŒ ์ˆ˜์ •

๋ฐ˜๋ณต๊ณ„์—์„œ ์‚ฌ์šฉํ•˜๋Š” SQL๊ตฌ๋ฌธ์€ ๋„ˆ๋ฌด ๋‹จ์ˆœํ•˜๋‹ค. ์‹คํ–‰ ๊ณ„ํš์„ ๋ณด์•„๋„ unique scan๋˜๋Š” index range scan์ •๋„ ๋ฟ์ด๋‹ค. ์ด๋Ÿฐ ๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ์˜ ์–ด๋””๋ฅผ ์–ด๋–ป๊ฒŒ ํŠœ๋‹ํ•ด์•ผ ํ• ๊นŒ?

๊ฒŒ๋‹ค๊ฐ€ INSERT๊ตฌ๋ฌธ์„ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค. INSERT๊ตฌ๋ฌธ์€ SELECT๊ตฌ๋ฌธ๋ณด๋‹ค ๊ณ ์†ํ™”๊ฐ€ ๋” ์–ด๋ ต๋‹ค. ๋”ฐ๋ผ์„œ ํŠœ๋‹ ๊ฐ€๋Šฅ์„ฑ์ด ๋”์šฑ ์ œํ•œ๋œ๋‹ค.

๋‹ค์ค‘ํ™” ์ฒ˜๋ฆฌ

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

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

3. ๋ฐ˜๋ณต๊ณ„์˜ ์žฅ์ 

์ด๊ฒƒ์€ ๋ชจ๋‘ ๋ฐ˜๋ณต๊ณ„์˜ SQL๊ตฌ๋ฌธ์ด ์ง€๋‚˜์น˜๊ฒŒ ๋‹จ์ˆœํ•ด์„œ ์ƒ๊ธฐ๋Š” ์žฅ์ ์ด๋‹ค.

SELECT sale FROM sales2 WHERE company = 'A';

์ด๋Ÿฐ ๋‹จ์ˆœํ•œ ์ฟผ๋ฆฌ๋Š” ์‹คํ–‰ ๊ณ„ํš๋„ ์—„์ฒญ๋‚˜๊ฒŒ ๋‹จ์ˆœํ•˜๋‹ค.

https://yongineer.duckdns.org/sql/096.png

์‹คํ–‰ ๊ณ„ํš์˜ ์•ˆ์ •์„ฑ

์‹คํ–‰ ๊ณ„ํš์ด ๋‹จ์ˆœํ•˜๋‹ค๋Š” ๊ฒƒ์€ ํ•ด๋‹น ์‹คํ–‰ ๊ณ„ํš์— ๋ณ€๋™ ์œ„ํ—˜์ด ๊ฑฐ์˜ ์—†๋‹ค๋ผ๋Š”๊ฒƒ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋ณ€๋™์ด ์ผ์–ด๋‚œ๋‹ค๊ณ  ํ•ด ๋ดค์ž ๊ฒจ์šฐ ์˜ตํ‹ฐ๋งˆ์ด์ €์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ธ๋ฑ์Šค๋ฅผ ๋ฐ”๊พธ๋Š” ์ •๋„์ด๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ ์šด์šฉ ์ค‘์— ๊ฐ‘์ž๊ธฐ ์‹คํ–‰ ๊ณ„ํš์ด ๋ฐ”๋€Œ์–ด ๋А๋ ค์ง€๋Š” ํ˜„์ƒ์„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Ÿฐ ํ˜„์ƒ์€ ๋น„์šฉ ๊ธฐ๋ฐ˜(cost base)์˜ ์˜ตํ‹ฐ๋งˆ์ด์ €์—์„œ๋Š” ์ˆ™๋ช…์ ์ธ ๊ฒƒ์ธ๋ฐ, ๊ทธ๋กœ๋ถ€ํ„ฐ ์กฐ๊ธˆ์€ ์ž์œ ๋กœ์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ํŠนํžˆ SQL๊ตฌ๋ฌธ ๋‚ด๋ถ€์—์„œ ๊ฒฐํ•ฉ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ๊ฒƒ์ด ๊ต‰์žฅํžˆ ํฌ๊ฒŒ ์ž‘์šฉํ•œ๋‹ค. ์‹คํ–‰ ๊ณ„ํš ๋ณ€๋™์—์„œ ๊ฐ€์žฅ ๊ณจ์นซ๊ฑฐ๋ฆฌ๊ฐ€ ๋˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ๊ฒฐํ•ฉ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ณ€๊ฒฝ์ด ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋Š” ์–ด๋–ค ์˜๋ฏธ์—์„œ ๊ทœ์น™ ๊ธฐ๋ฐ˜(rule base)์—์„œ ๋น„์šฉ ๋ฐ”ํƒ•์œผ๋กœ ๋ณ€ํ™”ํ•˜๋Š” DBMS์˜ ๋นˆํ™”๋ฅผ ๊ฑฐ์Šค๋ฅด๋Š” ๊ฒƒ์ด๋‹ค. ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์™„๋ฒฝํ•˜์ง€ ์•Š์€ ํ˜„์žฌ ์‹œ์ ์—์„œ ์•ˆ์ •์ ์ธ ์„ฑ๋Šฅ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ์ •๋ง ์–ด๋งˆ์–ด๋งˆํ•œ ์žฅ์ ์ด๋‹ค.

๋ฐ˜๋Œ€๋กœ ๋งํ•˜๋ฉด, ์ด๋Š” ํฌ์žฅ๊ณ„์˜ ๋‹จ์ ์ด๋‹ค. ํฌ์žฅ๊ณ„๋Š” SQL๊ตฌ๋ฌธ์ด ๋ณต์žกํ•œ ๋งŒํผ ์‹คํ–‰ ๊ณ„ํš์˜ ๋ณ€๋™ ๊ฐ€๋Šฅ์„ฑ์ด ๊ต‰์žฅํžˆ ํฌ๋‹ค. ๋ฌผ๋ก  ์˜ตํ‹ฐ๋งˆ์ด์ €๊ฐ€ ์ž˜ ํ•  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ์žฅ์ ์ด๊ณ , ์œ„ํ—˜ํ•˜๋‹ค ์ƒ๊ฐํ•˜๋ฉด ๋‹จ์ ์ด ๋˜๋Š” ๋ฏธ๋ฌ˜ํ•œ ๋ถ€๋ถ„์ด๋‹ค. ํ•˜์ง€๋งŒ ํ˜„ ์‹œ์ ์—์„œ, ์‹คํ–‰ ๊ณ„ํš ๋ณ€๋™์ด ์‰ฌ์šด SQL๊ตฌ๋ฌธ์— ๋Œ€ํ•ด์„œ๋Š” ๋ถ€๋ถ„์ ์œผ๋กœ ํžŒํŠธ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด ์‹คํ–‰ ๊ณ„ํš์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ์กฐ๊ธˆ ๋‹จ์ˆœํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

์˜ˆ์ƒ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์˜ ์ •๋ฐ€๋„

์‹คํ–‰ ๊ณ„ํš์ด ๋‹จ์ˆœํ•˜๊ณ  ์„ฑ๋Šฅ์ด ์•ˆ์ •์ ์ด๋ผ๋Š” ๊ฒƒ์€ ์ถ”๊ฐ€์ ์ธ ์žฅ์ ์„ ๊ฐ€์ ธ์˜จ๋‹ค. ๋ฐ”๋กœ ์˜ˆ์ƒ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์˜ ์ •๋ฐ€๋„๊ฐ€ ๋†’๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ฐ˜๋ณต๊ณ„์˜ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œํ˜„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • <์ฒ˜๋ฆฌ ์‹œ๊ฐ„> = <ํ•œ ๋ฒˆ์˜ ์‹คํ–‰ ์‹œ๊ฐ„> * <์‹คํ–‰ ํšŸ์ˆ˜>

์‹คํ–‰ ํšŸ์ˆ˜๋Š” ๊ธฐ๋Šฅ ์š”๊ฑด์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ํ•œํŽธ ํ•œ ๋ฒˆ์˜ ์‹คํ–‰ ์‹œ๊ฐ„์€ ๋Œ€์ถฉ 0.1๋ฐ€๋ฆฌ ์ดˆ ~ 0.5์ดˆ ์ •๋„ ์‚ฌ์ด์ด๋‹ค. 0.1๋ฐ€๋ฆฌ ์ดˆ์™€ 0.5์ดˆ๋Š” 5000๋ฐฐ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ ˆ๋Œ€์น˜๋กœ ๋ณด๋ฉด ๊ทธ๋ ‡์ง€๋งŒ SQL ๊ตฌ๋ฌธ์€ ๋ฏธ์„ธํ•œ ์กฐ๊ฑด์˜ ์ฐจ์ด๋กœ ์ˆ˜๋ฐฐ ~ ์ˆ˜๋ฐฑ ๋ฐฐ์˜ ์ฐจ์ด๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ์ด๋ฏ€๋กœ, ์ด ์ •๋„๋งŒ ํ•ด๋„ ์˜ˆ์ƒ์„ ์œ„ํ•œ ์ •๋ฐ€๋„๊ฐ€ ๋†’๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋‹ค. ํฌ์žฅ๊ณ„๋Š” ์‹คํ–‰ ๊ณ„ํš์— ๋”ฐ๋ผ ์„ฑ๋Šฅ์ด ์ „ํ˜€ ๋‹ฌ๋ผ์ง€๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋žจ์˜ ์‚ฌ์–‘์„ ์‚ฌ์ „์— ์˜ˆ์ƒํ•˜๊ธฐ ์กฐ์ฐจ ํž˜๋“ค๋‹ค. ๊ทธ์— ๋น„ํ•˜๋ฉด ๊ต‰์žฅํžˆ ๊ดœ์ฐฎ๋‹ค.

์ •๋ฐ€ํ•œ ์˜ˆ์ƒ์„ ํ•˜๋ ค๋ฉด, ์–ด๋А ์ •๋„ ๊ทœ๋ชจ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด ๋ชจ๋ธ ๊ฒ€์ฆ์„ ํ•œ ๋’ค์—, ๋ช‡ ๊ฐœ์—์„œ ์–ด๋А ์ •๋„์˜ ์‹คํ–‰ ์‹œ๊ฐ„์ด ๋‚˜์˜ค๋Š”์ง€ ์ธก์ •ํ•˜๊ณ  (10๋งŒ ๊ฑด, 100๋งŒ ๊ฑด, 1000๋งŒ ๊ฑด ๋“ฑ), ์‹คํ–‰ ์‹œ๊ฐ„์ด ์„ ํ˜•์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋Š”์ง€ ์—ฌ๋ถ€์™€ ๊ธฐ์šธ๊ธฐ๋ฅผ ํ™•์ธํ•ด์„œ ๊ณ„์‚ฐํ•ด์•ผ ํ•œ๋‹ค.

ํŠธ๋žœ์žญ์…˜ ์ œ์–ด๊ฐ€ ํŽธ๋ฆฌ

๋ฐ˜๋ณต๊ณ„์˜ ๋˜ ํ•˜๋‚˜์˜ ์žฅ์ ์€ ํŠธ๋žœ์žญ์…˜์˜ ์ •๋ฐ€๋„๋ฅผ ๋ฏธ์„ธํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐฑ์‹  ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ˜๋ณต๊ณ„์—์„œ, ํŠน์ • ๋ฐ˜๋ณต ํšŸ์ˆ˜๋งˆ๋‹ค ์ปค๋ฐ‹ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ๋งŒ์•ฝ ์ค‘๊ฐ„์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ํ•ด๋„, ์ค‘๊ฐ„์— ์ปค๋ฐ‹์„ ํ–ˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ์ง€์  ๊ทผ์ฒ˜์—์„œ ๋‹ค์‹œ ์ฒ˜๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋œ๋‹ค. ๋˜ํ•œ ํŠน์ • ์ด์œ ๋กœ ๋ฐฐ์น˜๋ฅผ ์ž ์‹œ ์ค‘๋‹จํ•ด์•ผ ํ•  ๋•Œ๋„ ํ•ด๋‹น ์ง€์  ๊ทผ์ฒœ์—์„œ ๋‹ค์‹œ ์ฒ˜๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฏธ์„ธํ•œ ์ œ์–ด๋Š” ํฌ์žฅ๊ณ„์˜ SQL๊ตฌ๋ฌธ์—์„œ๋Š” ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค. ํฌ์žฅ๊ณ„์—์„œ๋Š” ๊ฐฑ์‹  ์ฒ˜๋ฆฌ ์ค‘๊ฐ„์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์ฒ˜๋ฆฌ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

SQL์—์„œ๋Š” ๋ฐ˜๋ณต์„ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ• ๊นŒ?

1. ํฌ์ธํŠธ๋Š” CASE์‹๊ณผ ์œˆ๋„์šฐ ํ•จ์ˆ˜

SQL์—์„œ ๋ฐ˜๋ณต์„ ๋Œ€์‹ ํ•˜๋Š” ์ˆ˜๋‹จ์€ ๋ฐ”๋กœ CASE์‹๊ณผ ์œˆ๋„์šฐ ํ•จ์ˆ˜์ด๋‹ค. ์ •ํ™•ํ•˜๊ฒŒ CASE์‹์€ ์ ˆ์ฐจ ์ง€ํ–ฅํ˜• ์–ธ์–ด์—์„œ ๋งํ•˜๋Š” IF-THEN-ELSE๊ตฌ๋ฌธ์— ๋Œ€์‘ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

SQL์—์„œ๋„ CASE์‹๊ณผ ์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์„ธํŠธ๋ผ๊ณ  ๊ธฐ์–ตํ•˜๋ฉด๋œ๋‹ค. ๋ฐ˜๋ณต๊ณ„์˜ ์ฝ”๋“œ๋ฅผ ํฌ์žฅ๊ณ„์˜ SQL๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

INSERT INTO sales2
	SELECT company, year, sale, CASE SIGN(sale - MAX(sale)
																					OVER(PARTITION BY company ORDER BY year
																									ROWS BETWEEN 1 PRECEDING
																												AND 1 PRECEDING))
	WHEN 0 THEN '='
	WHEN 1 THEN '+'
	WHEN -1 THEN '-'
	ELSE NULL END AS var
FROM sales

์ด ์ฝ”๋“œ์˜ ํฌ์ธํŠธ๋Š” ๋ฐ”๋กœ SIGNํ•จ์ˆ˜์ด๋‹ค. SIGNํ•จ์ˆ˜๋Š” ์ˆซ์ž ์ž๋ฃŒํ˜•์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„ ์Œ์ˆ˜๋ผ๋ฉด -1, ์–‘์ˆ˜๋ผ๋ฉด 1, 0์ด๋ผ๋ฉด 0์„ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ์ง์ „ ์—ฐ๋„์™€์˜ ํŒ๋งค ๋ณ€ํ™”๋ฅผ ์•Œ๊ณ ์ž ์‚ฌ์šฉํ–ˆ๋‹ค. CASE์‹์˜ ์กฐ๊ฑด ๋ถ€๋ถ„์— ์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ๋ช‡ ๋ฒˆ์”ฉ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก ํ•ด์ฃผ๋Š” ๊ธฐ์ˆ ์ด๊ธฐ๋„ ํ•˜๋‹ค.

๊ทธ๋Ÿผ ์ด์ œ INSERT๊ตฌ๋ฌธ์„ ์ œ์™ธํ•œ SELECT๊ตฌ๋ฌธ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ์‚ดํŽด๋ณด์ž

https://yongineer.duckdns.org/sql/097.png

์ผ๋‹จ sales ํ…Œ์ด๋ธ”์„ ํ’€์Šค์บ”ํ•˜๊ณ  (WHERE๊ตฌ๋ฅผ ์‚ฌ์šฉํ•œ ์กฐ๊ฑด ์ง€์ •์ด ์—†์œผ๋ฏ€๋กœ ๋‹น์—ฐํ•จ), ์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ์ •๋ ฌ๋กœ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. (Extra : Using filesort) ํ˜„์žฌ SELECT ๊ตฌ๋ฌธ์€ ๊ฒฐํ•ฉ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•ด๋„ ์‹คํ–‰ ๊ณ„ํš์— ๋ณ„๋‹ค๋ฅธ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฏ€๋กœ ์•ˆ์ •์ ์ด๋ผ ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

์œ„ ์ฝ”๋“œ์—์„œ ์ค‘์š”ํ•œ ํฌ์ธํŠธ๋Š” ์œˆ๋„์šฐ ํ•จ์ˆ˜์— ROWS BETWEEN์˜ต์…˜์„ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด๋‹ค. ์ด๋Š” ๋Œ€์ƒ ๋ฒ”์œ„์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ง์ „์˜ 1๊ฐœ๋กœ ์ œํ•œํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING์€ โ€˜ํ˜„์žฌ ๋ ˆ์ฝ”๋“œ์—์„œ 1๊ฐœ ์ด์ „ ๋ถ€ํ„ฐ 1๊ฐœ ์ด์ „๊นŒ์ง€์˜ ๋ ˆ์ฝ”๋“œ ๋ฒ”์œ„โ€™๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋”ฐ๋ผ์„œ ์ง์ „์˜ 1๊ฐœ๋กœ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ œํ•œํ•˜๊ฒŒ ๋œ๋‹ค.

https://yongineer.duckdns.org/sql/098.png

๋”ฐ๋ผ์„œ ํ˜„์žฌ ์œˆ๋„์šฐ ํ•จ์ˆ˜๋Š” โ€˜๊ฐ™์€ ํšŒ์‚ฌ์˜ ์ง์ „ ๋งค์ƒโ€™์„ ๋ฆฌํ„ดํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

SELECT company, year, sale, 
				MAX(company) 
						OVER (PARTITION BY company ORDER BY year
										ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS pre_company,
				MAX(sale)
						OVER (PARTITION BY company ORDER BY year
										ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS pre_sale,
FROM sales;

https://yongineer.duckdns.org/sql/099.png

์ด๋•Œ ๋งŒ์•ฝ ๋น„๊ต ๋Œ€์ƒ ๋ ˆ์ฝ”๋“œ๋ฅผ โ€˜1๊ฐœ ์ „ ๋ ˆ์ฝ”๋“œโ€™๊ฐ€ ์•„๋‹Œ โ€˜2๊ฐœ ์ „ ๋ ˆ์ฝ”๋“œโ€™๋กœ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING ์œผ๋กœ ๋ฒ”์œ„๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์œ ์—ฐํ•จ์€ ์œ„๋„์šฐ ํ•จ์ˆ˜๊ฐ€ ๋ณด๊ธ‰๋˜๊ธฐ ์ด์ „์— ์‚ฌ์šฉํ•˜๋˜ ์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ๋Š” ํ•˜๊ธฐ ํž˜๋“  ๊ฒƒ์ด๋‹ค.

๐Ÿ’ก ์ƒ๊ด€ ์„œ๋ธŒ๋ญ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋Œ€์ƒ ๋ ˆ์ฝ”๋“œ ์ œํ•œ

์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” ์„œ๋ธŒ์ฟผ๋ฆฌ ๋‚ด๋ถ€์—์„œ ์™ธ๋ถ€ ์ฟผ๋ฆฌ์™€์˜ ๊ฒฐํ•ฉ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•˜๊ณ , ํ•ด๋‹น ๊ฒฐํ•ฉ ํ‚ค๋กœ ์ž˜๋ผ์ง„ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์„ ์กฐ์ž‘ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค. ์ด๋ ‡๋‚˜ ์ ์—์„œ ์œˆ๋„์šฐ ํ•จ์ˆ˜์˜ PARTITION BY๊ตฌ์™€ ORDER BY๊ตฌ์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ฐ–๋Š”๋‹ค. ์•ž์„œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๊ฒฐํ•ฉ์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋œ๋‹ค.

SELECT company, year, sale,
				(SELECT company FROM sales S2 
						WHERE S1.company = S2.company AND 
								year = (SELECT MAX(yaer) FROM sales S3
													WHERE S1.company = S3.company # ์ƒ๊ด€ ์„œ๋ธŒ ์ฟผ๋ฆฌ์˜ ๊ฒฐํ•ฉ ์กฐ๊ฑด
														AND S1.year > S3.year)) AS pre_company
				(SELECT sale FROM sales S2 
						WHERE S1.company = S2.company AND 
								year = (SELECT MAX(yaer) FROM sales S3
													WHERE S1.company = S3.company # ์ƒ๊ด€ ์„œ๋ธŒ ์ฟผ๋ฆฌ์˜ ๊ฒฐํ•ฉ ์กฐ๊ฑด
														AND S1.year > S3.year)) AS pre_sale
FROM sales S1

์ƒ๊ด€ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ์—์„œ๋Š” โ€˜์ง์ „โ€™ ๋˜๋Š” โ€˜์งํ›„โ€™์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌํ•  ๋•Œ MAX/MINํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ๋ฒˆ์งธ, ์„ธ ๋ฒˆ์งธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์กฐ๊ธˆ ์–ด๋ ต๋‹ค. ๋˜ํ•œ ์‹คํ–‰ ๊ณ„ํš์ด ๊ต‰์žฅํžˆ ๋ณต์žกํ•ด์ง€๋ฏ€๋กœ ์„ฑ๋Šฅ์ ์ธ ๋ฆฌ์Šคํฌ๋„ ๋ฐœ์ƒํ•œ๋‹ค.

2. ์ตœ๋Œ€ ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ ์ •ํ•ด์ง„ ๊ฒฝ์šฐ

์ธ์ ‘ํ•œ ์šฐํŽธ ๋ฒˆํ˜ธ ์ฐพ๊ธฐ

์ผ๋ณธ์—์„œ๋Š” 413-0033์ฒ˜๋Ÿผ ํ•˜์ดํ”ˆ(-)์œผ๋กœ ๊ตฌ๋ถ„๋œ 7์ž๋ฆฌ ์ˆซ์ž๋ฅผ ์šฐํŽธ๋ฒˆํ˜ธ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ์•ž์˜ ์„ธ ์ž๋ฆฌ๋Š” ์ง€์—ญ์„ ๋‚˜ํƒ€๋‚ด๊ณ , ์˜ค๋ฅธ์ชฝ ๋„ค ์ž๋ฆฌ๋Š” ํ•ด๋‹น ์ง€์—ญ์„ ์กฐ๊ธˆ ๋” ์ž์„ธํ•˜๊ฒŒ ๋‚˜๋ˆ„์–ด ์ผ๋ จ ๋ฒˆํ˜ธ๋ฅผ ๋ถ™์ธ ๊ฒƒ์ด๋‹ค. ์œ ์ผ์„ฑ ๊ด€์ ์—์„œ ๋ณด๋ฉด, ํ•˜์ดํ”ˆ์„ ์ œ์™ธํ•œ 4130033์™€ ๊ฐ™์€ ์ผ๊ณฑ ์ž๋ฆฌ ์ˆซ์ž๊ฐ€ ์œ ์ผํ•˜๋‹ค. ์ด๋•Œ ํ•˜์œ„ ์ž๋ฆฟ์ˆ˜๊นŒ์ง€ ์ผ์น˜ํ• ์ˆ˜๋ก ๊ฐ€๊นŒ์šด ์ง€์—ญ์ž„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 4130033์€ ์‹œ์ฆˆ์˜ค์นดํ˜„ ์•„ํƒ€๋ฏธ์‹œ ์•„ํƒ€๋ฏธ๋ฅผ ๋‚˜ํƒœ๋‚ด๊ณ  4130002๋Š” ์‹œ์ฆˆ์˜ค์นดํ˜„ ์•„ํƒ€๋ฏธ์‹œ ์ด์ฆˆ์‚ฐ์„ ๋‚˜ํƒ€๋‚ด๋ฏ€๋กœ ์ธ์ ‘ํ•œ ์ง€์—ญ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ์šฐํŽธ๋ฒˆํ˜ธ์˜ ์„ฑ์งˆ์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ๋ฅผ ํ’€์–ด๋ณด์ž. ์ผ๋‹จ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ ๋‹ค. ์ด ํ…Œ์ด๋ธ”์— ์ €์žฅํ•˜๋Š” ์šฐํŽธ๋ฒˆํ˜ธ๋Š” ์ง‘ํ•ฉ์—์„œ ์ž…๋ ฅ๋ฐ›์€ ์šฐํŽธ๋ฒˆํ˜ธ์™€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ๊ฒ€์ƒ‰ํ•ด๋ณธ๋‹ค ๊ฐ€์ •ํ• ๋•Œ ๊ฐ€๊นŒ์šด ์ง€์—ญ์ผ ์ˆ˜๋ก ํ•˜์œ„ ์ž๋ฆฌ ์ˆซ์ž๊นŒ์ง€ ์ผ์น˜ํ•  ๊ฒƒ์ด๋‹ค. 7์ž๋ฆฌ๊ฐ€ ๋ชจ๋‘ ์ผ์น˜ํ•œ๋‹ค๋ฉด ๊ทธ๊ฒƒ์ด ๋‹ต์ด์ง€๋งŒ, ์ •ํ™•ํ•˜๊ธฐ ์ผ์น˜ํ•˜๋Š” ์ˆซ์ž๊ฐ€ ์—†์„ ๋•Œ๋Š” ์™ผ์ชฝ๋ถ€ํ„ฐ์˜ ์ž๋ฆฟ์ˆ˜๊ฐ€ ๋งŽ์ด ์ผ์น˜ํ•˜๋Š” ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ๋‹ต์œผ๋กœ ํ•œ๋‹ค.

๋จผ์ € ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

https://yongineer.duckdns.org/sql/100.png

์ด ํ…Œ์ด๋ธ”์—์„œ ๋งŒ์•ฝ ์šฐํŽธ๋ฒˆํ˜ธ 4130033์„ ์ž…๋ ฅ์‹œ ์ธ์ ‘ํ•œ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค.

https://yongineer.duckdns.org/sql/101.png

์ด ๋ฌธ์ œ์˜ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ์žˆ์–ด ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ์ผ๋‹จ ์šฐํŽธ๋ฒˆํ˜ธ 4130033์ด ํ…Œ์ด๋ธ”์— ์žˆ๋Š”์ง€๋ฅผ ์ฐพ๋Š”๋‹ค ๋งŒ์•ฝ ์—†๋‹ค๋ฉด ์ด์–ด์„œ 413003* (์—ฌ๊ธฐ์„œ *์€ ์ž„์˜์˜ ์ˆซ์ž)๊ฐ€ ์žˆ๋Š”์ง€๋ฅผ ์ฐพ๋Š”๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—†๋‹ค๋ฉด ์ด์–ด์„œ 41300**๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ๋Š”๋‹ค. ๋งŒ์•ฝ ์ผ์น˜ํ•˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด๊ฒƒ์„ ์ถœ๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋ฐฉ๋ฒ•์€ ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์„ฑ๋Šฅ ์ธก๋ฉด์—์„œ ์ ์  ์•…ํ™”๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

๊ฒฐ๊ตญ, ์ˆœ์œ„ ๋ถ™์ด๊ธฐ ๋ฌธ์ œ

์ด ๋ฌธ์ œ์˜ ํฌ์ธํŠธ๋Š” ์ˆœ์œ„์ด๋‹ค. ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์šฐํŽธ๋ฒˆํ˜ธ ์ˆœ์œ„๋ฅผ 0, ๊ฐ€์žฅ ๋จผ ์šฐํŽธ๋ฒˆํ˜ธ ์ˆœ์œ„๋ฅผ 6์œผ๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค.

https://yongineer.duckdns.org/sql/102.png

์ด๋Ÿฌํ•œ rank_pcodeํ•„๋“œ๋ฅผ ๋งŒ๋“œ๋ ค๋ฉด CASE์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

SELECT pcode, district_name,
	CASE WHEN pcode = '4130033' THEN 0
			 WHEN pcode LIKE '413003%' THEN 1
			 WHEN pcode LIKE '41300%' THEN 2
			 WHEN pcode LIKE '4130%' THEN 3
			 WHEN pcode LIKE '413%' THEN 4
			 WHEN pcode LIKE '41%' THEN 5
			 WHEN pcode LIKE '4%' THEN 6
			 ELSE NULL END AS rank_pcode
FROM PostalCode ORDER BY rank_pcode

CASE์‹์˜ WHEN๊ตฌ๋Š” ์ฐจ๋ก€๋Œ€๋กœ ์กฐ๊ฑด์„ ๊ฒ€์‚ฌํ•˜๋‹ค๊ฐ€. ์กฐ๊ฑด์ด ๋งž์œผ๋ฉด ์ดํ›„์˜ WHEN๊ตฌ๋ฅผ ํ‰๊ฐ€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์ˆœ์œ„๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋ฉด ์ด ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์„๊ฒƒ์ด๋‹ค.

  • ์ˆœ์œ„๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ์„ ํƒ

์ˆœ์œ„๊ฐ€ ๊ฐ€์žฅ ๋†’๋‹ค๋Š” ๊ฒƒ์€ rank_pcodeํ•„๋“œ์˜ ๊ฐ’์ด ๊ฐ€์žฅ ์ž‘๋‹ค๋Š” ์˜๋ฏธ์ด๋ฏ€๋กœ MINํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

SELECT pcode, district_name FROM PostalCode
	WHERE CASE WHEN pcode = '4130044' THEN 0
						 WHEN pcode LIKE '413003%' THEN 1
						 WHEN pcode LIKE '41300%' THEN 2
						 WHEN pcode LIKE '4130%' THEN 3
						 WHEN pcode LIKE '413%' THEN 4
						 WHEN pcode LIKE '41%' THEN 5
						 WHEN pcode LIKE '4%' THEN 6
						 ELSE NULL END =
									(SELECT MIN(CASE WHEN pcode = '4130033' THEN 0 
																	 WHEN pcode LIKE '413003%' THEN 1
																	 WHEN pcode LIKE '41300%' THEN 2
																	 WHEN pcode LIKE '4130%' THEN 3
																	 WHEN pcode LIKE '413%' THEN 4
																	 WHEN pcode LIKE '41%' THEN 5
																	 WHEN pcode LIKE '4%' THEN 6
																	 ELSE NULL END)
										FROM PostalCode);

https://yongineer.duckdns.org/sql/103.png

์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์˜ ํฌ์ธํŠธ๋Š” 7ํšŒ ๋ฐ˜๋ณต์„ CASE์‹์˜ ๋ถ„๊ธฐ๋กœ ๋ณ€ํ™˜ํ–ˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•ด SQL ๊ตฌ๋ฌธ์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•  ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์ด ์ฟผ๋ฆฌ๋Š” ์„ฑ๋Šฅ์ ์ธ ๊ด€์ ์—์„œ ๊ฐ€์žฅ ์ข‹์€ ๋‹ต์ด๋ผ ํ•˜๊ธฐ์—๋Š” ์•„์ง ์ด๋ฅด๋‹ค. ์‹คํ–‰ ๊ณ„ํš์„ ์‚ดํŽด๋ณด๋ฉด ํ…Œ์ด๋ธ”์— ์ ‘๊ทผ์ด 2ํšŒ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

https://yongineer.duckdns.org/sql/104.png

๋งŒ์•ฝ ํ…Œ์ด๋ธ”์˜ ์ˆ˜๊ฐ€ ์ˆ˜๋ฐฑ ๋งŒ์—์„œ ์ˆ˜์ฒœ ๋งŒ์œผ๋กœ ๋Š˜์–ด๋‚˜๋ฉด ์‹œ๊ฐ„์ด ๊ฝค ๊ฑธ๋ฆด๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ์Šค์บ” ํšŸ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์—ฐ๊ตฌํ•ด์•ผ ํ•œ๋‹ค.

์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ์Šค์บ” ํšŸ์ˆ˜ ๊ฐ์†Œ

๊ทธ๋Ÿฐ๋ฐ ์™œ ํ…Œ์ด๋ธ” ์Šค์บ”์ด 2ํšŒ ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ƒ๊ฐํ•ด๋ด์•ผ ํ•œ๋‹ค. ๋ฐ”๋กœ ์ˆœ์œ„์˜ ์ตœ์†Ÿ๊ฐ’์„ ์„œ๋ธŒ์ฟผ๋ฆฌ์—์„œ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ณ ์ „์ ์ธ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šค์บ” ํšŸ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

SELECT pcode, district_name 
	FROM (SELECT pcode, district_name,
										CASE WHEN pcode = '4130044' THEN 0
												 WHEN pcode LIKE '413003%' THEN 1
												 WHEN pcode LIKE '41300%' THEN 2
												 WHEN pcode LIKE '4130%' THEN 3
												 WHEN pcode LIKE '413%' THEN 4
												 WHEN pcode LIKE '41%' THEN 5
												 WHEN pcode LIKE '4%' THEN 6
												 ELSE NULL END AS hit_code,
										MIN(CASE WHEN pcode = '4130033' THEN 0 
														 WHEN pcode LIKE '413003%' THEN 1
														 WHEN pcode LIKE '41300%' THEN 2
														 WHEN pcode LIKE '4130%' THEN 3
														 WHEN pcode LIKE '413%' THEN 4
														 WHEN pcode LIKE '41%' THEN 5
														 WHEN pcode LIKE '4%' THEN 6
														 ELSE NULL END)
										OVER(ORDER BY CASE WHEN pcode = '4130033' THEN 0 
																			 WHEN pcode LIKE '413003%' THEN 1
																			 WHEN pcode LIKE '41300%' THEN 2
																			 WHEN pcode LIKE '4130%' THEN 3
																			 WHEN pcode LIKE '413%' THEN 4
																			 WHEN pcode LIKE '41%' THEN 5
																			 WHEN pcode LIKE '4%' THEN 6
																			 ELSE NULL END) AS min_code
				FROM PostalCode)Foo
WHERE hit_code = min_code;

https://yongineer.duckdns.org/sql/105.png

์‹คํ–‰๊ณ„ํš์„ ๋ณด๋ฉด ํ…Œ์ด๋ธ” ์ ‘๊ทผ์ด 1ํšŒ๋กœ ๊ฐ์†Œํ•œ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์œˆ๋„์šฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ ์ธํ•ด ์ •๋ ฌ (Using filesort)๊ฐ€ ์ถ”๊ฐ€๋กœ ์‚ฌ์šฉ๋˜์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๊ธฐ์— ๋น„์šฉ์ด ์ถ”๊ฐ€๋˜๋Š”๋ฐ ํ…Œ์ด๋ธ” ํฌ๊ธฐ๊ฐ€ ํฌ๋‹ค๋ฉด ํ…Œ์ด๋ธ” ํ’€ ์Šค์บ”์„ ์ค„์ด๋Š” ๊ฒƒ์˜ ํšจ๊ณผ๊ฐ€ ๋” ํฌ๋‹ค.

๐Ÿ’กselect_type์˜ DERIVED

MySQL์˜ ์‹คํ–‰๊ณ„ํš์—์„œ DERIVED๋ž€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • FROM์ ˆ์— ์‚ฌ์šฉ๋œ ์„œ๋ธŒ ์ฟผ๋ฆฌ๋กœ ๋ถ€ํ„ฐ ๋ฐœ์ƒํ•œ ์ž„์‹œํ…Œ์ด๋ธ”
  • ์ด ์ž„์‹œํ…Œ์ด๋ธ”์€ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋  ์ˆ˜ ๋„ ์žˆ๊ณ  ๋””์Šคํฌ์— ์ €์žฅ๋  ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ ์„ฑ๋Šฅ์ €ํ•˜๊ฐ€ ์—†์ง€๋งŒ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์„œ ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ๋””์Šคํฌ์— ์ €์žฅํ•˜๋ฉด ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง€๊ฒŒ ๋œ๋‹ค.

3. ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ ์ •ํ•ด์ง€์ง€ ์•Š์€ ๊ฒฝ์šฐ

์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ชจ๋ธ๊ณผ ์žฌ๊ท€ ์ฟผ๋ฆฌ

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ˜„์žฌ ์ฃผ์†Œ(pcode)๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ณผ๊ฑฐ์— ์‚ด๋˜ ์ฃผ์†Œ(new_pcode)๊นŒ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ํ…Œ์ด๋ธ”์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด์ž

https://yongineer.duckdns.org/sql/106.png

์ด ํ…Œ์ด๋ธ”์— ํ˜„์žฌ ์ฃผ์†Œ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ˜„์žฌ ์ฃผ์†Œ์˜ ์šฐํŽธ๋ฒˆํ˜ธ๋งŒ ๋“ฑ๋กํ•˜๊ณ  โ€˜์ด์‚ฌํ•˜๋Š” ๊ณณ์˜ ์šฐํŽธ๋ฒˆํ˜ธโ€™๋Š” NULL๋กœ ํ•œ๋‹ค.

('A', '4130001', NULL)

์ดํ›„ A๊ฐ€ ์ด์‚ฌ๋ฅผ ํ•˜๋Š” ์‹œ์ ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด โ€˜์ด์‚ฌํ•˜๋Š” ๊ณณ์˜ ์šฐํŽธ๋ฒˆํ˜ธโ€™๋ฅผ ๋ณ€๊ฒฝ ํ•œ๋‹ค.

('A', '4130001', NULL) -> ('A', '4130001', '4130002')

์ด๋ฒˆ์—๋Š” ๋‹ค์‹œ, ์ด์‚ฌํ•œ ๊ณณ์˜ ์ฃผ์†Œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒˆ๋กœ์šด ๋ ˆ์ฝ”๋“œ๋กœ ๋“ฑ๋กํ•œ๋‹ค.

('A', '4130002', NULL)

์ดํ›„ A๊ฐ€ ์ด์‚ฌ๋ฅผ ๋ฐ˜๋ณตํ•  ๋•Œ๋งˆ๋‹ค ์ด๋Ÿฌํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ˜๋ณตํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ด๋ ฅ์„ ์ €์žฅํ•˜๋ฉด A๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด์‚ฌ๋ฅผ ๋‘๋ฒˆ ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

4130001 -> 4130002 -> 4130103(ํ˜„์žฌ ์ฃผ์†Œ)

์‹ค์ œ ์šฐ์ฒด๊ตญ์—์„œ๋„ ์˜ค๋žœ๋œ ์ฃผ์†Œ๋กœ ๋ณด๋‚ด์ง„ ์šฐํŽธ๋ฌผ์„ ์ƒˆ๋กœ์šด ์ฃผ์†Œ๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ์ด๋ ฅ์„ ๊ด€๋ฆฌํ•œ๋‹ค. ์ด์ฒ˜๋Ÿผ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ํ‚ค๋กœ ์‚ผ์•„ ๋ฐ์ดํ„ฐ๋ฅผ ์ค„์ค„์ด ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์„ ํฌ์ธํ„ฐ ์ฒด์ธ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๊ณ ์ „์ ์ธ ๋ฐฉ๋ฒ•์ด๋‹ค. ํฌ์ธํ„ฐ ์ฒด์ธ์„ ์‚ฌ์šฉํ•˜๋Š” PostalHistory ๊ฐ™์€ ํ…Œ์ด๋ธ” ํ˜•์‹์„ ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ชจ๋ธ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๋งŒ์•ฝ A๊ฐ€ ๊ฐ€์žฅ ์˜ค๋ž˜์ „์— ์‚ด์•˜๋˜ ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•œ๋‹ค๋ฉด ๋‹ต์€ 4130001์ผ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์„ ์ฐพ์œผ๋ ค๋ฉด ํ˜„์žฌ ์ฃผ์†Œ์—์„œ ์ถœ๋ฐœํ•ด์„œ ์ฐจ๊ทผ์ฐจ๊ทผ ์ด์ „ ์ฃผ์†Œ๋ฅผ ์ฐพ์•„์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ๋ฌธ์ œ๋Š” ๋ช‡ ๋ฒˆ์„ ๋”ฐ๋ผ ์˜ฌ๋ผ๊ฐ€์•ผ๋งŒ ๊ฐ€์žฅ ์˜ค๋ž˜๋„๋‹ˆ ์ฃผ์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ธ์ง€ ์‚ฌ์ „์—๋Š” ์•Œ ์ˆ˜ ์—†๋‹ค๋Š” ์ ์ด๋‹ค.

์ด์‚ฌ๋ฅผ ํ•œ ๋ฒˆ ์ •๋„๋ฐ–์— ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋„ ์žˆ๊ฒ ์ง€๋งŒ, ์ด์‚ฌ๋ฅผ 100๋ฒˆ ๋„˜๊ฒŒ ํ•˜๋Š” ์ด์‚ฌ ๋งค๋‹ˆ์•„๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด์‚ฌ ํšŸ์ˆ˜์˜ ์ƒํ•œ์ด ์ •ํ•ด์ ธ ์žˆ๋‹ค๋ฉด ๊ทธ๋งŒํผ ์ž๊ธฐ ๊ฒฐํ•ฉ์„ ๋ฐ˜๋ณตํ•  ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, ์ƒํ•œ์ด ์ •ํ•ด์ง€์ง€ ์•Š์•˜๋‹ค๋ฉด ๊ทธ๋Ÿฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

์ด๋•Œ ์ ˆ์ฐจ ์ง€ํ–ฅํ˜• ์–ธ์–ด์—์„œ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ฌธ์ œ๋ฅผ ์‰ฝ๊ฒŒ ํ’€ ์ˆ˜ ์žˆ๋‹ค. ํŒŒ์ผ์„ name์œผ๋กœ ์ •๋ ฌํ•˜๊ณ , ํ˜„์žฌ ์ฃผ์†Œ์˜ ๋ ˆ์ฝ”๋“œ๋ถ€ํ„ฐ ์ถœ๋ฐœํ•ด์„œ ์ด์ „ ์ฃผ์†Œ๊ฐ€ ์—†์„ ๋•Œ ๊นŒ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ์ฃผ์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ์€ SQL์—์„œ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋Š” ์žฌ๊ท€ ๊ณตํ†ต ํ…Œ์ด๋ธ” ์‹(recursion common table expression)์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

WITH RECURSIVE Explosion (name, pcode, new_pcode, depth)
AS
(SELECT name, pcode, new_pcode, 1 FROM PostalHistory 
	WHERE name = 'A' AND new_pcode IS NULL /* ๊ฒ€์ƒ‰ ์‹œ์ž‘ */
UNION
SELECT Child.name, Child.pcode, Child.new_pcode, depth + 1
	FROM Explosion AS Parent, PostalHistory AS Child
		WHERE Parent.pcode = Child.new_pcode AND Parent.name = Child.name)
/* ๋ฉ”์ธ SELECT ๊ตฌ๋ฌธ */
SELECT name, pcode, new_pcode FROM Explosion
	WHERE depth = (SELECT MAX(depth) FROM Explosion);

https://yongineer.duckdns.org/sql/107.png

์žฌ๊ท€ ๊ณตํ†ต ํ…Œ์ด๋ธ” ์‹ Explosion์€, A์— ๋Œ€ํ•œ ํ˜„์žฌ ์ฃผ์†Œ(new_pcodeํ•„๋“œ๊ฐ€ NULL)๋ถ€ํ„ฐ ์ถœ๋ฐœํ•ด์„œ ํฌ์ธํ„ฐ ์ฒด์ธ์„ ํƒ€๊ณ  ์˜ฌ๋ผ๊ฐ€ ๊ณผ๊ฑฐ์˜ ์ฃผ์†Œ๋ฅผ ๋ชจ๋‘ ์ฐพ๋Š”๋‹ค. ์ด๋•Œ ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ์ฃผ์†Œ๋Š” ์žฌ๊ท€ ์ˆ˜์ค€์ด ๊ฐ€์žฅ ๊นŠ์€ ๋ ˆ์ฝ”๋“œ์ด๋ฏ€๋กœ, ์ด๋ฅผ depthํ•„๋“œ๋กœ ์ฐพ๋Š”๋‹ค. depthํ•„๋“œ๋Š” ํ•œ ๋ฒˆ ๋ฐ˜๋ณตํ•  ๋•Œ๋งˆ๋‹ค 1์”ฉ ์ฆ๊ฐ€ํ•˜๋ฏ€๋กœ, depthํ•„๋“œ๊ฐ€ ๊ฐ€์žฅ ํฐ ๊ฒƒ์ด ๊ฐ€์žฅ ์žฌ๊ท€ ์ˆ˜์ค€์ด ๊นŠ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๊ทธ๋Ÿผ ์‹คํ–‰ ๊ณ„ํš์€ ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

https://yongineer.duckdns.org/sql/108.png

id3์˜ Parentํ…Œ์ด๋ธ” ์˜์—ญ์˜ Extra๋ฅผ ๋ณด๋ฉด Recorsive; Using where์ด๋ผ๊ณ  ๋‚˜์™€์žˆ๋Š”๋ฐ ์ด๊ฒƒ์ด ์žฌ๊ท€ ์—ฐ์‚ฐ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด ์ฟผ๋ฆฌ๋Š” ๋ช‡ ๋ฒˆ์„ ์ด์‚ฌํ•ด๋„ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ๊ต‰์žฅํžˆ ์œ ์—ฐํ•˜๋‹ค. ๋˜ํ•œ ๋งˆ์ง€๋ง‰ ์‹คํ–‰ ๊ณ„ํš์„ ๋ณด๋ฉด Using temporary์ด๋ผ๋Š” ์„ค๋ช…์ด ๋ณด์ด๋Š”๋ฐ ์ดํ‹‘ Explosion๋ทฐ์— ์—ฌ๋Ÿฌ ๋ฒˆ ์ ‘๊ทผํ•˜๋ฏ€๋กœ ์ž„์‹œ ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“ค์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ์ž„์‹œ ํ…Œ์ด๋ธ”๊ณผ ์›๋ž˜ PostalHistoryํ…Œ์ด๋ธ”์€, ์ธ๋ฑ์Šค idx_new_pcode๋ฅผ ์‚ฌ์šฉํ•ด Nested Loops๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ๊ฝค ํšจ์œจ์ ์ธ ๊ณ„ํš์ธ๋‹ค.

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

์ค‘์ฒฉ ์ง‘ํ•ฉ ๋ชจ๋ธ

SQL์—์„œ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ 3๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  1. ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ชจ๋ธ
  2. ์ค‘์ฒฉ ์ง‘ํ•ฉ ๋ชจ๋ธ
  3. ๊ฒฝ๋กœ ์—ด๊ฑฐ ๋ชจ๋ธ

1๏ธโƒฃ ์€ ์•ž์—์„œ ์‚ดํŽด๋ณธ ๋ฐฉ๋ฒ•์œผ๋กœ, RDB๊ฐ€ ํƒ„์ƒํ•˜๊ธฐ ์ด์ „๋ถ€ํ„ฐ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉ๋˜์—ˆ๋‹ค. 3๏ธโƒฃ ์€ ๊ฐฑ์‹ ์ด ๊ฑฐ์˜ ๋ฐœ์ƒํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ํž˜์„ ๋ฐœํœ˜ํ•œ๋‹ค. ์ค‘์š”ํ•œ ๊ฒƒ์€ 2๏ธโƒฃ ์˜ ์ค‘์ฒฉ ์ง‘ํ•ฉ ๋ชจ๋ธ์ด๋‹ค. ์ด ๋ฐฉ๋ฒ•์˜ ํฌ์ธํŠธ๋Š” ๊ฐ ๋ ˆ์ฝ”๋“œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘ํ•ฉ(์›)์œผ๋กœ ๋ณด๊ณ , ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์ง‘ํ•ฉ์˜ ์ค‘์ฒฉ ๊ด€๊ณ„๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

https://yongineer.duckdns.org/sql/109.png

๋จผ์ € ์œ„์™€ ๊ฐ™์€ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค. ์ด ํ…Œ์ด๋ธ”์€ ์šฐํŽธ ๋ฒˆํ˜ธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์น˜์„  ์ƒ์— ์กด์žฌํ•˜๋Š” ์›์œผ๋กœ ์ƒ๊ฐํ•œ๋‹ค. lft์™€ rgt๋Š” ์›์˜ ์™ผ์ชฝ ๋๊ณผ ์˜ค๋ฅธ์ชฝ ๋์— ์œ„์น˜ํ•˜๋Š” ์ขŒํ‘œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ขŒํ‘œ๊ฐ’์€ ๋Œ€์†Œ ๊ด€๊ณ„๋งŒ ์ ์ ˆํ•˜๋‹ค๋ฉด ์ž„์˜์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด์‚ฌ ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์šฐํŽธ๋ฒˆํ˜ธ๊ฐ€ ์ด์ „์˜ ์šฐํŽธ๋ฒˆํ˜ธ โ€˜์•ˆ์—โ€™ ํฌํ•จ๋˜๋Š” ํ˜„ํƒœ๋กœ ์ถ”๊ฐ€๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด A์˜ ์šฐํŽธ๋ฒˆํ˜ธ 3๊ฐœ์˜ ํฌํ•จ ๊ด€๊ณ„๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜ํƒ€๋‚  ๊ฒƒ์ด๋‹ค.

https://yongineer.duckdns.org/sql/110.png

์ด๋•Œ ์ƒˆ๋กœ ์‚ฝ์ž…ํ•˜๋Š” ์šฐํŽธ๋ฒˆํ˜ธ์˜ ์ขŒํ‘œ๋Š” ์™ธ์ธก ์›์˜ ์™ผ์ชฝ ๋๊ณผ ์˜ค๋ฅธ์ชฝ ๋์˜ ์ขŒํ‘œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒฐ์ •๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์™ธ์ธก์˜ ์šฐํŽธ๋ฒˆํ˜ธ์˜ ์™ผ์ชฝ ๋ ์ขŒํ‘œ๋ฅผ plft, ์˜ค๋ฅธ์ชฝ ๋ ์ขŒํ‘œ๋ฅผ prgt๋ผ๊ณ  ํ•œ๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆ˜์‹์— ๋”ฐ๋ผ ์ž๋™์ ์œผ๋กœ ๋…ธ๋“œ์˜ ์ขŒํ‘œ๋ฅผ ์—ฐ์‚ฐํ•œ๋‹ค.

  • ์ถ”๊ฐ€๋˜๋Š” ๋…ธ๋“œ์˜ ์™ผ์ชฝ ๋ ์ขŒํ‘œ = (plftโˆ—2+prgt)/3(plft * 2 + prgt) / 3
  • ์ถ”๊ฐ€๋˜๋Š” ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ๋ ์ขŒํ‘œ = (plft+prgtโˆ—2)/3(plft + prgt * 2) / 3

๋”ฐ๋ผ์„œ plft์™€ prgt๋กœ 3๊ฐœ์˜ ๊ตฌ๊ฐ„์„ ๋ถ„ํ• ํ•  ์ˆ˜ ์žˆ๋Š” 2๊ฐœ์˜ ์ขŒํ‘œ๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด๋‹ค. lft์™€ rgt์˜ ์ž๋ฃŒํ˜•์€ ์‹ค์ˆ˜ํ˜•(REAL)์ธ๋ฐ DBMS์˜ ์ •๋ฐ€ ๋ฒˆ์œ„ ๋‚ด์—์„œ๋Š” ๋‚ฎ์€ ๋น„์šฉ์œผ๋กœ๋„ ์ค‘์ฒฉ์„ ์–ผ๋งˆ๋“ ์ง€ ํ•  ์ˆ˜ ์žˆ๋‹ค.

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

SELECT name, pcode FROM PostalHistory2 PH1
	WHERE name = 'A' 
		AND NOT EXISTS (
					SELECT * FROM PostalHistory2 PH2
						WHERE PH2.name = 'A' AND PH1.lft > PH2.lft);

https://yongineer.duckdns.org/sql/111.png

์ด์ œ ์‹คํ–‰ ๊ณ„ํš์„ ์‚ดํŽด๋ณด์ž.

https://yongineer.duckdns.org/sql/112.png

์™ธ์ธก ํ…Œ์ด๋ธ” (PH1)๊ณผ ๋‚ด์ธก ํ…Œ์ด๋ธ”(PH2)์„ ํ•œ ๋ฒˆ๋งŒ Nested Loops๋กœ ๊ฒฐํ•ฉํ•˜๋Š” ์‹คํ–‰ ๊ณ„ํš์ด๋‹ค. ์—ฌ๊ธฐ์„œ ์žฌ๊ท€ ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์— ์ฃผ๋ชฉํ•ด์•ผ ํ•œ๋‹ค. PostgreSQL์—์„œ๋Š” ํ…Œ์ด๋ธ”์˜ ํ’€ ์Šค์บ”์ด ์ˆ˜ํ–‰ ๋˜๋Š”๋ฐ ์ด๋Š” ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ ์ˆ˜๊ฐ€ ์ ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค ๋ฐ˜๋ฉด MySQL์—์„œ๋Š” ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ณ„ํš์„ ์„ธ์šฐ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ค‘์ฒฉ ์ง‘ํ•ฉ์˜ ์ฝ”๋“œ๊ฐ€ ์žฌ๊ท€๋ณด๋‹ค ๋น ๋ฅผ์ง€ ๋‹จ์ˆœํ•˜๊ฒŒ ํŒ๋‹จํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ, ์ผ๋ฐ˜์ ์ธ ์ฝ”๋”ฉ์—์„œ๋Š” ์—†๋Š” ๋ชจ๋ธ(์—”ํ‹ฐํ‹ฐ ๊ตฌ์กฐ)์˜ ๊ด€์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ผ๋‹จ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ๋œ๋‹ค.

์ •๋ฆฌ

  • ์šฐ๋ฆฌ๋Š” ๋ชจ๋‘ ๋ฐ˜๋ณต๋ฌธ ์˜์กด์ฆ์— ๊ฑธ๋ ค ์žˆ๋‹ค.
  • SQL์€ ์˜๋„์ ์œผ๋กœ ๋ฐ˜๋ณต๋ฌธ์„ ์„ค๊ณ„์—์„œ ์ œ์™ธํ–ˆ์Œ
  • ๋ฐ˜๋ณต๊ณ„๋Š” ์„ฑ๋Šฅ์ ์œผ๋กœ ํฐ ๊ฒฐ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ๋ช‡๊ฐ€์ง€ ์žฅ์ ๋„ ์žˆ์Œ
  • ํ•˜์ง€๋งŒ ๋ฐ˜๋ณต๊ณ„๋Š” ์„ฑ๋Šฅ ํŠœ๋‹ ๊ฐ€๋Šฅ์„ฑ์ด ๊ฑฐ์˜ ์—†์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์‹œ ์ฃผ์˜๊ฐ€ ํ•„์š”
  • ์—ฌ๊ธฐ์—์„œ๋„ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋ฅผ ๊ณ ๋ คํ•ด์„œ, ๋ฐ˜๋ณต๊ณ„์™€ ํฌ์žฅ๊ณ„ ์ค‘์— ์–ด๋–ค ๊ฒƒ์„ ์ฑ„์šฉํ• ์ง€ ํŒ๋‹จํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

Yongineer
Written by@Yongineer
Backend Developer

GitHubInstagram