TL; DR: JSONB๋ ์ฟผ๋ฆฌ ์ฑ๋ฅ์ ์ ํ์ํค์ง ์๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง ๊ฐ๋ฐ์ ํฌ๊ฒ ๋จ์ํํ ์ ์์ต๋๋ค.
์๊ฐ
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(๋ฐ์ดํฐ๋ฒ ์ด์ค) ์ธ๊ณ์์ ์๋ง๋ ๊ฐ์ฅ ์ค๋๋ ์ฌ์ฉ ์ฌ๋ก ์ค ํ๋์ ๋ํ ์ ํ์ ์ธ ์๋ฅผ ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. ์ํฐํฐ๊ฐ ์๊ณ ์ด ์ํฐํฐ์ ํน์ ์์ฑ(์์ฑ)์ ์ ์ฅํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ๋์ผํ ์์ฑ ์งํฉ์ ๊ฐ์ง ์๋ ์์ผ๋ฉฐ ์์ผ๋ก ๋ ๋ง์ ์์ฑ์ด ์ถ๊ฐ๋ ์ ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๊ฐ ์์ฑ ๊ฐ์ ๋ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ ์ด์ ๋ง๋ค๊ณ ํน์ ์ํฐํฐ ์ธ์คํด์ค์ ํ์ํ ํญ๋ชฉ์ ๊ฐ๋จํ ์ฑ์ฐ๋ ๊ฒ์ ๋๋ค. ์์ฒญ๋! ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค... ํ ์ด๋ธ์ ์๋ฐฑ๋ง ๊ฐ์ ๋ ์ฝ๋๊ฐ ํฌํจ๋์ด ์ ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํด์ผ ํ ๋๊น์ง์ ๋๋ค.
EAV ํจํด์ ๊ณ ๋ คํ์ญ์์ค(
๊ทธ๋ฌ๋ EVA ์ ๊ทผ ๋ฐฉ์์ ๋ช ๊ฐ์ง ๋จ์ ์ด ์์๋ค๋ฉด ์ ๋ ์ด ๊ฒ์๋ฌผ์ ์์ฑํ์ง ์์์ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด ๊ฐ๊ฐ 1๊ฐ์ ์์ฑ์ ๊ฐ์ง ํ๋ ์ด์์ ์ํฐํฐ๋ฅผ ์ป์ผ๋ ค๋ฉด ์ฟผ๋ฆฌ์ 2๊ฐ์ ์กฐ์ธ์ด ํ์ํฉ๋๋ค. ์ฒซ ๋ฒ์งธ๋ ์์ฑ ํ
์ด๋ธ๊ณผ์ ์กฐ์ธ์ด๊ณ ๋ ๋ฒ์งธ๋ ๊ฐ ํ
์ด๋ธ๊ณผ์ ์กฐ์ธ์
๋๋ค. ์ํฐํฐ์ 2๊ฐ์ ์์ฑ์ด ์๋ ๊ฒฝ์ฐ 4๊ฐ์ ์กฐ์ธ์ด ํ์ํฉ๋๋ค! ๋ํ ๋ชจ๋ ์์ฑ์ ์ผ๋ฐ์ ์ผ๋ก ๋ฌธ์์ด๋ก ์ ์ฅ๋๋ฏ๋ก ๊ฒฐ๊ณผ์ WHERE ์ ๋ชจ๋์ ๋ํด ์ ํ ์บ์คํ
์ด ์ํ๋ฉ๋๋ค. ์ฟผ๋ฆฌ๋ฅผ ๋ง์ด ์์ฑํ๋ฉด ๋ฆฌ์์ค ์ฌ์ฉ ์ธก๋ฉด์์ ์๋นํ ๋ญ๋น๊ฐ ๋ฉ๋๋ค.
์ด๋ฌํ ๋ช
๋ฐฑํ ๋จ์ ์๋ ๋ถ๊ตฌํ๊ณ EAV๋ ์ด๋ฌํ ์ ํ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ์ค๋ซ๋์ ์ฌ์ฉ๋์ด ์์ต๋๋ค. ์ด๋ ํผํ ์ ์๋ ๋จ์ ์ด์๊ณ ๋ ๋์ ๋์์ ์์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ PostgreSQL์ ์๋ก์ด "๊ธฐ์ "์ด ๋ฑ์ฅํ์ต๋๋ค.
PostgreSQL 9.4๋ถํฐ JSON ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด JSONB ๋ฐ์ดํฐ ์ ํ์ด ์ถ๊ฐ๋์์ต๋๋ค. JSON์ ์ด ํ์์ผ๋ก ์ ์ฅํ๋ฉด ์ผ๋ฐ์ ์ผ๋ก ์ผ๋ฐ ํ ์คํธ JSON๋ณด๋ค ์ฝ๊ฐ ๋ ๋ง์ ๊ณต๊ฐ๊ณผ ์๊ฐ์ด ์์๋์ง๋ง ์์ ์ํ ์๋๋ ํจ์ฌ ๋น ๋ฆ ๋๋ค. JSONB๋ ์ธ๋ฑ์ฑ๋ ์ง์ํ๋ฏ๋ก ์ฟผ๋ฆฌ ์๋๊ฐ ๋์ฑ ๋นจ๋ผ์ง๋๋ค.
JSONB ๋ฐ์ดํฐ ์ ํ์ ์ฌ์ฉํ๋ฉด ์ํฐํฐ ํ ์ด๋ธ์ JSONB ์ด ํ๋๋ง ์ถ๊ฐํ์ฌ ๋ฒ๊ฑฐ๋ก์ด EAV ํจํด์ ๋์ฒดํ ์ ์์ผ๋ฏ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ๊ฐ ํฌ๊ฒ ๋จ์ํ๋ฉ๋๋ค. ํ์ง๋ง ๋ง์ ์ฌ๋๋ค์ ์ด๊ฒ์ด ์์ฐ์ฑ ์ ํ๋ฅผ ๋๋ฐํด์ผ ํ๋ค๊ณ ์ฃผ์ฅํฉ๋๋ค... ๊ทธ๋์ ์ด ๊ธ์ ์ผ์ต๋๋ค.
ํ ์คํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์
์ด ๋น๊ต๋ฅผ ์ํด $9.5 ๋น๋์ PostgreSQL 80๋ฅผ ์๋ก ์ค์นํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ฑํ์ต๋๋ค.
CREATE TABLE entity (
id SERIAL PRIMARY KEY,
name TEXT,
description TEXT
);
CREATE TABLE entity_attribute (
id SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE entity_attribute_value (
id SERIAL PRIMARY KEY,
entity_id INT REFERENCES entity(id),
entity_attribute_id INT REFERENCES entity_attribute(id),
value TEXT
);
์๋๋ ๋์ผํ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋์ง๋ง JSONB ์ ํ ์ด์ ์์ฑ์ด ์๋ ํ ์ด๋ธ์ ๋๋ค. ์์ฑ.
CREATE TABLE entity_jsonb (
id SERIAL PRIMARY KEY,
name TEXT,
description TEXT,
properties JSONB
);
ํจ์ฌ ๋ ๋จ์ํด ๋ณด์ด์ง ์๋์? ๊ทธ๋ฐ ๋ค์ ์ํฐํฐ ํ ์ด๋ธ(์ค์ฌ & ์ํฐํฐ_jsonb) 10๋ง ๊ฐ์ ๋ ์ฝ๋์ ๋ฐ๋ผ EAV ํจํด๊ณผ JSONB ์ด์ ์ฌ์ฉํ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ๋์ผํ ๋ฐ์ดํฐ๋ก ํ ์ด๋ธ์ ์ฑ์ ์ต๋๋ค. ์ํฐํฐ_jsonb.properties. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์ ์ฒด ์์ฑ ์งํฉ ์ค์์ ์ฌ๋ฌ ๊ฐ์ง ๋ค๋ฅธ ๋ฐ์ดํฐ ์ ํ์ ๋ฐ์์ต๋๋ค. ์์ ๋ฐ์ดํฐ:
{
id: 1
name: "Entity1"
description: "Test entity no. 1"
properties: {
color: "red"
lenght: 120
width: 3.1882420
hassomething: true
country: "Belgium"
}
}
์ด์ ๋ ์ต์ ๋ชจ๋์ ๋ํด ๋์ผํ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค. ์ง์ฅ์์์ ๊ตฌํ ๋น๊ต๋ฅผ ์์ํด ๋ณด๊ฒ ์ต๋๋ค!
๋์์ธ์ ๋จ์ํํ์ธ์
์ด์ ์๋ EAV์ ์ธ ๊ฐ์ ํ ์ด๋ธ์ ์ฌ์ฉํ๋ ๋์ ์์ฑ์ JSONB ์ด์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋์์ธ์ด ํฌ๊ฒ ๋จ์ํ๋์๋ค๊ณ ์ธ๊ธํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์์ฒญ์ ์ด๋ป๊ฒ ๋ฐ์๋ฉ๋๊น? ํ๋์ ์ํฐํฐ ์์ฑ์ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
-- EAV
UPDATE entity_attribute_value
SET value = 'blue'
WHERE entity_attribute_id = 1
AND entity_id = 120;
-- JSONB
UPDATE entity_jsonb
SET properties = jsonb_set(properties, '{"color"}', '"blue"')
WHERE id = 120;
๋ณด์๋ค์ํผ ๋ง์ง๋ง ์์ฒญ์ ๋ ๋จ์ํด ๋ณด์ด์ง ์์ต๋๋ค. JSONB ๊ฐ์ฒด์ ์์ฑ ๊ฐ์ ์
๋ฐ์ดํธํ๋ ค๋ฉด ๋ค์ ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์ด์ ์๋ก์ด ์์์ ๊ธฐ๋ฐ์ผ๋ก ๋ฐฉ๊ธ ์ ๋ฐ์ดํธํ ์ํฐํฐ๋ฅผ ์ ํํด ๋ณด๊ฒ ์ต๋๋ค.
-- EAV
SELECT e.name
FROM entity e
INNER JOIN entity_attribute_value eav ON e.id = eav.entity_id
INNER JOIN entity_attribute ea ON eav.entity_attribute_id = ea.id
WHERE ea.name = 'color' AND eav.value = 'blue';
-- JSONB
SELECT name
FROM entity_jsonb
WHERE properties ->> 'color' = 'blue';
๋๋ ๋ ๋ฒ์งธ ๊ฒ์ด ๋ ์งง๊ณ (์กฐ์ธ ์์!) ๋ ์ฝ๊ธฐ ์ฝ๋ค๋ ์ ์ ๋์ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. JSONB๊ฐ ์ฌ๊ธฐ์ ์น๋ฆฌํ์ต๋๋ค! JSON ->> ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ JSONB ๊ฐ์ฒด์์ ์์์ ํ ์คํธ ๊ฐ์ผ๋ก ๊ฐ์ ธ์ต๋๋ค. @> ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ JSONB ๋ชจ๋ธ์์ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป๋ ๋ ๋ฒ์งธ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค.
-- JSONB
SELECT name
FROM entity_jsonb
WHERE properties @> '{"color": "blue"}';
์ด๋ ์ข ๋ ๋ณต์กํฉ๋๋ค. ์์ฑ ์ด์ JSON ๊ฐ์ฒด์ @> ์ฐ์ฐ์ ์ค๋ฅธ์ชฝ์ ์๋ ๊ฐ์ฒด๊ฐ ํฌํจ๋์ด ์๋์ง ํ์ธํฉ๋๋ค. ๊ฐ๋ ์ฑ์ด ๋ฎ๊ณ ์์ฐ์ฑ์ด ๋์ต๋๋ค(์๋ ์ฐธ์กฐ).
ํ ๋ฒ์ ์ฌ๋ฌ ์์ฑ์ ์ ํํด์ผ ํ๋ ๊ฒฝ์ฐ JSONB๋ฅผ ๋์ฑ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. JSONB ์ ๊ทผ ๋ฐฉ์์ด ์ค์ ๋ก ํ์ํ ๊ณณ์ ๋๋ค. ์กฐ์ธ์ด ํ์ ์์ด ๊ฒฐ๊ณผ ์งํฉ์์ ์์ฑ์ ์ถ๊ฐ ์ด๋ก ์ ํํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
-- JSONB
SELECT name
, properties ->> 'color'
, properties ->> 'country'
FROM entity_jsonb
WHERE id = 120;
EAV๋ฅผ ์ฌ์ฉํ๋ฉด ์ฟผ๋ฆฌํ๋ ค๋ ๊ฐ ์์ฑ์ ๋ํด 2๊ฐ์ ์กฐ์ธ์ด ํ์ํฉ๋๋ค. ์ ์๊ฐ์๋ ์์ ์ฟผ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ๊ฐ ํฌ๊ฒ ๋จ์ํ๋์์์ ๋ณด์ฌ์ค๋๋ค. JSONB ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ถ๊ฐ ์์ ๋ ์ฐธ์กฐํ์ธ์.
์ด์ ์ฑ๋ฅ์ ๋ํด ์ด์ผ๊ธฐํ ์ฐจ๋ก์
๋๋ค.
ะัะพะธะทะฒะพะดะธัะตะปัะฝะพััั
๋ด๊ฐ ์ฌ์ฉํ ์ฑ๋ฅ์ ๋น๊ตํ๊ธฐ ์ํด
๋ฐ์ดํฐ ์ ๋ฐ์ดํธ๋ฅผ ํตํด ์๊ฐ(ms) ๊ธฐ์ค์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋ฌ์ต๋๋ค. ์ฒ๋๋ ๋์์ ์ ๋๋ค.
์์์ ์ค๋ช
ํ ์ด์ ๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด JSONB๊ฐ EAV๋ณด๋ค ํจ์ฌ(> 50000-x) ๋น ๋ฆ
๋๋ค. ๊ธฐ๋ณธ ํค๋ก ์ด์ ์ธ๋ฑ์ฑํ๋ฉด ์ฐจ์ด๊ฐ ๊ฑฐ์ ์ฌ๋ผ์ง์ง๋ง JSONB๋ ์ฌ์ ํ EAV๋ณด๋ค 1,3๋ฐฐ ๋น ๋ฆ
๋๋ค. ํ๊ฐ ๊ธฐ์ค์์ ์์ฑ ์ด์ ์ฌ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ JSONB ์ด์ ์ธ๋ฑ์ค๋ ์ฌ๊ธฐ์ ์๋ฌด๋ฐ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
์์ฑ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ต๋๋ค(์ผ๋ฐ ์ฒ๋).
JSONB๋ ์ธ๋ฑ์ค๊ฐ ์๋ EAV๋ณด๋ค ๋น ๋ฅด๊ฒ ์๋ํ์ง๋ง ์ธ๋ฑ์ค๊ฐ ์๋ EAV์ ๊ฒฝ์ฐ ์ฌ์ ํ JSONB๋ณด๋ค ๋น ๋ฅด๊ฒ ์๋ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ JSONB ์ฟผ๋ฆฌ์ ์๊ฐ์ด ๋์ผํ๋ค๋ ๊ฒ์ ์์๊ณ ์ด๋ก ์ธํด GIN ์ธ๋ฑ์ค๊ฐ ์๋ํ์ง ์๋๋ค๋ ์ฌ์ค์ ์๊ฒ ๋์์ต๋๋ค. ์์ฑ์ด ์ฑ์์ง ์ด์ GIN ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ฉด ํฌํจ ์ฐ์ฐ์ @>๋ฅผ ์ฌ์ฉํ ๋๋ง ์ ์ฉ๋ฉ๋๋ค. ๋๋ ์ด๊ฒ์ ์๋ก์ด ํ
์คํธ์ ์ฌ์ฉํ๊ณ ์๊ฐ์ ํฐ ์ํฅ์ ๋ฏธ์ณค์ต๋๋ค: ๋จ 0,153ms! ์ด๋ EAV๋ณด๋ค 15000๋ฐฐ ๋น ๋ฅด๋ฉฐ ->> ์ฐ์ฐ์๋ณด๋ค 25000๋ฐฐ ๋น ๋ฆ
๋๋ค.
์ถฉ๋ถํ ๋นจ๋๋ ๊ฒ ๊ฐ์์!
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ ํฌ๊ธฐ
๋ ์ ๊ทผ ๋ฐฉ์์ ํ ์ด๋ธ ํฌ๊ธฐ๋ฅผ ๋น๊ตํด ๋ณด๊ฒ ์ต๋๋ค. psql์์๋ ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ์ฌ ๋ชจ๋ ํ ์ด๋ธ๊ณผ ์ธ๋ฑ์ค์ ํฌ๊ธฐ๋ฅผ ํ์ํ ์ ์์ต๋๋ค. dti+
EAV ์ ๊ทผ ๋ฐฉ์์ ๊ฒฝ์ฐ ํ
์ด๋ธ ํฌ๊ธฐ๋ ์ฝ 3068MB์ด๊ณ ์ธ๋ฑ์ค๋ ์ต๋ 3427MB๋ก ์ด 6,43GB์
๋๋ค. JSONB ์ ๊ทผ ๋ฐฉ์์ ํ
์ด๋ธ์ 1817MB, ์ธ๋ฑ์ค์ 318MB(2,08GB)๋ฅผ ์ฌ์ฉํฉ๋๋ค. 3 ๋ฐฐ ๋ ์ ์ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค! ์ฐ๋ฆฌ๋ ๋ชจ๋ JSONB ๊ฐ์ฒด์ ์์ฑ ์ด๋ฆ์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ์ด ์ฌ์ค์ ์กฐ๊ธ ๋๋์ต๋๋ค.
๊ทธ๋ฌ๋ ์ฌ์ ํ ์ซ์๋ ๊ทธ ์์ฒด๋ก ๋ํ๋ฉ๋๋ค. EAV์์๋ ์์ฑ ๊ฐ๋น 2๊ฐ์ ์ ์ ์ธ๋ ํค๋ฅผ ์ ์ฅํ์ฌ 8๋ฐ์ดํธ์ ์ถ๊ฐ ๋ฐ์ดํฐ๊ฐ ์์ฑ๋ฉ๋๋ค. ๋ํ EAV๋ ๋ชจ๋ ์์ฑ ๊ฐ์ ํ ์คํธ๋ก ์ ์ฅํ๋ ๋ฐ๋ฉด JSONB๋ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋ด๋ถ์ ์ผ๋ก ์ซ์ ๋ฐ ๋ถ์ธ ๊ฐ์ ์ฌ์ฉํ๋ฏ๋ก ๊ณต๊ฐ์ด ๋ ์์์ง๋๋ค.
๊ฒฐ๊ณผ
์ ๋ฐ์ ์ผ๋ก ์ํฐํฐ ์์ฑ์ JSONB ํ์์ผ๋ก ์ ์ฅํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํจ์ฌ ์ฝ๊ฒ ์ค๊ณํ๊ณ ์ ์ง ๊ด๋ฆฌํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ง์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ ๊ฒฝ์ฐ ๋ชจ๋ ํญ๋ชฉ์ ์ํฐํฐ์ ๋์ผํ ํ ์ด๋ธ์ ์ ์งํ๋ฉด ์ค์ ๋ก ๋ ํจ์จ์ ์ผ๋ก ์๋ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ด ๋ฐ์ดํฐ ๊ฐ์ ์ํธ ์์ฉ์ ๋จ์ํํ๋ค๋ ์ฌ์ค์ ์ด๋ฏธ ์ฅ์ ์ด์ง๋ง ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ณผ๋ฅจ์ 3๋ฐฐ ๋ ์์ต๋๋ค.
๋ํ ์ํ๋ ํ
์คํธ์ ๋ฐ๋ฅด๋ฉด ์ฑ๋ฅ ์์ค์ด ๋งค์ฐ ๋ฏธ๋ฏธํ๋ค๋ ๊ฒฐ๋ก ์ ๋ด๋ฆด ์ ์์ต๋๋ค. ์ด๋ค ๊ฒฝ์ฐ์๋ JSONB๊ฐ EAV๋ณด๋ค ํจ์ฌ ๋นจ๋ผ์ ํจ์ฌ ๋ ์ข์ต๋๋ค. ํ์ง๋ง ๋ฌผ๋ก ์ด ๋ฒค์น๋งํฌ๊ฐ ๋ชจ๋ ์ธก๋ฉด(์: ๋งค์ฐ ๋ง์ ์์ ์์ฑ์ ๊ฐ์ง ์ํฐํฐ, ๊ธฐ์กด ๋ฐ์ดํฐ์ ์์ฑ ์์ ์๋นํ ์ฆ๊ฐ ๋ฑ)์ ๋ค๋ฃจ์ง๋ ์์ผ๋ฏ๋ก ์ด๋ฅผ ๊ฐ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ ์ ์ฌํญ์ด ์์ผ๋ฉด , ์์ ๋กญ๊ฒ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์!
์ถ์ฒ : habr.com