์คํธ๋ฆฌ๋ฐ SQL ๊ธฐ๋ฐ ๋ง์ดํฌ๋ก์๋น์ค๊ฐ ์ค์๊ฐ ๋ฐ์ดํฐ ๋ถ์์ ๋ณต์กํ ์ฝ๋ฉ ์์ด SQL๋ก ์ค์๊ฐ ๋น์ฆ๋์ค ๋ก์ง์ ๊ตฌํํ๊ณ , ์๋์ ์ค์ ๊ตฌํ ๋ฐฉ์์ ํ์ธํ์
์ ์ฆ๊ฐ์ ์ธ ์ธ์ฌ์ดํธ๋ฅผ ๋ง๋ค์ด๋ณด์ธ์!
์ฃผ์ ๊ธฐ๋ฅ ํจ๊ณผ ๋ฐ ์ด์
์ค์๊ฐ ์ธ์ฌ์ดํธ:
- ๊ณ ๊ฐ ํ๋, ์์ฅ ๋ํฅ์ ์ค์๊ฐ์ผ๋ก ํ์ ํ์ฌ ์ฆ๊ฐ์ ์ธ ์์ฌ๊ฒฐ์ ์ ๋ด๋ฆด ์ ์์ต๋๋ค.
๊ฐ๋ฐ ํจ์จ์ฑ ๊ทน๋ํ:
- ๋ณต์กํ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ ๋์ , ์น์ํ SQL๋ก ์ค์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฝ๊ฒ ๊ฐ๋ฐํ ์ ์์ต๋๋ค.
๋น์ฆ๋์ค ๋ฏผ์ฒฉ์ฑ ํฅ์:
- ๋ณํํ๋ ์์ฅ ์ํฉ์ ๋น ๋ฅด๊ฒ ๋์ํ๊ณ , ์๋ก์ด ๋น์ฆ๋์ค ๋ชจ๋ธ์ ์ ์ฐํ๊ฒ ์ ์ฉํ ์ ์์ต๋๋ค.
๋น์ฉ ์ ๊ฐ:
- ๊ธฐ์กด์ ๋ณต์กํ ์์คํ ๊ตฌ์ถ ๋ฐ ์ ์ง๋ณด์ ๋น์ฉ์ ์ ๊ฐํ์ฌ ํจ์จ์ ์ธ ์์ ๋ฐฐ๋ถ์ด ๊ฐ๋ฅํฉ๋๋ค.
"์ฝ๋๋ฅผ ํ ๋ฒ ์์ฑํ๋ฉด ๋ชจ๋ ๊ณณ์์ ์คํ๋๋ค"๋ ์คํธ๋ฆฌ๋ฐ SQL์ ์ฒ ํ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ํจ๋ฌ๋ค์์ ๋ฐ๊พธ๊ณ ์์ต๋๋ค. ๋ ์ด์ ๋ฐ์ดํฐ ์์ง๋์ด๋ง์ ๋ณต์ก์ฑ์ ์ฝ๋งค์ด์ง ์๊ณ , ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง์ ์ง์คํ์ฌ ๋ ํฐ ๊ฐ์น๋ฅผ ์ฐฝ์ถํ ์ ์์ต๋๋ค.
์์ธ ์ ๋ณด ๋ฐ ์ค์ ๊ตฌํ ์์
-
๋ด์ฅ ํจ์, UDF, ๋ฌผ๋ฆฌํ๋ ๊ฒฐ๊ณผ, ๊ทธ๋ฆฌ๊ณ ML ๋ฐ AI ๋ชจ๋ธ๊ณผ์ ํตํฉ์ ์คํธ๋ฆฌ๋ฐ SQL์ ๋ง์ดํฌ๋ก์๋น์ค ๊ตฌ์ถ ์ ๋งค๋ ฅ์ ์ธ ์ ํ์ง๋ก ๋ง๋ญ๋๋ค.
-
์ ํต์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค(์: Postgres)์์์ SQL ์ฟผ๋ฆฌ๋ ๊ฒฝ๊ณ๊ฐ ์๋ ์ฟผ๋ฆฌ๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ด์ ์ ํํ ๋ฐ์ดํฐ ์งํฉ์ ๋์์ผ๋ก ๋์ํฉ๋๋ค.
์ด ๊ฒฝ๊ณ ๋ฐ์ดํฐ์๋ ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ์์ ์ ์กด์ฌํ๋ ๋ฐ์ดํฐ๋ง ํฌํจ๋ฉ๋๋ค. ์ฟผ๋ฆฌ ์คํ ์ดํ์ ๋ฐ์ํ ๋ฐ์ดํฐ ์งํฉ์ ๋ณ๊ฒฝ ์ฌํญ์ ์ต์ข
๊ฒฐ๊ณผ์ ํฌํจ๋์ง ์์ต๋๋ค. ๋์ , ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ค๋ฉด ๋ค์ ์ฟผ๋ฆฌ๋ฅผ ์คํํด์ผ ํฉ๋๋ค. 
-
๋ฐ๋ฉด, ์คํธ๋ฆฌ๋ฐ SQL ์ฟผ๋ฆฌ๋ ์ ํ๋์ง ์์ ๋ฐ์ดํฐ ์งํฉ, ๊ฐ์ฅ ์ผ๋ฐ์ ์ผ๋ก๋ ํ๋ ์ด์์ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ๋์์ผ๋ก ๋์ํฉ๋๋ค.

์ด ๋ชจ๋ธ์์ ์คํธ๋ฆฌ๋ฐ SQL ์์ง์ ์คํธ๋ฆผ์ผ๋ก๋ถํฐ ์ด๋ฒคํธ๋ฅผ ํ๋์ฉ ์๋นํ๋ฉฐ, ํ์์คํฌํ์ ์คํ์
์ ๋ฐ๋ผ ์ด๋ฅผ ์ ๋ ฌํฉ๋๋ค. 
-
๋ํ ์คํธ๋ฆฌ๋ฐ SQL ์ฟผ๋ฆฌ๋ ๋ฌด๊ธฐํ ์คํ๋๋ฉฐ, ์ ๋ ฅ์ผ๋ก ์ด๋ฒคํธ๊ฐ ๋์ฐฉํ๋ ์ฆ์ ์ด๋ฅผ ์ฒ๋ฆฌํ๊ณ , ์ํ ์ ์ฅ์๋ฅผ ๊ฐฑ์ ํ๋ฉฐ, ๊ฒฐ๊ณผ๋ฅผ ๊ณ์ฐํ๊ณ , ๋์๊ฐ ํ์ ์คํธ๋ฆผ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ถ๋ ฅํ๊ธฐ๋ ํฉ๋๋ค.


๋ชฉ๋ก์ ์ฒซ ๋ฒ์งธ๋ก, ์คํธ๋ฆฌ๋ฐ SQL์ SQL ์ฝ๋์์ ์ธ๊ณต์ง๋ฅ(AI) ๋ฐ ๋จธ์ ๋ฌ๋(ML) ๋ชจ๋ธ๊ณผ์ ์ง์ ์ ์ธ ํตํฉ์ ์ง์ํฉ๋๋ค. ์คํธ๋ฆฌ๋ฐ SQL์ ํตํด AI ๋๋ ML ๋ชจ๋ธ์ ์ ๊ทผํ๋ ๊ฒ์ ๊ทธ ์ด๋ ๋๋ณด๋ค ์ฌ์์ก์ต๋๋ค. ![]()
-
AI๊ฐ ๋ค์ํ ๋น์ฆ๋์ค ์ํฌ๋ก๋์ ์ ๋ ฅํ ๋์์ผ๋ก ๋ถ์ํจ์ ๋ฐ๋ผ, ์คํธ๋ฆฌ๋ฐ SQL์ ๋ณ๋์ ์ ์ฉ ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ๋์ฐ๊ณ , ์คํํ๊ณ , ๊ด๋ฆฌํ ํ์ ์์ด ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋ฐฉ์์ผ๋ก ๋ชจ๋ธ์ ํ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.


์ด ํจํด์ ์ฌ์ฉ์ ์ ์ ํจ์(UDF) ํจํด๊ณผ ์ ์ฌํ๊ฒ ๋์ํฉ๋๋ค. ์ฆ, ๋ชจ๋ธ์ ์์ฑํ๊ณ , ์ฌ์ฉํ๋๋ก ๋ฑ๋กํ ๋ค, SQL ์ฟผ๋ฆฌ ์์์ ์ธ๋ผ์ธ์ผ๋ก ํธ์ถํ๋ฉด ๋ฉ๋๋ค. 

-
Flink ๋ฌธ์์์๋ ๋ชจ๋ธ์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ ์์ธํ ์ค๋ช ํ๊ณ ์์ต๋๋ค:

CREATE MODEL sentiment_analysis_model
INPUT (text STRING COMMENT 'Input text for sentiment analysis')
OUTPUT (sentiment STRING COMMENT 'Predicted sentiment (positive/negative/neutral/mixed)')
COMMENT 'A model for sentiment analysis of text'
WITH (
'provider' = 'openai',
'endpoint' = 'https://api.openai.com/v1/chat/completions',
'api-key' = '<YOUR KEY>',
'model'='gpt-3.5-turbo',
'system-prompt' = 'Classify the text below into one of the following labels: [positive, negative, neutral, mixed]. Output only the label.'
);
-
-
๋ชจ๋ธ ์ ์ธ์ ์คํธ๋ฆฌ๋ฐ SQL ์ฝ๋์์ ํด๋น ๋ชจ๋ธ์ ์ฌ์ฉํ ์ ์๋๋ก ํด์ฃผ๋ ์ผ๋ จ์ ์ฐ๊ฒฐ ์ค์ ๊ณผ ๊ตฌ์ฑ์ด๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.

์๋ฅผ ๋ค์ด, ์ด ๋ชจ๋ธ ์ ์ธ์ ์ฌ์ฉํ๋ฉด ์ด๋ฒคํธ์ ํฌํจ๋ ํ
์คํธ ๋ณธ๋ฌธ์ ๋ํด ๊ฐ์ฑ ๋ถ์์ ์ํํ ์ ์์ต๋๋ค. 

-
์ฌ๊ธฐ์
ML_PREDICT๋ ์ฌ์ฉ๋๋ ๊ตฌ์ฒด์ ์ธ ๋ชจ๋ธ ์ด๋ฆ๊ณผ ํ ์คํธ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ชจ๋ ํ์๋ก ํ๋ค๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค.
_
-
INSERT INTO my_sentiment_results
SELECT text, sentiment
FROM input_event_stream, LATERAL TABLE(ML_PREDICT('sentiment_analysis_model', text));
-
ํจํด 2: ํจ์๋ก ๊ตฌํํ๋ ๋ง์ถคํ ๋น์ฆ๋์ค ๋ก์ง


-
์คํธ๋ฆฌ๋ฐ SQL์ ๋ค์ํ ํจ์๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ์ง๋ง, ๋ชจ๋ ๊ธฐ๋ฅ์ ์ธ์ด ๋ฌธ๋ฒ์ ํฌํจ์ํค๋ ๊ฒ์ ํ์ค์ ์ผ๋ก ๋ถ๊ฐ๋ฅํฉ๋๋ค. ์ด ์ง์ ์์ **์ฌ์ฉ์ ์ ์ ํจ์(UDF)**๊ฐ ๋ฑ์ฅํฉ๋๋ค. UDF๋ ์ฌ์ฉ์๊ฐ ์ง์ ์ ์ํ ํจ์๋ก, SQL ๋ฌธ ์์์ ํ๋ก๊ทธ๋จ์ด ์ด๋ฅผ ์คํํ ์ ์์ต๋๋ค.

-
UDF๋ ํต์ฌ SQL ๋ฌธ๋ฒ์์ ์ง์ํ์ง ์๋ ์ธ๋ถ ์์คํ ํธ์ถ์ด๋ ์ฌ์ด๋ ์ดํํธ ์์ฑ๋ ์ํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ํด, ๋ ๋ฆฝ์ ์ธ ํ์ผ์ ํจ์ ์ฝ๋๋ฅผ ๊ตฌํํ ๋ค, SQL ๋ฌธ์ ์คํํ๊ธฐ ์ ์ ํด๋น ํจ์๋ฅผ ์คํธ๋ฆฌ๋ฐ SQL ์๋น์ค์ ์ ๋ก๋ํฉ๋๋ค.


-
์ด์ Flink ์์ ๋ฅผ ํ๋ ์ดํด๋ณด๊ฒ ์ต๋๋ค.

-
// Declare the UDF in a separate java file
import org.apache.flink.table.api.*;
import org.apache.flink.table.functions.ScalarFunction;
import static org.apache.flink.table.api.Expressions.*;
//Returns 2 for high risk, 1 for normal risk, 0 for low risk.
public static class DefaultRiskUDF extends ScalarFunction {
public Integer eval(Integer debt,
Integer interest_basis_points,
Integer annual_repayment,
Integer timespan_in_years) throws Exception {
int computed_debt = debt;
for (int i = 0; i < timespan_in_years; i++) {
computed_debt = computed_debt +
(computed_debt *
interest_basis_points / 10000)
- annual_repayment;
}
if ( computed_debt >= debt )
return 2;
else if ( computed_debt < debt && computed_debt > debt / 2)
return 1;
else
return 0;
}
-
- ๋ค์์ผ๋ก, Java ํ์ผ์ JAR ํ์ผ๋ก ์ปดํ์ผํ ๋ค ์คํธ๋ฆฌ๋ฐ SQL ํ๋ ์์ํฌ๊ฐ ์ ๊ทผํ ์ ์๋ ์์น์ ์
๋ก๋ํด์ผ ํฉ๋๋ค.

JAR๊ฐ ๋ก๋๋๋ฉด ํ๋ ์์ํฌ์ ์ด๋ฅผ ๋ฑ๋กํด์ผ ํ๋ฉฐ, ์ดํ ์คํธ๋ฆฌ๋ฐ SQL ๋ฌธ์์ ํด๋น ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. 

- ์๋๋ ๋ฑ๋ก๊ณผ ํธ์ถ ๋ฌธ๋ฒ์ ๋ํ ์์ฃผ ๊ฐ๋จํ ์์์
๋๋ค.

- ๋ค์์ผ๋ก, Java ํ์ผ์ JAR ํ์ผ๋ก ์ปดํ์ผํ ๋ค ์คํธ๋ฆฌ๋ฐ SQL ํ๋ ์์ํฌ๊ฐ ์ ๊ทผํ ์ ์๋ ์์น์ ์
๋ก๋ํด์ผ ํฉ๋๋ค.
-- Register the function.
CREATE FUNCTION DefaultRiskUDF
AS 'com.namespace.SubstringUDF'
USING JAR '<path-to-jar>';
-- Invoke the function to compute the risk of:
-- 100k debt over 15 years, 4% interest rate (400 basis points), and a 10k annual repayment rate
SELECT UserId, DefaultRiskUDF(100000, 400, 10000, 15) AS RiskRating
FROM UserFinances
WHERE RiskRating >= 1;
-
-
์ด UDF๋ฅผ ์ฌ์ฉํ๋ฉด ๋์ถ์๊ฐ ๋์ถ์ **์ฐ์ฒด(๋ํดํธ)**ํ ์ํ์ ๊ณ์ฐํ ์ ์์ผ๋ฉฐ, ๋ฎ์ ์ํ๊ณผ ๋ณดํต ์ํ์ ๋ํด์๋ ๊ฐ๊ฐ 0๊ณผ 1์ ๋ฐํํ๊ณ , ๊ณ ์ํ ์ฐจ์ ์ ๋๋ ์ํ ์ํ์ ๊ณ์ ์ ๋ํด์๋ 2 ๊ฐ์ ๋ฐํํฉ๋๋ค.


-
์ด UDF๋ ๋น๊ต์ ๋จ์ํ๊ณ ๋ค์ ์ธ์์ ์ธ ์์์ด์ง๋ง, ํ์ค Java ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ด์ ๊ฑฐ์ ๋ชจ๋ ๊ธฐ๋ฅ์ ํ์ฉํด ํจ์ฌ ๋ ๋ณต์กํ ์ฐ์ฐ์ ์ํํ ์ ์์ต๋๋ค.

์คํธ๋ฆฌ๋ฐ SQL ์๋ฃจ์
์ ์๋ ๊ธฐ๋ฅ์ ์ป๊ธฐ ์ํด ๊ตณ์ด ์ ์ฒด ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ๊ตฌ์ถํ ํ์๋ ์์ต๋๋ค. ๋์ , ๋ถ์กฑํ ๊ธฐ๋ฅ์ ๊ตฌํํด ์
๋ก๋ํ ๋ค์, ์ฝ๋์์ ์ธ๋ผ์ธ์ผ๋ก ์ง์ ํธ์ถํ๋ฉด ๋ฉ๋๋ค. 


-
-
ํจํด 3: ๊ธฐ๋ณธ ํํฐ, ์ง๊ณ, ์กฐ์ธ


- ์ด ํจํด์ ์คํธ๋ฆฌ๋ฐ SQL ํ๋ ์์ํฌ์ ๊ธฐ๋ณธ์ผ๋ก ๋ด์ฅ๋(ํ์ง๋ง ๊ฐ๋ ฅํ) ๊ธฐ๋ฅ๋ค๋ก ๋ค์ ์ด์ ์ ์ฎ๊น๋๋ค. ์คํธ๋ฆฌ๋ฐ SQL์ ๋ํ์ ์ธ ํ์ฉ ์ฌ๋ก ์ค ํ๋๋ ๋จ์ ํํฐ๋ง์ผ๋ก, ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ ์ฝ๋๋ง ์ ์งํ๊ณ ๋๋จธ์ง๋ ๋ฒ๋ฆฌ๋ ๋ฐฉ์์
๋๋ค.

- ์๋ ์์๋
total_price > 10.00์ธ ๋ ์ฝ๋๋ง ๋ฐํํ๋ SQL ํํฐ๋ฅผ ๋ณด์ฌ์ฃผ๋ฉฐ, ์ด ๊ฒฐ๊ณผ๋ฅผ ๊ฒฐ๊ณผ ํ ์ด๋ธ๋ก ์ถ๋ ฅํ๊ฑฐ๋ ์ด๋ฒคํธ ์ํ์ค ํํ์ ์คํธ๋ฆผ์ผ๋ก ๋ด๋ณด๋ผ ์ ์์ต๋๋ค.

- ์ด ํจํด์ ์คํธ๋ฆฌ๋ฐ SQL ํ๋ ์์ํฌ์ ๊ธฐ๋ณธ์ผ๋ก ๋ด์ฅ๋(ํ์ง๋ง ๊ฐ๋ ฅํ) ๊ธฐ๋ฅ๋ค๋ก ๋ค์ ์ด์ ์ ์ฎ๊น๋๋ค. ์คํธ๋ฆฌ๋ฐ SQL์ ๋ํ์ ์ธ ํ์ฉ ์ฌ๋ก ์ค ํ๋๋ ๋จ์ ํํฐ๋ง์ผ๋ก, ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ ์ฝ๋๋ง ์ ์งํ๊ณ ๋๋จธ์ง๋ ๋ฒ๋ฆฌ๋ ๋ฐฉ์์
๋๋ค.
SELECT *
FROM orders
WHERE total_price > 10.00;
-
- ์๋์๊ณผ ์ง๊ณ๋ ์คํธ๋ฆฌ๋ฐ SQL์์ ๋ ํ๋์ ๊ฐ๋ ฅํ ๊ตฌ์ฑ ์์์
๋๋ค.

์ด ๋ณด์ ์์ ์์๋ 1๋ถ ํ
๋ธ๋ง ์๋์ฐ ๋ด์์ ํน์ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์๋๋ฅผ ๋ช ๋ฒ ํ๋์ง๋ฅผ ์ง๊ณํฉ๋๋ค(์ฌ๋ผ์ด๋ฉ, ์ธ์
๋ฑ ๋ค๋ฅธ ์๋์ฐ ํ์
๋ ์ฌ์ฉํ ์ ์์ต๋๋ค). 
- ์๋์๊ณผ ์ง๊ณ๋ ์คํธ๋ฆฌ๋ฐ SQL์์ ๋ ํ๋์ ๊ฐ๋ ฅํ ๊ตฌ์ฑ ์์์
๋๋ค.
SELECT
COUNT(user_id) AS login_count,
TUMBLE_START(event_time, INTERVAL '1' MINUTE) AS window_start
FROM login_attempts
GROUP BY TUMBLE(event_time, INTERVAL '1' MINUTE);
-
- ์๋์ฐ ๋ด ๋ก๊ทธ์ธ ์๋ ํ์๋ฅผ ๊ตฌํ ๋ค, ๊ทธ ๊ฐ์ด ์ผ์ ๊ธฐ์ค(์: > 10)์ ์ด๊ณผํ๋ ๊ฒฝ์ฐ๋ฅผ ํํฐ๋งํ์ฌ, ํดํน ๋ฐฉ์ง ๊ธฐ๋ฅ์ผ๋ก UDF ๋ด๋ถ์ ๋น์ฆ๋์ค ๋ก์ง์ ํธ๋ฆฌ๊ฑฐํด ์ผ์์ ์ผ๋ก ๊ณ์ ์ ์ ๊ทธ๋๋ก ํ ์ ์์ต๋๋ค.


- ๋ง์ง๋ง์ผ๋ก, ๋ช ๊ฐ์ง ๊ฐ๋จํ ๋ช
๋ น๋ง์ผ๋ก๋ ์ฌ๋ฌ ์คํธ๋ฆผ์ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ธํ ์ ์์ต๋๋ค. ์คํธ๋ฆผ์ ์คํธ๋ฆผ(๋๋ ํ
์ด๋ธ)์ผ๋ก ์กฐ์ธํ๋ ์์
์ ์คํธ๋ฆฌ๋ฐ ํ๋ ์์ํฌ ์์ด๋, ํนํ ์ฅ์ ํ์ฉ์ฑ, ํ์ฅ์ฑ, ์ฑ๋ฅ์ ๊ณ ๋ คํ ๋ ์๋นํ ๊ตฌํํ๊ธฐ ์ด๋ ต์ต๋๋ค.

์ด ์์ ์์๋ ์ ํ ID๋ฅผ ๊ธฐ์ค์ผ๋ก Orders ๋ฐ์ดํฐ์ Product ๋ฐ์ดํฐ๋ฅผ ์กฐ์ธํ์ฌ, ํ์ฅ๋ Order + Product ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
- ์๋์ฐ ๋ด ๋ก๊ทธ์ธ ์๋ ํ์๋ฅผ ๊ตฌํ ๋ค, ๊ทธ ๊ฐ์ด ์ผ์ ๊ธฐ์ค(์: > 10)์ ์ด๊ณผํ๋ ๊ฒฝ์ฐ๋ฅผ ํํฐ๋งํ์ฌ, ํดํน ๋ฐฉ์ง ๊ธฐ๋ฅ์ผ๋ก UDF ๋ด๋ถ์ ๋น์ฆ๋์ค ๋ก์ง์ ํธ๋ฆฌ๊ฑฐํด ์ผ์์ ์ผ๋ก ๊ณ์ ์ ์ ๊ทธ๋๋ก ํ ์ ์์ต๋๋ค.
SELECT * FROM Orders
INNER JOIN Product
ON Orders.productId = Product.id
-
- ๋ชจ๋ ์คํธ๋ฆฌ๋ฐ ํ๋ ์์ํฌ(SQL ์ฌ๋ถ์ ๊ด๊ณ์์ด)๊ฐ ๊ธฐ๋ณธ ํคโ์ธ๋ ํค ์กฐ์ธ์ ์ง์ํ๋ ๊ฒ์ ์๋๋ผ๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค. ์ผ๋ถ๋ ๊ธฐ๋ณธ ํคโ๊ธฐ๋ณธ ํค ์กฐ์ธ๋ง ํ์ฉํฉ๋๋ค.
์ด์ ๋ฅผ ๊ฐ๋จํ ๋งํ๋ฉด, ์ฅ์ ํ์ฉ์ฑ, ํ์ฅ์ฑ, ์ฑ๋ฅ์ ํจ๊ป ๊ณ ๋ คํ ๋ ์ด๋ฌํ ์กฐ์ธ ์ ํ์ ๊ตฌํํ๋ ๊ฒ์ด ์๋นํ ์ด๋ ต๊ธฐ ๋๋ฌธ์
๋๋ค. ์ค์ ๋ก ์ฌ์ฉ ์ค์ธ ์คํธ๋ฆฌ๋ฐ SQL ํ๋ ์์ํฌ๊ฐ ์กฐ์ธ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง, ์ธ๋ ํค์ ๊ธฐ๋ณธ ํค ์กฐ์ธ์ ๋ชจ๋ ์ง์ํ๋์ง, ์๋๋ฉด ํ์๋ง ์ง์ํ๋์ง๋ฅผ ๋ฐ๋์ ๊ฒํ ํด์ผ ํฉ๋๋ค. 
- ์ง๊ธ๊น์ง ์คํธ๋ฆฌ๋ฐ SQL์ ๋ช ๊ฐ์ง ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ์ดํด๋ณด์์ง๋ง, ์์ง ์ด ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ค์ด ๋ ๋ณต์กํ ๋ฌด์ธ๊ฐ๋ฅผ ๊ตฌ๋ํ๊ณ ์์ง๋ ์์ต๋๋ค. ํ์ฌ ์ํ๋ก๋, ์ด ๊ฒฐ๊ณผ๋ค์ ํ์ ์๋น์ค๊ฐ ์๋นํ๋๋ก ๋ ๋ค๋ฅธ ์ด๋ฒคํธ ์คํธ๋ฆผ์ผ๋ก ์ถ๋ ฅํ๋ ์์ค์ ๋จธ๋ฌด๋ฅด๊ฒ ๋ฉ๋๋ค.

์ด๋ ๋ค์ ํจํด์ธ **์ฌ์ด๋์นด(sidecar)**๋ก ์ด์ด์ง๋๋ค. 
- ๋ชจ๋ ์คํธ๋ฆฌ๋ฐ ํ๋ ์์ํฌ(SQL ์ฌ๋ถ์ ๊ด๊ณ์์ด)๊ฐ ๊ธฐ๋ณธ ํคโ์ธ๋ ํค ์กฐ์ธ์ ์ง์ํ๋ ๊ฒ์ ์๋๋ผ๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค. ์ผ๋ถ๋ ๊ธฐ๋ณธ ํคโ๊ธฐ๋ณธ ํค ์กฐ์ธ๋ง ํ์ฉํฉ๋๋ค.
-
ํจํด 4: ์คํธ๋ฆฌ๋ฐ SQL ์ฌ์ด๋์นด


- ์คํธ๋ฆฌ๋ฐ SQL ์ฌ์ด๋์นด ํจํด์ Flink๋ Kafka Streams์ ๊ฐ์ ์์ ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ ์คํธ๋ฆผ ์ฒ๋ฆฌ ์์ง์ ๊ธฐ๋ฅ์, ๋น์ฆ๋์ค ๋ก์ง์ ๋์ผํ ์ธ์ด๋ก ์์ฑํ์ง ์๊ณ ๋ ํ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค.


- ์คํธ๋ฆฌ๋ฐ SQL ์ปดํฌ๋ํธ๋ ์ง๊ณ, ์กฐ์ธ๊ณผ ๊ฐ์ ํ๋ถํ ์คํธ๋ฆผ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ , ํ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์์ ๋ง์ ๋
๋ฆฝ์ ์ธ ๋ฐํ์์์ ๊ฒฐ๊ณผ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํฉ๋๋ค.


- ์คํธ๋ฆฌ๋ฐ SQL ์ฌ์ด๋์นด ํจํด์ Flink๋ Kafka Streams์ ๊ฐ์ ์์ ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ ์คํธ๋ฆผ ์ฒ๋ฆฌ ์์ง์ ๊ธฐ๋ฅ์, ๋น์ฆ๋์ค ๋ก์ง์ ๋์ผํ ์ธ์ด๋ก ์์ฑํ์ง ์๊ณ ๋ ํ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค.
-
- ์ด ์์ ์์
INTERNAL_STREAM์ SQL ์ฌ์ด๋์นด๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋กํ๋ Kafka ํ ํฝ์ ๋๋ค.
์ฌ์ด๋์นด ๊ธฐ๋ฐ ์ด๋ฒคํธ ๋๋ฆฌ๋ธ ์๋น์ค๋ INTERNAL_STREAM์ผ๋ก๋ถํฐ ์ด๋ฒคํธ๋ฅผ ์๋นํ์ฌ ์ ์ ํ ์ฒ๋ฆฌํ๊ณ , ๊ฒฝ์ฐ์ ๋ฐ๋ผOUTPUT_STREAM์ผ๋ก ์ด๋ฒคํธ๋ฅผ ๋ค์ ๋ฐํํ ์๋ ์์ต๋๋ค.

- ์ฌ์ด๋์นด์ ๋ ๋ค๋ฅธ ์ผ๋ฐ์ ์ธ ํ์ฉ ๋ฐฉ์์ ์น ์๋น์ค์์ ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์
์ ์ ๊ณตํ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ๋ ๊ฒ์
๋๋ค. ์ด ๊ฒฝ์ฐ ์ปจ์๋จธ๋
INPUT_STREAM์ ์๋นํด ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋ค, ์น ์๋น์ค๊ฐ ์์ฒด ์ํ ์ ์ฅ์๋ก ๋ฌผ๋ฆฌํํ ์ ์๋๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
๊ทธ ์ดํ์๋ REST๋ RPC ์์ฒญ๊ณผ ๊ฐ์ ์์ฒญ/์๋ต ๋ฐฉ์์ ์ง์๋ฅผ ๋ค๋ฅธ ์๋น์ค์ ์ ๊ณตํ ์ ์์ต๋๋ค. 

- ์ด ์์ ์์
-
- ์ฌ์ด๋์นด ํจํด์ ๋ค์ํ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง, SQL ์ฟผ๋ฆฌ์ ํจ๊ป ์ฌ์ด๋์นด ์๋น์ค๋ฅผ ์ง์ ๊ตฌ์ถยท๊ด๋ฆฌยท๋ฐฐํฌํด์ผ ํ๋ค๋ ์๊ตฌ์ฌํญ์ด ๋ฐ๋ฆ
๋๋ค.


- ์ด ํจํด์ ํต์ฌ์ ์ธ ์ฅ์ ์, ์ ์ฒด ๊ธฐ์ ์คํ์ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์คํธ๋ฆฌ๋ฐ ๋ณํ๊ณผ ๋ก์ง ์ฒ๋ฆฌ๋ฅผ ์คํธ๋ฆฌ๋ฐ SQL ๊ธฐ๋ฅ์ ๋งก๊ธธ ์ ์๋ค๋ ์ ์
๋๋ค. ๋์ , ์คํธ๋ฆฌ๋ฐ SQL์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์กด ๊ธฐ์ ์คํ์ ๊ทธ๋๋ก ์ฐ๊ฒฐํ์ฌ, ์ง๊ธ๊น์ง ์ฌ์ฉํด์จ ๋์ผํ ๋๊ตฌ๋ค๋ก ์น ์๋น์ค๋ ๊ธฐํ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.


- ์ฌ์ด๋์นด ํจํด์ ๋ค์ํ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง, SQL ์ฟผ๋ฆฌ์ ํจ๊ป ์ฌ์ด๋์นด ์๋น์ค๋ฅผ ์ง์ ๊ตฌ์ถยท๊ด๋ฆฌยท๋ฐฐํฌํด์ผ ํ๋ค๋ ์๊ตฌ์ฌํญ์ด ๋ฐ๋ฆ
๋๋ค.
-
์ถ๊ฐ ํ์ฉ ์ฌ๋ก


- ๊ฐ ํจํด์ ๊ฐ๋ณ์ ์ธ ์ฐ์ฐ์ ๋
๋ฆฝ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๋ฉฐ, ์ด๋ ๋น๊ต์ ๋จ์ํ ์ ํ๋ฆฌ์ผ์ด์
์๋ ์ถฉ๋ถํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ ๋ณต์กํ ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ ๊ฒฝ์ฐ, ์ฌ๋ฌ ํจํด์ ์ฐ์์ ์ผ๋ก ์ฐ๊ฒฐํ์ฌ ์ ๋จ๊ณ์ ๊ฒฐ๊ณผ๊ฐ ๋ค์ ๋จ๊ณ๋ก ์ ๋ฌ๋๋ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๊ฒ ๋ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค.

- ์๋ฅผ ๋ค์ด, ๋จผ์ ๋ฐ์ดํฐ๋ฅผ ํํฐ๋งํ ๋ค UDF๋ฅผ ์ ์ฉํ๊ณ , ์ดํ
ML_PREDICT๋ฅผ ์ฌ์ฉํด ML ๋๋ AI ๋ชจ๋ธ์ ํธ์ถํ ์ ์์ต๋๋ค. ์ด๋ ์๋ ์์์ ์ ๋ฐ๋ถ์ ๋ํ๋ ์์ต๋๋ค.
์ด์ด์ ์คํธ๋ฆฌ๋ฐ SQL์ ์ฒซ ๋ฒ์งธ ML_PREDICT์ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ํํฐ๋งํ๊ณ , UDF๋ฅผ ์ ์ฉํ ๋ค์, ์ต์ข ์ ์ผ๋ก ๋ ๋ค๋ฅธ ML ๋ชจ๋ธ๋ก ์ ๋ฌํ ๋คOUTPUT_STREAM์ ๊ธฐ๋กํฉ๋๋ค.
_
- ๊ฐ ํจํด์ ๊ฐ๋ณ์ ์ธ ์ฐ์ฐ์ ๋
๋ฆฝ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๋ฉฐ, ์ด๋ ๋น๊ต์ ๋จ์ํ ์ ํ๋ฆฌ์ผ์ด์
์๋ ์ถฉ๋ถํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ ๋ณต์กํ ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ ๊ฒฝ์ฐ, ์ฌ๋ฌ ํจํด์ ์ฐ์์ ์ผ๋ก ์ฐ๊ฒฐํ์ฌ ์ ๋จ๊ณ์ ๊ฒฐ๊ณผ๊ฐ ๋ค์ ๋จ๊ณ๋ก ์ ๋ฌ๋๋ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๊ฒ ๋ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค.
-
- ์คํธ๋ฆฌ๋ฐ SQL์ ๋ค์์ ํด๋ผ์ฐ๋ ๋ฒค๋์์ ์๋ฒ๋ฆฌ์ค ๊ธฐ๋ฅ์ผ๋ก ์ ๊ณต๋๋ฉฐ, ์คํธ๋ฆฌ๋ฐ ๋ฐ์ดํฐ ์๋น์ค๋ฅผ ๋น ๋ฅด๊ณ ์ฝ๊ฒ ๊ตฌ์ถํ ์ ์๋ ๋ฐฉ์์ผ๋ก ๊ณผ๊ธ๋ฉ๋๋ค.


- ๋ด์ฅ ํจ์, UDF, ๋ฌผ๋ฆฌํ๋ ๊ฒฐ๊ณผ, ๊ทธ๋ฆฌ๊ณ ML ๋ฐ AI ๋ชจ๋ธ๊ณผ์ ํตํฉ์ ํตํด, ์คํธ๋ฆฌ๋ฐ SQL์ ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ๊ตฌ์ถํ ๋ ์ถฉ๋ถํ ๊ณ ๋ คํ ๋งํ ๋์์์ด ์
์ฆ๋์์ต๋๋ค.


- ์คํธ๋ฆฌ๋ฐ SQL์ ๋ค์์ ํด๋ผ์ฐ๋ ๋ฒค๋์์ ์๋ฒ๋ฆฌ์ค ๊ธฐ๋ฅ์ผ๋ก ์ ๊ณต๋๋ฉฐ, ์คํธ๋ฆฌ๋ฐ ๋ฐ์ดํฐ ์๋น์ค๋ฅผ ๋น ๋ฅด๊ณ ์ฝ๊ฒ ๊ตฌ์ถํ ์ ์๋ ๋ฐฉ์์ผ๋ก ๊ณผ๊ธ๋ฉ๋๋ค.
[์ถ์ฒ] Why your next microservices should be streaming SQL-driven | InfoWorld
| This is a space where knowledge is not merely consumed, but respected, sovereign, and connectedโshared together with cloud industry professionals (Bros).|
| ์ง์์ด ์๋น๋์ง ์๊ณ ์กด์คยท์ฃผ๊ถ๋ณด์ฅยท์ฐ๊ฒฐ๋๋ ๊ณต๊ฐ์ผ๋ก ํด๋ผ์ฐ๋ ํ์ ์ ๋ฌธ๊ฐ(Bro)์ ํจ๊ป ๊ณต์ ํ๊ณ ์์ต๋๋ค. |




