13์ฃผ์ฐจ ์๋ฃ์ ๋ชจ๋ ํ ํฝ์ "DB ์ด๋ก โ SQL ์ฑ๋ฅ"์ ๋ ์ถ์ผ๋ก ์ฌ๋ฐฐ์ดํ ํ์ต ๊ฒฝ๋ก.
12์ฃผ์ฐจ๊น์ง Java/Spring/JPA๋ฅผ ๋ค๋ค๋ค๋ฉด, 13์ฃผ์ฐจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ๋๋ฉํธ๋ก ๋ฐฉํฅ ์ ํ.1) Part A โ DB ์ด๋ก ๊ณผ ๊ด๋ฆฌ (๋ชจ๋ธ๋ง, ์ ๊ทํ, NoSQL, ๋ถ์ฐ ์์คํ ์ด๋ก , ๋ฝ)
2) Part B โ SQL ์ฑ๋ฅ ์ต์ ํ (์ตํฐ๋ง์ด์ , ์ธ๋ฑ์ค, B-tree, EXPLAIN)JPA๊ฐ ์ถ์ํํด์ ๊ฐ๋ ค๋์๋ DB ๋ณธ์ฐ์ ์์ญ์ ์ ๋ฉด์ผ๋ก ๋ณด๋ ์ฃผ์ฐจ๋ค.
[Part A โ DB ์ด๋ก ๊ณผ ๊ด๋ฆฌ]
[Phase 1] DB ํต์ฌ ์ฉ์ด์ ๋ชจ๋ธ๋ง (์ํฐํฐ/๋ฆด๋ ์ด์
/์คํค๋ง)
โ
[Phase 2] ์ ๊ทํ (1NF โ 2NF โ 3NF โ BCNF)
โ
[Phase 3] ์ด์ ํ์๊ณผ ์ ๊ทํ ํ๊ฐ
โ
[Phase 4] SQL Injection ๋ณด์
โ
[Phase 5] RDBMS์ NoSQL (Scale-Up vs Scale-Out)
โ
[Phase 6] ๋ถ์ฐ ์์คํ
์ด๋ก + ๋ฝ (BASE/CAP/PACELC + S/X Lock)
[Part B โ SQL ์ฑ๋ฅ ์ต์ ํ]
[Phase 7] ์ตํฐ๋ง์ด์ (RBO/CBO + ๋์ 6๋จ๊ณ)
โ
[Phase 8] ์ธ๋ฑ์ค ๊ธฐ์ด (๋น
์ค, B-tree) โ ์ ์ 1
โ
[Phase 9] ๋ฉํฐ์ปฌ๋ผ ์ธ๋ฑ์ค์ EXPLAIN
โ
[Phase 10] ์ธ๋ฑ์ค ์ต์ ํ ์ ๋ต (Covering Index, Full Scan ์ ํ)
์ด 10 Phase ร 31 Unit โ ๋จ์ผ ์ฃผ์ฐจ๋ก๋ ํฐ ๋ถ๋ (Part A/B ๊ตฌ์กฐ).
| ์ฃผ์ฐจ | ์ฃผ์ | ํต์ฌ ๋ณํ |
|---|---|---|
| 1์ฃผ์ฐจ | OOPยทJVMยทGCยท์ปฌ๋ ์ ยทI/O ๊ฐ๋ก | ์๋ฐ ํฐ ๊ทธ๋ฆผ |
| 2์ฃผ์ฐจ | JVM ๋ด๋ถยท๋ฐ์ดํธ์ฝ๋ยทG1 GC | "์ด๋ป๊ฒ ๋์๊ฐ๋" |
| 3์ฃผ์ฐจ | ์ปฌ๋ ์ ยท์ ๋ค๋ฆญยทํจ์ํ | ์๋ฐ ํํ๋ ฅ |
| 4์ฃผ์ฐจ | ๋ฉํฐ์ค๋ ๋ฉยท๋์์ฑยทExecutor | ๋์์ฑ ์ ๋ณต |
| 5์ฃผ์ฐจ | Atomic + Spring IoC/DI ์ ๋ฌธ | ์๋ฐ โ Spring ๋ค๋ฆฌ |
| 6์ฃผ์ฐจ | ํ ์คํธ + ์น ์ธํ๋ผ + DB ์ ๊ทผ ์งํ | Spring ์ค์ ํ๊ฒฝ |
| 7์ฃผ์ฐจ | JPA/ORM ์ ๋ฌธ + ํธ๋์ญ์ ์ถ์ํ | DB ์ถ์ํ ์ ๋ฌธ |
| 8์ฃผ์ฐจ | ํ๋ก์์ ์งํ | AOP ๋ฉ์ปค๋์ฆ |
| 9์ฃผ์ฐจ | Spring AOP ์ค์ + ํธ๋์ญ์ ์ ํ | AOP ์ค์ ํ์ฉ |
| 10์ฃผ์ฐจ | ํธ๋์ญ์ ์ ๋ฆฌ + ๋น ๋ผ์ดํ์ฌ์ดํด ํจ์ + ๊ฒฉ๋ฆฌ ์์ค | ํธ๋์ญ์ ๋ง๋ฌด๋ฆฌ |
| 11์ฃผ์ฐจ | JPA์ ์ ์ฒด์ ์์์ฑ ์ปจํ ์คํธ | JPA ๋ฉ์ปค๋์ฆ ์์ ์ดํด |
| 12์ฃผ์ฐจ | ์ฐ๊ด๊ด๊ณ + N+1 ๋ฑ ์ฑ๋ฅ ์ต์ ํ | JPA ์ค์ ํ์ฉ |
| 13์ฃผ์ฐจ (์ง๊ธ) | DB ํ๋๋ฉํธ - ๋ชจ๋ธ๋ง๋ถํฐ ์ธ๋ฑ์ค๊น์ง | DB ๋ณธ์ฐ์ ์์ญ์ผ๋ก |
| Day | Phase | ํ์ต ๋ชฉํ |
|---|---|---|
| Part A | ||
| 1์ผ์ฐจ | Phase 1 + 2 | DB ์ฉ์ด + ์ ๊ทํ (1NF~BCNF) |
| 2์ผ์ฐจ | Phase 3 + 4 | ์ด์ ํ์ + SQL Injection |
| 3์ผ์ฐจ | Phase 5 | RDBMS์ NoSQL (Scale, Redis) |
| 4์ผ์ฐจ | Phase 6 | BASE/CAP/PACELC + ๊ณต์ ๋ฝ/๋ฒ ํ๋ฝ |
| Part B | ||
| 5์ผ์ฐจ | Phase 7 + 8 | ์ตํฐ๋ง์ด์ + ์ธ๋ฑ์ค ๊ธฐ์ด (B-tree) โ |
| 6์ผ์ฐจ | Phase 9 | ๋ฉํฐ์ปฌ๋ผ ์ธ๋ฑ์ค + EXPLAIN |
| 7์ผ์ฐจ | Phase 10 + ์ข ํฉ | Covering Index + ์ธ๋ฑ์ค ์ต์ ํ + ์๊ธฐ ์ ๊ฒ |
์ฌ์ ์ผ์ (10์ผ): Phase 8๊ณผ Phase 9์ ๊ฐ +1์ผ. ์ธ๋ฑ์ค๋ ์ง์ SQL์ ๋๋ฆฌ๋ฉฐ EXPLAIN์ผ๋ก ํ์ธํด์ผ ์ฒดํ๋จ.
๋ชฉํ: JPA๊ฐ ๊ฐ๋ ค๋์๋ DB์ ๊ธฐ๋ณธ ์ดํ๋ฅผ ์ ํํ ์ก๋๋ค.
์ ์ ์ง์: 6์ฃผ์ฐจ Phase 6 (DB ๊ธฐ์ด), 11์ฃผ์ฐจ Phase 3
ํต์ฌ ๊ฐ๋
์ํฐํฐ(Entity):
๋ฆด๋ ์ด์ (Relation):
๋น์ :
"์ํฐํฐ๋ ํด๋์ค, ๋ฆด๋ ์ด์ ์ ์ธ์คํด์ค์ ๋ชจ์(ํ ์ด๋ธ)"
ILIC ์ฌ๋ก:
Booking ๊ฐ์ฒด (๊ฐ๋
)bookings ํ
์ด๋ธ (๋ฌผ๋ฆฌ)@Entity ๊ฐ ์ด ๋ ๊ฐ๋
์ ์๋ ๋ค๋ฆฌ์๊ธฐ ์ ๊ฒ
@Entity ์ด๋
ธํ
์ด์
์ด ๋งคํํ๋ ๋ ์ธ๊ณ๋?์ ์ ์ง์: Unit 1.1
ํต์ฌ 5๊ฐ์ง ์ฉ์ด โญ :
| ์ฉ์ด | ์๋ฏธ | ์์ (๊ณ ๊ฐ ํ ์ด๋ธ) |
|---|---|---|
| ์ดํธ๋ฆฌ๋ทฐํธ(Attribute) | ์์ฑ = ์ด(Column) | ์ด๋ฆ, ์ ํ๋ฒํธ, ์ฃผ์ |
| ์ฐจ์(Degree) | ์ดํธ๋ฆฌ๋ทฐํธ์ ๊ฐ์ | 4 |
| ํํ(Tuple) = ๋ ์ฝ๋ | ํ(Row) ํ๋ | ๊น์ฒ ์, 010-..., ์์ธ |
| ์นด๋๋๋ฆฌํฐ(Cardinality) | ํํ์ ๊ฐ์ | 1000 |
| ๋๋ฉ์ธ(Domain) | ์ดํธ๋ฆฌ๋ทฐํธ๊ฐ ๊ฐ์ง ์ ์๋ ๊ฐ์ ์งํฉ | ์๊ฒฝ ์ฐฉ์ฉ = {์ , ๋ฌด} |
ํต์ฌ ์ฐจ์ด:
๋๋ฉ์ธ ์์:
CREATE TABLE customer (
glasses VARCHAR(2) CHECK (glasses IN ('์ ', '๋ฌด')) -- ๋๋ฉ์ธ = {์ , ๋ฌด}
);
โ JPA๋ก ํํํ๋ฉด enum ๋๋ @Check ์ด๋ ธํ ์ด์
์๊ธฐ ์ ๊ฒ
bookings ํ
์ด๋ธ์ ์ฐจ์์ ์นด๋๋๋ฆฌํฐ๋?์ ์ ์ง์: Unit 1.2
ํต์ฌ ๊ฐ๋
์คํค๋ง:
"๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์ ์"
3๊ณ์ธต ๊ตฌ์กฐ โญ :
| ๊ณ์ธต | ์ ์ | ํํ ๋ฐฉ์ |
|---|---|---|
| ๊ฐ๋ ์ ์คํค๋ง | ๋ชจ๋ ์ฌ์ฉ์ ๊ณต์ ๊ตฌ์กฐ | ERD (Entity-Relationship Diagram) |
| ๋ ผ๋ฆฌ์ ์คํค๋ง | ํน์ DB ๋ชจ๋ธ๋ก ๋ณํ | SQL DDL ๊ตฌ๋ฌธ |
| ๋ฌผ๋ฆฌ์ ์คํค๋ง | ๋์คํฌ ์ ์ฅ ๋ฐฉ์ | ์ธ๋ฑ์ค, ํํฐ์ , ํด๋ฌ์คํฐ๋ง |
์์ ํ๋ฆ:
[์ค๊ณ] ๊ณ ๊ฐ โ ์ฃผ๋ฌธ (1:N) โ ERD
โ
[๋ณํ] CREATE TABLE customer (...); -- DDL
CREATE TABLE order (...);
โ
[์ ์ฅ] B-tree ์ธ๋ฑ์ค, ํ์ด์ง ํฌ๊ธฐ 16KB, ...
์คํค๋ง vs ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ด๊ณ:
์๊ธฐ ์ ๊ฒ
๋ชฉํ: ๋ฐ์ดํฐ ์ค๋ณต์ ์ค์ด๊ณ ์ด์ ํ์์ ์ ๊ฑฐํ๋ ๋จ๊ณ์ ๋ถํด ๊ธฐ๋ฒ์ ๋ง์คํฐํ๋ค. ๋ฉด์ ๋จ๊ณจ.
์ ์ ์ง์: Phase 1
ํต์ฌ ๊ฐ๋
์ ๊ทํ(Normalization):
"์์ฑ ๊ฐ ์ข ์ ๊ด๊ณ๋ฅผ ๋ถ์ํ์ฌ ์ฌ๋ฌ ๋ฆด๋ ์ด์ ์ผ๋ก ๋ถํด ํ๋ ๊ณผ์ "
๋ชฉ์ :
๋จ๊ณ์ ๋ถํด โญ :
์๋ณธ โ 1NF โ 2NF โ 3NF โ BCNF โ ... (4NF, 5NF๋ ๊ฑฐ์ ์ ์)
์ค๋ฌด ๊ถ์ฅ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.1
ํต์ฌ ๊ท์น:
"ํ ์ด๋ธ์ ๋ชจ๋ ์ปฌ๋ผ์ด ์์๊ฐ(Atomic Value) ์ ๊ฐ์ ธ์ผ ํ๋ค"
์๋ฐ ์ฌ๋ก:
| ์ด๋ฆ | ์ทจ๋ฏธ |
|---|---|
| ๊น์ฐ์ | ์ธํฐ๋ท |
| ์ถ์ ์ | ์ํ, ์์ โ ์์๊ฐ X! |
| ๋ฐ์ธ๋ฆฌ | ์์ , ์ผํ |
1NF ์ ์ฉ ํ:
| ์ด๋ฆ | ์ทจ๋ฏธ |
|---|---|
| ๊น์ฐ์ | ์ธํฐ๋ท |
| ์ถ์ ์ | ์ํ |
| ์ถ์ ์ | ์์ |
| ๋ฐ์ธ๋ฆฌ | ์์ |
| ๋ฐ์ธ๋ฆฌ | ์ผํ |
๋ชจ๋ฒ ์ฌ๋ก:
ํ๋ DB์ ์์ธ (์ฐธ๊ณ ):
ARRAY ํ์
JSON ์ปฌ๋ผ์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.2
ํต์ฌ ๊ท์น:
"1NF + ๊ธฐ๋ณธ ํค์ ์ผ๋ถ์๋ง ์ข ์๋ ์์ฑ์ ๋ค๋ฅธ ํ ์ด๋ธ๋ก ๋ถ๋ฆฌ"
์ ์ : ๊ธฐ๋ณธ ํค๊ฐ ๋ณตํฉ ํค(composite key)์ผ ๋ ์๋ฏธ๊ฐ ์์
์๋ฐ ์ฌ๋ก:
๊ธฐ๋ณธ ํค = (ํ์ID, ๊ฐ์๋ช )
| ํ์ID | ๊ฐ์๋ช | ํ์๋ช | ๊ต์๋ช |
|---|---|---|---|
| 101 | ๋ฐ์ดํฐ๋ฒ ์ด์ค | Alice | ๊น๊ต์ |
| 101 | ์ด์์ฒด์ | Alice | ๋ฐ๊ต์ |
์ข ์ ๋ถ์:
ํ์๋ช
์ ํ์ID ๋ง์ผ๋ก ๊ฒฐ์ โ ๋ถ๋ถ ํจ์ ์ข
์๊ต์๋ช
์ ๊ฐ์๋ช
๋ง์ผ๋ก ๊ฒฐ์ โ ๋ถ๋ถ ํจ์ ์ข
์2NF ์ ์ฉ โ 3๊ฐ ํ ์ด๋ธ๋ก ๋ถ๋ฆฌ:
[ํ์ ํ
์ด๋ธ] (ํ์ID ๊ธฐ๋ณธ ํค)
| ํ์ID | ํ์๋ช
|
|---|---|
| 101 | Alice |
[๊ฐ์ ํ
์ด๋ธ] (๊ฐ์๋ช
๊ธฐ๋ณธ ํค)
| ๊ฐ์๋ช
| ๊ต์๋ช
|
|---|---|
| ๋ฐ์ดํฐ๋ฒ ์ด์ค | ๊น๊ต์ |
[์๊ฐ ํ
์ด๋ธ] (ํ์ID, ๊ฐ์๋ช
๋ณตํฉ ํค)
| ํ์ID | ๊ฐ์๋ช
|
|---|---|
| 101 | ๋ฐ์ดํฐ๋ฒ ์ด์ค |
| 101 | ์ด์์ฒด์ |
ํต์ฌ ํต์ฐฐ:
"๋ถ๋ถ ํจ์ ์ข ์ = ๋ณตํฉ ํค์ ์ผ๋ถ๋ถ์๋ง ์์กดํ๋ ์์ฑ"
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.3
ํต์ฌ ๊ท์น (3NF):
"2NF + ๊ธฐ๋ณธ ํค๊ฐ ์๋ ์์ฑ์ด ์ดํ ํจ์ ์ข ์(Transitive Dependency) ๋์ง ์์"
์ดํ ํจ์ ์ข ์:
"A โ B ์ด๊ณ B โ C ์ผ ๋ A โ C ์ธ ๊ด๊ณ"
์๋ฐ ์ฌ๋ก (๊ธฐ๋ณธ ํค = ์ด๋ฆ):
| ์ด๋ฆ | ํ๊ณผ | ๋ฑ๋ก๊ธ |
|---|---|---|
| ์ฒ ์ | ๊ธฐ๊ณ๊ณตํ | 350 |
| ์ํฌ | ์ํ | 250 |
| ๋ฏผ์ | ํํ๊ณตํ | 300 |
์ข ์ ๋ถ์:
๋ฌธ์ :
3NF ์ ์ฉ:
[ํ์ ํ
์ด๋ธ]
| ์ด๋ฆ | ํ๊ณผ |
|---|---|
| ์ฒ ์ | ๊ธฐ๊ณ๊ณตํ |
[ํ๊ณผ ํ
์ด๋ธ]
| ํ๊ณผ | ๋ฑ๋ก๊ธ |
|---|---|
| ๊ธฐ๊ณ๊ณตํ | 350 |
BCNF (Boyce-Codd Normal Form):
"3NF + ๋ชจ๋ ๊ฒฐ์ ์๊ฐ ํ๋ณด ํค์ฌ์ผ ํจ"
์ฉ์ด:
์๋ฐ ์ฌ๋ก:
| ํ์๋ฒํธ | ๊ณผ๋ชฉ | ์ง๋๊ต์ |
|---|
ํ๋ณด ํค: (ํ์๋ฒํธ, ๊ณผ๋ชฉ) โ ์ง๋๊ต์ ๊ฒฐ์ ๊ฐ๋ฅ
ํ์ง๋ง: ์ง๋๊ต์ โ ๊ณผ๋ชฉ ๋ ๊ฒฐ์ ๊ฐ๋ฅ
โ BCNF ์๋ฐ
BCNF ์ ์ฉ:
์ค๋ฌด ๊ฒฐ๋ก :
"๋ณดํต 3NF๊น์ง ์ ๊ทํ. BCNF๋ ํน์ ์ํฉ"
์๊ธฐ ์ ๊ฒ
๋ชฉํ: ์ ๊ทํ์ ๋๊ธฐ(์ ํ์ํ๊ฐ)์ ํ๊ณ(์ธ์ ์ ์ข์๊ฐ)๋ฅผ ๋ชจ๋ ๋ณธ๋ค.
์ ์ ์ง์: Phase 2
ํต์ฌ 3๊ฐ์ง โญ :
์ฝ์ ์ด์(Insertion Anomaly):
"ํน์ ๋ฐ์ดํฐ ์ฝ์ ์ ๋ถํ์ํ ๋ฐ์ดํฐ ๊น์ง ํจ๊ป ์ ๋ ฅํด์ผ ํจ"
์: "์๊ณ ๋ฆฌ์ฆ" ์ ๊ท ๊ณผ๋ชฉ์ ์ถ๊ฐํ๋ ค๋๋ฐ ํ์์ด ์์ผ๋ฉด NULL์ ๋ฃ๊ฑฐ๋ ๋๋ฏธ ํ์ ์ ๋ณด ํ์
๊ฐฑ์ ์ด์(Update Anomaly):
"๋ฐ์ดํฐ ์์ ์ ์ฌ๋ฌ ๋ ์ฝ๋๋ฅผ ๋ชจ๋ ์์ ํด์ผ ํจ โ ์ผ๋ถ๋ง ์์ ์ ๋ถ์ผ์น"
์: ๊น๊ต์์ ์ฐ๋ฝ์ฒ ๋ณ๊ฒฝ ์ ๊น๊ต์๊ฐ ๊ฐ๋ฅด์น๋ ๋ชจ๋ ๊ฐ์ ๋ ์ฝ๋ ๊ฐฑ์ ํ์
UPDATE ๊ฐ์์ ๋ณด SET ๊ต์์ฐ๋ฝ์ฒ = '...' WHERE ๊ต์ID = 1;
-- 5๊ฐ ๋ ์ฝ๋ ๋ชจ๋ ๊ฐฑ์ โ ์ผ๋ถ ๋๋ฝ ์ ๋ถ์ผ์น
์ญ์ ์ด์(Deletion Anomaly):
"ํน์ ๋ฐ์ดํฐ ์ญ์ ์ ์๋ํ์ง ์์ ๋ฐ์ดํฐ ๊น์ง ํจ๊ป ์ญ์ ๋จ"
์: ํ์์ด ์๊ฐ ์ทจ์ โ ๊ทธ ํ์์ด ๋ง์ง๋ง ์๊ฐ์์๋ค๋ฉด โ ๊ณผ๋ชฉ ์ ๋ณด๊น์ง ์ฌ๋ผ์ง
3๊ฐ์ง๊ฐ ๋ฐ์ํ๋ ๊ทผ๋ณธ ์์ธ:
"์๋ก ๋ค๋ฅธ ์๋ฏธ์ ์ ๋ณด๊ฐ ํ ํ ์ด๋ธ์ ๋ฌถ์ฌ ์์"
โ ์ ๊ทํ ๊ฐ ํด๊ฒฐ โญ
ILIC ๊ด์ ์ ๊ฒ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 3.1
ํต์ฌ ํ๊ฐ
์ฅ์ :
๋จ์ :
๋ฐ์ ๊ทํ(Denormalization):
"์ฑ๋ฅ์ ์ํด ์๋์ ์ผ๋ก ์ผ๋ถ ๋ฐ์ดํฐ ์ค๋ณต ํ์ฉ"
์ธ์ ๋ฐ์ ๊ทํ?:
1. ์์ฃผ ํจ๊ป ์กฐํ๋๋ ๋ฐ์ดํฐ โ JOIN ๋น์ฉ ์ ๊ฐ
2. ํต๊ณ ๋งํธ, ๋ณด๊ณ ์์ฉ ํ
์ด๋ธ
3. ์ฝ๊ธฐ ๋น์จ์ด ์๋์ ์ผ๋ก ๋์ ํ
์ด๋ธ
ILIC ์ฌ๋ก:
์์น:
"์ ๊ทํ ํ ๋ฐ์ ๊ทํ โ ์ ๋ ์ฒ์๋ถํฐ ๋น์ ๊ทํ๋ก ์์ํ์ง ๋ง ๊ฒ"
์๊ธฐ ์ ๊ฒ
๋ชฉํ: ๊ฐ์ฅ ํํ ์น ๋ณด์ ์ทจ์ฝ์ ์ ์ดํดํ๊ณ ํ์ค ๋ฐฉ์ด๋ฒ์ ์ตํ๋ค.
์ ์ ์ง์: 6์ฃผ์ฐจ Phase 7 (JdbcTemplate)
ํต์ฌ ๊ฐ๋
SQL Injection:
"์ฌ์ฉ์ ์ ๋ ฅ์ ์ ์์ ์ธ SQL ์ฝ๋๋ฅผ ์ฃผ์ ํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ์กฐ์ํ๋ ๊ณต๊ฒฉ"
์ทจ์ฝ ์ฝ๋:
String username = request.getParameter("username");
String query = "SELECT * FROM users WHERE username = '" + username + "'";
// โ ์ง์ ๋ฌธ์์ด ๊ฒฐํฉ (์ํ!)
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
๊ณต๊ฒฉ ์๋๋ฆฌ์ค:
' OR '1'='1 ์
๋ ฅSELECT * FROM users WHERE username = '' OR '1'='1'
-- โ ํญ์ ์ฐธ โ ๋ชจ๋ ์ฌ์ฉ์ ์กฐํ!
๋ค๋ฅธ ๊ณต๊ฒฉ ํจํด:
'; DROP TABLE users; -- โ ํ
์ด๋ธ ์ญ์ ' UNION SELECT password FROM admins -- โ ๊ถํ ์ฐํํผํด:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 4.1
ํต์ฌ ๋ฐฉ์ด โ Prepared Statement โญ :
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, username); // ์
๋ ฅ๊ฐ์ด SQL์ด ์๋ ๋ฐ์ดํฐ๋ก ์ธ์
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
์ ์์ ํ๊ฐ:
', ;, -- ๋ฑ์ด ์๋ ์ด์ค์ผ์ดํJPA์ ์๋ ์ ์ฉ:
:userName)๋ค์ธต ๋ฐฉ์ด (Defense in Depth):
public static String sanitizeInput(String input) {
return input.replaceAll("[^a-zA-Z0-9]", ""); // ์์ซ์๋ง
}
Spring Security์ ๋์:
@Valid, @Pattern)์๊ธฐ ์ ๊ฒ
PreparedStatement๋ฅผ ์ฐ๋ฉด ์ ๋ง 100% ์์ ํ๊ฐ? (ํํธ: ๋์ ํ
์ด๋ธ๋ช
/์ปฌ๋ผ๋ช
์ ์ฌ์ ํ ์ํ)๋ชฉํ: ๋ฐ์ดํฐ ์ ์ฅ์ ๋ ํจ๋ฌ๋ค์์ ๋น๊ตํ๊ณ , ILIC๊ฐ ์ RDBMS์ธ์ง ์ดํดํ๋ค.
์ ์ ์ง์: 6์ฃผ์ฐจ Phase 6, 10์ฃผ์ฐจ Phase 5
ํต์ฌ ์ ์
RDBMS (Relational Database Management System):
"๋ฐ์ดํฐ๋ฅผ ํ ์ด๋ธ ํํ๋ก ์ ์ฅํ๊ณ ๊ด๊ณ๋ฅผ ์ ์ํ์ฌ ๊ด๋ฆฌ"
4๊ฐ์ง ํต์ฌ ํน์ง:
| ์ ์ฝ | ์๋ฏธ |
|---|---|
| PRIMARY KEY | ํ ์๋ณ, ์ค๋ณต/NULL ๋ถ๊ฐ |
| FOREIGN KEY | ๋ค๋ฅธ ํ ์ด๋ธ ์ฐธ์กฐ |
| UNIQUE | ์ค๋ณต ๋ฐฉ์ง |
| NOT NULL | ํ์ ์ ๋ ฅ |
| CHECK | ๊ฐ ๋ฒ์/์กฐ๊ฑด ๊ฒ์ฆ |
๋ํ RDBMS:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.1
ํต์ฌ ๋น๊ต:
| Scale-Up (์์ง ํ์ฅ) | Scale-Out (์ํ ํ์ฅ) | |
|---|---|---|
| ๋ฐฉ์ | ๋จ์ผ ์๋ฒ ์ฑ๋ฅ ์ ๊ทธ๋ ์ด๋ | ์ฌ๋ฌ ์๋ฒ ์ถ๊ฐ |
| ๋น์ | ๋ ํฐ ์ปดํจํฐ | ์ปดํจํฐ ์ฌ๋ฌ ๋ |
| ์ ํฉ | RDBMS | NoSQL |
| ํ๊ณ | ํ๋์จ์ด ํ๊ณ, ๋น์ฉ โ | ๋ฐ์ดํฐ ์ ํฉ์ฑ, ๋คํธ์ํฌ ๋น์ฉ |
| ์ | CPU/RAM/SSD ๊ฐํ | Sharding, Replication |
RDBMS๊ฐ Scale-Up ์ ํธํ๋ ์ด์ :
NoSQL์ด Scale-Out ์ ํธํ๋ ์ด์ :
Replication (๋ณต์ ):
ILIC์ ํ์ค:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.2
RDB์ ํ๊ณ (NoSQL ๋ฑ์ฅ ๋๊ธฐ):
1. ์ ์ฐํ ํ์ฅ์ฑ ๋ถ์กฑ (์คํค๋ง ๋ณ๊ฒฝ ๋น์ฉ)
2. ๋ฐ์ดํฐ ์ค๋ณต ๋นํ์ฉ โ ๋ณต์กํ JOIN
3. ๋จ์ผ ์๋ฒ ํธ๋ํฝ ํ๊ณ
4. ACID ๋ณด์ฅ์ ์ฑ๋ฅ ๋น์ฉ
NoSQL = "Not Only SQL":
NoSQL 5๊ฐ์ง ํน์ง:
1. ์ ์ฐํ ์คํค๋ง โ ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ์ ์ฑ์์ ์ฑ
์
2. ๋์ ํ์ฅ์ฑ โ Scale-Out ์นํ
3. ๋น ๋ฅธ ์ฒ๋ฆฌ ์๋ โ JOIN ํํผ, ์ค์ฒฉ ์ ์ฅ
4. ๋ค์ํ ์ ์ฅ ๋ฐฉ์ โ JSON, Key-Value, Graph ๋ฑ
5. BASE ๋ชจ๋ธ โ ACID ๋์
4๊ฐ์ง NoSQL ์ ํ โญ :
| ์ ํ | ์ ์ฅ ๋ฐฉ์ | ๋ํ ์ ํ | ์ฌ์ฉ ์ฌ๋ก |
|---|---|---|---|
| Key-Value | ํค-๊ฐ ๋จ์ ์ ์ฅ | Redis, DynamoDB | ์บ์, ์ธ์ |
| Document | JSON/BSON ๋ฌธ์ | MongoDB, CouchDB | ๋ค์ํ ๊ตฌ์กฐ ๋ฐ์ดํฐ |
| Column-Family | ์ด ๊ธฐ๋ฐ ์ ์ฅ | Cassandra, HBase | ๋๋ ์๊ณ์ด, ๋ถ์ |
| Graph | ๋ ธ๋ + ์ฃ์ง | Neo4j, Amazon Neptune | ๊ด๊ณ ๋ถ์, ์ถ์ฒ |
Document Store ํต์ฌ โ ์ปฌ๋ ์ (Collection):
// ๊ฐ์ users ์ปฌ๋ ์
์์ ๋ ๋ค๋ฅธ ๊ตฌ์กฐ OK
{ "name": "Alice", "age": 25 }
{ "name": "Bob", "skills": ["Java", "Python"] }
Graph DB์ ๊ฐ๋ ฅํจ:
๊ธ์ต/๊ฒฐ์ /์์ฝ ๊ฐ์ ๋ฐ์ดํฐ ์ผ๊ด์ฑ ์ค์ ์์ญ์ NoSQL ์ฌ์ฉ ์กฐ์ฌ.
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.3, 4์ฃผ์ฐจ Phase 5
ํต์ฌ ๊ฐ๋
Redis (Remote Dictionary Server):
ํ์ฉ ์์ญ โญ :
[Client] โ [App] โ [Redis] (์์ผ๋ฉด ๋ฐํ)
โ (์์ผ๋ฉด)
[DB] โ [Redis ์ ์ฅ] โ [Client]
๋ฉ์์ง ํ (Pub/Sub)
๋ถ์ฐ ๋ฝ:
SETNX ๋ช
๋ น์ผ๋ก ๋จ์ผ ๋ฝ ๊ตฌํ์ ํ๋ธ ์บ์ฑ ์์:
1. ์ฌ์ฉ์๊ฐ ๋์์ ์์ฒญ
2. Backend โ Redis ์กฐํ (TTL 60์ด ์ค์ )
3. ์์ผ๋ฉด โ ์ฆ์ ๋ฐํ (DB ์ ๊ฑฐ์นจ)
4. ์์ผ๋ฉด โ DB ์กฐํ โ Redis ์ ์ฅ โ ๋ฐํ
๊ณ ๊ฐ์ฉ์ฑ (High Availability):
ILIC ์ ์ฉ ๊ฐ๋ฅ:
์๊ธฐ ์ ๊ฒ
๋ชฉํ: ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ผ๊ด์ฑยท๊ฐ์ฉ์ฑ ํธ๋ ์ด๋์คํ ์ด๋ก ๊ณผ ๋์์ฑ ์ ์ด๋ฅผ ์ดํดํ๋ค.
์ ์ ์ง์: Phase 5, 6์ฃผ์ฐจ ACID
ํต์ฌ ๊ฐ๋
BASE = ACID์ ๋ฐ๋ ์ฒ ํ โญ :
3๊ฐ์ง ํ์ด๋ณด๊ธฐ:
1. Basically Available (๊ธฐ๋ณธ์ ๊ฐ์ฉ์ฑ):
2. Soft State (๋ถ๋๋ฌ์ด ์ํ):
3. Eventually Consistent (์ต์ข ์ ์ผ๊ด์ฑ):
์์ โ ๋ถ์ฐ ํ๊ฒฝ ๊ฒ์๋ฌผ ์
๋ก๋:
1. ์ฌ์ฉ์๊ฐ ๊ฒ์๋ฌผ ์
๋ก๋
2. ์ผ๋ถ ์๋ฒ: ์ฆ์ ๋ฐ์
3. ์ผ๋ถ ์๋ฒ: ์ ์ ๋์ ๋ณด์ด์ง ์์
4. ๋ช ์ด~๋ช ๋ถ ํ: ๋ชจ๋ ์๋ฒ ๋๊ธฐํ ์๋ฃ
ACID vs BASE:
| ์ธก๋ฉด | ACID | BASE |
|---|---|---|
| ์ผ๊ด์ฑ | ์ฆ์ ๊ฐํ ์ผ๊ด์ฑ | ์ต์ข ์ ์ผ๊ด์ฑ |
| ๊ฐ์ฉ์ฑ | ์ผ๊ด์ฑ ์ํด ์๋ณด | ์ฐ์ ๋ณด์ฅ |
| ํธ๋์ญ์ | ๊ฐ๋ ฅ | ๋์จ |
| ์ ํฉ ์์ญ | ๊ธ์ตยท๊ฒฐ์ | SNSยท๋ก๊ทธยท๊ฒ์ |
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.1
ํต์ฌ ์ด๋ก
CAP ์ด๋ก :
"๋ถ์ฐ ์์คํ ์์ Consistency, Availability, Partition Tolerance ์ค 2๊ฐ์ง๋ง ๋ง์กฑ ๊ฐ๋ฅ"
3๊ฐ์ง ์์ฑ:
| ์ ์ | |
|---|---|
| C Consistency (์ผ๊ด์ฑ) | ๋ชจ๋ ๋ ธ๋์์ ๊ฐ์ ๊ฐ |
| A Availability (๊ฐ์ฉ์ฑ) | ๋ชจ๋ ์์ฒญ์ ์๋ต |
| P Partition Tolerance (๋ถํ ํ์ฉ์ฑ) | ๋คํธ์ํฌ ๋จ์ ์์๋ ๋์ |
3๊ฐ์ง ์กฐํฉ:
CP (์ผ๊ด์ฑ + ๋ถํ ํ์ฉ์ฑ) โ NoSQL:
AP (๊ฐ์ฉ์ฑ + ๋ถํ ํ์ฉ์ฑ) โ NoSQL:
CA (์ผ๊ด์ฑ + ๊ฐ์ฉ์ฑ) โ RDBMS:
์ค์ํ ํต์ฐฐ:
"ํ์ค ๋ถ์ฐ ์์คํ ์์๋ P(Partition)๋ ํ์"
๋ฐ๋ผ์ ์ง์ง ์ ํ์ CP vs AP
ILIC ๊ด์ :
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.2
ํต์ฌ ๊ฐ๋
CAP์ ํ๊ณ:
PACELC:
"Partition ๋ฐ์ ์ Availability vs Consistency, Else ์ ์ ์ Latency vs Consistency"
๋ ๊ฐ์ง ๋ถ๊ธฐ:
PA/PC: ๋คํธ์ํฌ ์ฅ์ ์ (CAP๊ณผ ๋์ผ)
EL/EC: ์ ์ ์
๋ํ ์์คํ ๋ถ๋ฅ:
| ์์คํ | ๋ถ๋ฅ | ํน์ง |
|---|---|---|
| MongoDB | PA + EC | ์ฅ์ ์ ๊ฐ์ฉ์ฑ, ์ ์ ์ ์ผ๊ด์ฑ |
| Cassandra | PA + EL | ์ฅ์ ์ ๊ฐ์ฉ์ฑ, ์ ์ ์ ์ง์ฐ ์ฐ์ |
| HBase, Spanner | PC + EC | ์ฅ์ ์ยท์ ์ ์ ๋ชจ๋ ์ผ๊ด์ฑ ์ฐ์ |
| DynamoDB | PA + EL | Cassandra ์ ์ฌ |
| MySQL (๋จ์ผ) | (CA), EC | ์ฅ์ ๊ฐ์ X, ์ผ๊ด์ฑ |
ํต์ฌ ํต์ฐฐ:
"CAP๋ ์ฅ์ ์๋ง ๋ค๋ฃฌ๋ค. PACELC๋ ํ์์ ํธ๋ ์ด๋์คํ ๋ ๋ณธ๋ค"
ILIC ๊ด์ :
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: 4์ฃผ์ฐจ Phase 4 (synchronized), 10์ฃผ์ฐจ Phase 5
ํต์ฌ ๊ฐ๋
์ ๋ฝ์ด ํ์ํ๊ฐ:
2๊ฐ์ง ๋ฝ ์ข ๋ฅ โญ :
๊ณต์ ๋ฝ (Shared Lock, S Lock):
"์ฌ๋ฌ ํธ๋์ญ์ ์ด ๋์์ ์ฝ๊ธฐ OK, ์ฐ๊ธฐ๋ ์ฐจ๋จ"
SELECT ... LOCK IN SHARE MODE๋ฒ ํ ๋ฝ (Exclusive Lock, X Lock):
"ํ ํธ๋์ญ์ ๋ง ๋ฐ์ดํฐ ์ ๊ทผ, ๋ค๋ฅธ ํธ๋์ญ์ ์ ์ฝ๊ธฐ์กฐ์ฐจ ์ฐจ๋จ"
SELECT ... FOR UPDATEํธํ์ฑ ๋งคํธ๋ฆญ์ค:
| S Lock ์์ฒญ | X Lock ์์ฒญ | |
|---|---|---|
| S Lock ๋ณด์ ์ค | โ ํธํ | โ ๋๊ธฐ |
| X Lock ๋ณด์ ์ค | โ ๋๊ธฐ | โ ๋๊ธฐ |
JPA์์์ ํ์ฉ (์ฐธ๊ณ ):
@Lock(LockModeType.PESSIMISTIC_READ) // S Lock
@Lock(LockModeType.PESSIMISTIC_WRITE) // X Lock
๊ฒฉ๋ฆฌ ์์ค๊ณผ์ ๊ด๊ณ (10์ฃผ์ฐจ Phase 5):
ILIC ์๋๋ฆฌ์ค:
์๊ธฐ ์ ๊ฒ
๋ชฉํ: SQL์ด ์ด๋ป๊ฒ ์คํ ๊ณํ์ผ๋ก ๋ณํ๋๋์ง โ DB์ ๋๋๋ฅผ ์ดํดํ๋ค.
์ ์ ์ง์: Unit 5.1
ํต์ฌ ์ ์
์ตํฐ๋ง์ด์ (Optimizer):
"SQL์ ๊ฐ์ฅ ํจ์จ์ ์ธ ์คํ ๊ฒฝ๋ก๋ฅผ ์์ฑํ๋ DBMS์ ํต์ฌ ์์ง"
๋น์ :
"CPU๊ฐ ์ปดํจํฐ์ ๋๋๋ผ๋ฉด, ์ตํฐ๋ง์ด์ ๋ DB์ ๋๋"
๋์ ํ๋ฆ:
1. ๊ฐ๋ฐ์๊ฐ SQL ์์ฑ
2. ์ตํฐ๋ง์ด์ : "์ด ์ฟผ๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ์คํํ ๊น?"
3. ์ฌ๋ฌ ์คํ ๊ณํ ์์ฑ
4. ๊ฐ ๊ณํ์ ๋น์ฉ ์ฐ์
5. ์ต์ ๋น์ฉ ๊ณํ ์ ํ
6. SQL ์์ง์ด ์ค์ ์คํ
2๊ฐ์ง ์ตํฐ๋ง์ด์ ์ข ๋ฅ:
RBO (Rule-Based Optimizer) โ ๊ท์น ๊ธฐ๋ฐ:
CBO (Cost-Based Optimizer) โ ๋น์ฉ ๊ธฐ๋ฐ โญ :
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 7.1
ํต์ฌ 6๋จ๊ณ โญ :
[SQL ์
๋ ฅ]
โ
1. Parser โ SQL ๋ฌธ๋ฒ ๊ฒ์ฌ + ํ์ฑ ํธ๋ฆฌ ์์ฑ
โ
2. Query Transformer โ ์๋ธ์ฟผ๋ฆฌ โ JOIN, ๋ถํ์ ์กฐ๊ฑด ์ ๊ฑฐ
โ
3. Estimator โ ์คํ ๋น์ฉ ๊ณ์ฐ (ํต๊ณ ๊ธฐ๋ฐ)
โ
4. Plan Generator โ ์คํ ๊ณํ ํ๋ณด ์์ฑ + ์ต์ ์ ํ
โ
5. Row-Source Generator โ ์คํ ๊ฐ๋ฅํ ์ฝ๋๋ก ๋ณํ
โ
6. SQL Engine โ ์ค์ ์คํ
โ
[๊ฒฐ๊ณผ ๋ฐํ]
Step 2 ์์ โ ์ฟผ๋ฆฌ ๋ณํ:
-- ์
๋ ฅ
SELECT name FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'Seoul');
-- ์ตํฐ๋ง์ด์ ๊ฐ ๋ณํ
SELECT e.name FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE d.location = 'Seoul';
Step 3 โ Estimator์ ๊ณ ๋ ค ์์:
1. ์ธ๋ฑ์ค ์กด์ฌ ์ฌ๋ถ
2. ํ
์ด๋ธ ํฌ๊ธฐ
3. ์กฐ์ธ ๋ฐฉ์ (Nested Loop, Hash Join, Merge Join)
4. ์ ๋ ฌ ๋น์ฉ
ํต๊ณ ์ ๋ณด(Statistics):
๊ฐฑ์ ๋ฐฉ๋ฒ:
1. ์๋ ๊ฐฑ์ : DBMS ์ค์ผ์ค๋ฌ
2. ์๋ ๊ฐฑ์ : ๋๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ํ ์ฆ์
ANALYZE TABLE employees;
ํต๊ณ๊ฐ ์ค๋๋ ๊ฒฝ์ฐ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 7.2
์ตํฐ๋ง์ด์ ํํธ:
"SQL ์์ ์ฃผ์ ํํ๋ก ์ตํฐ๋ง์ด์ ๋์ ๊ฐ์ "
๋ฌธ๋ฒ (Oracle/MySQL ์ฐจ์ด ์์):
SELECT /*+ HINT_NAME(table_name) */ * FROM table_name;
์ฃผ์ ํํธ โญ :
| ํํธ | ์๋ฏธ |
|---|---|
/*+ FULL(t) */ | Full Table Scan ๊ฐ์ |
/*+ INDEX(t idx) */ | ํน์ ์ธ๋ฑ์ค ์ฌ์ฉ ๊ฐ์ |
/*+ ORDERED */ | FROM ์ ์์๋๋ก ์กฐ์ธ |
/*+ USE_HASH(t) */ | Hash Join ์ฌ์ฉ |
/*+ PARALLEL(t, 4) */ | ๋ณ๋ ฌ ์ฒ๋ฆฌ |
์์:
SELECT /*+ INDEX(emp idx_emp_name) */ *
FROM employees emp
WHERE name = 'John';
์ตํฐ๋ง์ด์ ๋ชจ๋:
"์ตํฐ๋ง์ด์ ์ ๊ธฐ๋ณธ ์ ์ฑ ์ค์ โ ์ ์ฒด ๋๋ ์ธ์ ๋จ์"
๋ชจ๋ ์ข ๋ฅ:
| ๋ชจ๋ | ์๋ฏธ |
|---|---|
| CHOOSE | ํต๊ณ ์์ผ๋ฉด CBO, ์์ผ๋ฉด RBO (๊ตฌ์) |
| FIRST_ROWS | ์ฒซ ๊ฒฐ๊ณผ ๋น ๋ฅด๊ฒ (์ธํฐ๋ํฐ๋ธ UI) |
| FIRST_ROWS(n) | ์ฒ์ n๊ฐ ํ ๋น ๋ฅด๊ฒ |
| ALL_ROWS | ์ ์ฒด ๊ฒฐ๊ณผ ๋น ๋ฅด๊ฒ (๋ฐฐ์น ์ฒ๋ฆฌ, Oracle 10g+ ๊ธฐ๋ณธ) |
ํํธ vs ๋ชจ๋:
ILIC ์ ์ฉ ๊ฐ๋ฅ:
์๊ธฐ ์ ๊ฒ
๋ชฉํ: DB ์ฑ๋ฅ์ ํต์ฌ์ธ ์ธ๋ฑ์ค๋ฅผ ๋น ์ค ํ๊ธฐ๋ฒ๋ถํฐ B-tree ๊ตฌ์กฐ๊น์ง ๊น์ด ์ดํดํ๋ค.
์ ์ ์ง์: ์๋ฃ๊ตฌ์กฐ ์ผ๋ฐ ์ง์
ํต์ฌ ๊ฐ๋
๋น ์ค ํ๊ธฐ๋ฒ:
"์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋ โ ์ ๋ ฅ ํฌ๊ธฐ N์ ๋ฐ๋ฅธ ์ฐ์ฐ ํ์"
์ฃผ์ ๋ณต์ก๋:
| ํ๊ธฐ | ์๋ฏธ | ์ |
|---|---|---|
| O(1) | ์์ โ ์ ๋ ฅ ๋ฌด๊ด | HashMap.get() |
| O(logN) | ๋ก๊ทธ โ ์ ๋ฐ์ฉ ์ค์ | ์ด์ง ํ์, B-tree |
| O(N) | ์ ํ โ ๋น๋ก | Full Scan |
| O(Nยฒ) | ์ ๊ณฑ โ ์ค์ฒฉ ๋ฐ๋ณต | Nested Loop |
logN์ ์ง๊ด:
์ซ์ ๋น๊ต (N = 100):
N = 1,000,000 (๋ฐฑ๋ง):
ํต์ฌ ํต์ฐฐ:
"ํฐ N์ผ์๋ก logN์ ์๋ ฅ์ด ํญ๋ฐ์ "
โ ์ธ๋ฑ์ค๊ฐ ๋ฐ์ดํฐ๊ฐ ๋ง์ ๋ ๋ ํจ๊ณผ์ ์ธ ์ด์ .
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 8.1
ํต์ฌ ๊ฐ๋
์ธ๋ฑ์ค(Index):
"๊ฒ์ ์ฑ๋ฅ์ ์ํ ์๋ฃ๊ตฌ์กฐ โ ์ฑ ์ ๋ชฉ์ฐจ ๊ฐ์ ์ญํ "
Full Scan vs Index:
์ธ๋ฑ์ค๊ฐ ์์ ๋:
SELECT * FROM users WHERE first_name = 'Minsoo';
-- โ 100๋ง ํ ์ ์ฒด ๋น๊ต (Full Scan)
์ธ๋ฑ์ค๊ฐ ์์ ๋:
CREATE INDEX idx_first_name ON users(first_name);
-- โ ์ธ๋ฑ์ค ํธ๋ฆฌ์์ ์ฝ 20๋ฒ ๋น๊ต โ ์ค์ ํ ์์น ํ์ธ
์ ์ธ๋ฑ์ค๋ฅผ ์ฐ๋๊ฐ (2๊ฐ์ง ์ด์ ):
1. WHERE ์กฐ๊ฑด ๋น ๋ฅธ ๊ฒ์
2. ์ ๋ ฌ(ORDER BY)/๊ทธ๋ฃนํ(GROUP BY) ๊ฐ์
์ธ๋ฑ์ค ์์ฑ ๋ฌธ๋ฒ:
์ผ๋ฐ ์ธ๋ฑ์ค:
CREATE INDEX player_name_idx ON player(name);
-- โ ์ธ๋ฑ์ค ์ด๋ฆ โ ์ปฌ๋ผ
์ ๋ํฌ ์ธ๋ฑ์ค (๋ฉํฐ ์ปฌ๋ผ = ๋ณตํฉ ์ธ๋ฑ์ค):
CREATE UNIQUE INDEX team_id_backnumber_idx
ON player (team_id, backnumber);
ํ ์ด๋ธ ์์ฑ ์:
CREATE TABLE player (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
INDEX idx_name (name)
);
Primary Key๋ ์๋ ์ธ๋ฑ์ค.
์ธ๋ฑ์ค ์ ๋ณด ํ์ธ:
SHOW INDEX FROM player;
Seq_in_index ์ปฌ๋ผ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 8.2
ํต์ฌ ๊ฐ๋
B-tree ์ธ๋ฑ์ค์ ๋ณธ์ง:
"์ ๋ ฌ๋ ๋ณ๋ ํ ์ด๋ธ + ํฌ์ธํฐ โ ์ด์ง ํ์์ผ๋ก O(logN)"
๊ตฌ์กฐ ์๊ฐํ:
[์๋ณธ ํ
์ด๋ธ] [์ธ๋ฑ์ค ํ
์ด๋ธ (์ ๋ ฌ๋จ)]
+----+----+----+ +----+----------+
| id | a | b | | a | pointer |
+----+----+----+ +----+----------+
| 1 | 5 | 80 | | 1 | โ row 7 |
| 2 | 3 | 60 | | 2 | โ row 9 |
| 3 | 8 | 95 | โCREATEโ | 3 | โ row 2 |
| 4 | 1 | 30 | INDEX(a) | 5 | โ row 1 |
| 5 | 9 | 70 | | 6 | โ row 8 |
| 6 | 2 | 40 | | 8 | โ row 3 |
| 7 | 1 | 20 | | 9 | โ row 5 |
+----+----+----+ +----+----------+
์กฐํ ํ๋ฆ (WHERE a = 9):
1. ์ธ๋ฑ์ค ํ
์ด๋ธ์์ ์ด์ง ํ์์ผ๋ก a=9 ์ฐพ๊ธฐ (O(logN))
2. ํฌ์ธํฐ ๋ฐ๋ผ ์๋ณธ ํ
์ด๋ธ row 5 ์ ๊ทผ
3. โ ํด๋น ํ ๋ฐํ
๋ฉํฐ์ปฌ๋ผ ์ธ๋ฑ์ค (Multi-column Index) โญ :
CREATE INDEX idx_a_b ON table(a, b);
์ ๋ ฌ ๊ธฐ์ค:
1. a ์ปฌ๋ผ ์ค๋ฆ์ฐจ์
2. a ๊ฐ์ ๊ฐ๋ค ์์์ b ์ค๋ฆ์ฐจ์
์์:
a | b
--+----
1 | 20 โ a ์ ๋ ฌ ํ
1 | 95
3 | 60
5 | 80
7 | 80
7 | 95 โ ๊ฐ์ a=7 ์์์ b๋ก ์ ๋ ฌ
8 | 95
9 | 70
ํจ์จ์ ์ฌ์ฉ โ WHERE a=7 AND b=95:
1. ์ธ๋ฑ์ค์์ a=7 ์์ญ ํ์ (์ด์ง)
2. ๊ทธ ์์์ b=95 ํ์ (์ด์ง โ ์ด๋ฏธ ์ ๋ ฌ๋จ)
3. โ ์์ ํ ํจ์จ์ ! โ
๋นํจ์จ ์ฌ์ฉ โ WHERE b=95:
๋นํจ์จ ์ฌ์ฉ โ WHERE a=7 OR c=400:
ํต์ฌ ์์น โญ :
"์ผ์ชฝ ์ปฌ๋ผ ์ฐ์ โ ๋ฉํฐ์ปฌ๋ผ ์ธ๋ฑ์ค๋ ์ผ์ชฝ๋ถํฐ ํ์ฉ ๊ฐ๋ฅํ ์ฟผ๋ฆฌ์๋ง ํจ๊ณผ"
ILIC ์ ์ฉ:
WHERE booking_date AND status ์์ฃผ โ INDEX(booking_date, status)WHERE status ๋ง ์์ฃผ โ INDEX(status) ๋ณ๋ ํ์์๊ธฐ ์ ๊ฒ
WHERE a > 5 ๋ ํจ๊ณผ์ ์ธ๊ฐ? (ํํธ: YES)WHERE a > 5 AND b = 80 ๋? (ํํธ: a๊น์ง๋ง โ b๋ ์ ๋ ฌ ์ ๋จ)๋ชฉํ: ์คํ ๊ณํ์ ์ง์ ๋ถ์ํ๊ณ ์ธ๋ฑ์ค ์ ํ์ ์ ์ดํ๋ค.
์ ์ ์ง์: Phase 8
ํต์ฌ ์๋๋ฆฌ์ค
ILIC player ํ
์ด๋ธ์ ์ฌ๋ฌ ์ธ๋ฑ์ค ์กด์ฌ:
(id) โ Primary Key ์๋(name)(team_id, backnumber)(backnumber)์ฟผ๋ฆฌ:
SELECT * FROM player WHERE backnumber = 7;
์๋ฌธ:
(team_id, backnumber) ์ (backnumber) ์ค ์ด๋ค ์ธ๋ฑ์ค ์ฌ์ฉ?๋ต: ์ตํฐ๋ง์ด์ ๊ฐ ๊ฒฐ์ โญ
์ผ๋ฐ์ ์ ํ:
(backnumber) ์ ํธํ์ธ ๋ฐฉ๋ฒ:
EXPLAIN SELECT * FROM player WHERE backnumber = 7;
โ key ์ปฌ๋ผ์ ์ฌ์ฉ๋ ์ธ๋ฑ์ค ํ์
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 9.1
ํต์ฌ ๊ฐ๋
EXPLAIN:
"SQL์ ์คํ ๊ณํ์ ๋ฏธ๋ฆฌ ๋ณด์ฌ์ฃผ๋ ๋ช ๋ น"
MySQL ์ถ๋ ฅ ์ฃผ์ ์ปฌ๋ผ:
| ์ปฌ๋ผ | ์๋ฏธ |
|---|---|
id | SELECT ์คํ ์์ |
select_type | SIMPLE, SUBQUERY, UNION ๋ฑ |
table | ๋์ ํ ์ด๋ธ |
type | ์ ๊ทผ ๋ฐฉ์ (๊ฐ์ฅ ์ค์!) |
possible_keys | ์ฌ์ฉ ๊ฐ๋ฅํ ์ธ๋ฑ์ค๋ค |
key | ์ค์ ์ฌ์ฉ๋ ์ธ๋ฑ์ค |
key_len | ์ธ๋ฑ์ค ์ฌ์ฉ ๊ธธ์ด |
ref | ๋น๊ต ๋์ |
rows | ๊ฒ์ฌ ์์ ํ ์ |
Extra | ์ถ๊ฐ ์ ๋ณด (Using index, filesort ๋ฑ) |
type ์ปฌ๋ผ โ ๊ฐ์ฅ ์ค์ โญ :
์ข์ ์ โ ๋์ ์:
| type | ์๋ฏธ | ํ๊ฐ |
|---|---|---|
const | PK/UNIQUE๋ก 1ํ | โญโญโญ |
eq_ref | UNIQUE JOIN | โญโญโญ |
ref | ์ธ๋ฑ์ค ๋น์ ๋ํฌ ์ผ์น | โญโญ |
range | ์ธ๋ฑ์ค ๋ฒ์ ๊ฒ์ | โญโญ |
index | ์ธ๋ฑ์ค ํ ์ค์บ | โญ |
ALL | ํ ์ด๋ธ ํ ์ค์บ โ | ์ํ |
Extra ์ปฌ๋ผ ์ฃผ์ ๊ฐ:
Using index โ Covering Index (Phase 10)Using where โ WHERE ์กฐ๊ฑด ์ ์ฉUsing filesort โ ๋ณ๋ ์ ๋ ฌ (์ฑ๋ฅ โ)Using temporary โ ์์ ํ
์ด๋ธ (์ฑ๋ฅ โ)ILIC ํ์ฉ:
EXPLAIN SELECT * FROM bookings WHERE customer_id = ?;
-- type = ref โ ์ธ๋ฑ์ค ์ฌ์ฉ โ
-- type = ALL โ Full Scan โ โ ์ธ๋ฑ์ค ์ถ๊ฐ ๊ฒํ
์๊ธฐ ์ ๊ฒ
Using filesort๊ฐ ๋ณด์ด๋ฉด ์ด๋ป๊ฒ ํด๊ฒฐ? (ํํธ: ORDER BY ์ปฌ๋ผ์ ์ธ๋ฑ์ค)type = ALL ์ด์ง๋ง ๋ฐ์ดํฐ๊ฐ ์ ์ด ๋น ๋ฅธ ๊ฒฝ์ฐ๋? (ํํธ: ์นด๋๋๋ฆฌํฐ ๋ฎ์)์ ์ ์ง์: Unit 9.2, 7.3
ํต์ฌ ๊ฐ๋
์ ์ธ๋ฑ์ค ํํธ?:
3๊ฐ์ง ํํธ โญ :
1. USE INDEX โ ์ฌ์ฉ ์ ๋ (๋์จ):
SELECT * FROM player USE INDEX (backnumber_idx)
WHERE backnumber = 7;
2. FORCE INDEX โ ๊ฐ์ ์ฌ์ฉ (๊ฐํจ) โญ :
SELECT * FROM player FORCE INDEX (backnumber_idx)
WHERE backnumber = 7;
3. IGNORE INDEX โ ๋ฌด์ ๊ฐ์ :
SELECT * FROM employees IGNORE INDEX (idx_emp_name)
WHERE name = 'John';
์ธ์ ์ฌ์ฉํ๋๊ฐ:
โ ๏ธ ๋จ์ฉ ์ฃผ์:
์ตํฐ๋ง์ด์ ํํธ vs ์ธ๋ฑ์ค ํํธ (๋น๊ต):
| ์ตํฐ๋ง์ด์ ํํธ | ์ธ๋ฑ์ค ํํธ | |
|---|---|---|
| ๋ฒ์ | ์คํ ๊ณํ ์ ์ฒด | ์ธ๋ฑ์ค ์ฌ์ฉ๋ง |
| ์ | /*+ ORDERED */ | FORCE INDEX (...) |
| ๊ฐ์ ๋ ฅ | ์ตํฐ๋ง์ด์ ๊ฐ ๋ฌด์ ๊ฐ๋ฅ | FORCE๋ ๊ฐ์ |
| ํ๊ธฐ | ์ฃผ์ (/*+ ... */) | ํค์๋ (USE/FORCE/IGNORE) |
ILIC ํ์ฉ:
์๊ธฐ ์ ๊ฒ
๋ชฉํ: ์ค๋ฌด ์ธ๋ฑ์ค ์ค๊ณ์ ๋ฒ ์คํธ ํ๋ํฐ์ค โ ๋ฌด์์ ํ ๊น, ๋ฌด์์ ํผํ ๊น.
์ ์ ์ง์: Phase 9
ํต์ฌ ๊ฐ๋
Covering Index:
"์ฟผ๋ฆฌ๊ฐ ํ์ํ ๋ชจ๋ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๊ฐ ํฌํจํ๋ ๊ฒฝ์ฐ"
์์:
์ธ๋ฑ์ค: (team_id, backnumber)
SELECT team_id, backnumber FROM player WHERE team_id = 1;
โ ์กฐํ ์ปฌ๋ผ(team_id, backnumber) ๋ชจ๋ ์ธ๋ฑ์ค์ ํฌํจ
โ ์ค์ ํ
์ด๋ธ ์ ๊ทผ ๋ถํ์ โญ
โ ์ธ๋ฑ์ค๋ง์ผ๋ก ๊ฒฐ๊ณผ ๋ฐํ = Covering Index
์ฅ์ :
EXPLAIN ๊ฒฐ๊ณผ:
Extra ์ปฌ๋ผ์ Using index ํ์Non-Covering ์ฌ๋ก:
SELECT * FROM player WHERE team_id = 1;
-- '*' = ๋ชจ๋ ์ปฌ๋ผ โ ์ธ๋ฑ์ค ์ธ ์ปฌ๋ผ๋ ํ์ โ ํ
์ด๋ธ ์ ๊ทผ
Covering ๋ง๋ค๊ธฐ โ ์ธ๋ฑ์ค ํ์ฅ:
-- ์์ฃผ SELECT name๋ ํ๋ค๋ฉด
CREATE INDEX idx_team_back_name ON player(team_id, backnumber, name);
ILIC ํ์ฉ:
(status, created_date, fare_id) ์ธ๋ฑ์คโ ๏ธ ์ฃผ์:
์๊ธฐ ์ ๊ฒ
SELECT * ๊ฐ Covering Index๋ฅผ ๊นจ๋ ์ด์ ๋?์ ์ ์ง์: Unit 10.1
ํต์ฌ ๊ฐ๋
Full Scan์ด ๋ ์ข์ ๊ฒฝ์ฐ:
๋ฐ์ดํฐ๊ฐ ์ ์ ํ ์ด๋ธ (๋ช์ญ~๋ช๋ฐฑ ๊ฑด)
์กฐํ ๋ฐ์ดํฐ๊ฐ ํ ์ด๋ธ์ ํฐ ๋น์จ (์: 30% ์ด์)
์นด๋๋๋ฆฌํฐ ๋งค์ฐ ๋ฎ์
์ตํฐ๋ง์ด์ ์ ํ๋จ:
์ธ๋ฑ์ค์ ๋น์ฉ โญ :
1. WRITE ์ ๋ชจ๋ ์ธ๋ฑ์ค ๊ฐฑ์ :
2. ์ถ๊ฐ ์ ์ฅ ๊ณต๊ฐ:
3. ์ธ๋ฑ์ค ์ ๋ ฌ ๋น์ฉ:
์์น โญ :
"ํ์ํ ๋งํผ๋ง, ์ต์ํ์ ์ธ๋ฑ์ค"
์ค๋ณต ์ธ๋ฑ์ค ํผํ๊ธฐ:
(team_id, backnumber) ์์ผ๋ฉด (team_id) ๋ถํ์๋์ฉ๋ ํ ์ด๋ธ ์ธ๋ฑ์ค ์ถ๊ฐ ์ฃผ์ โญ :
ALGORITHM=INPLACE MySQL 5.6+)ILIC ์๋๋ฆฌ์ค:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Phase 9, 10
์ต์ข ๋น๊ต ๋งคํธ๋ฆญ์ค โญ :
| ์ธก๋ฉด | ์ตํฐ๋ง์ด์ ํํธ | ์ธ๋ฑ์ค ํํธ |
|---|---|---|
| ๋ฒ์ | ์ ์ฒด ์คํ ๊ณํ (์กฐ์ธ ์์, ๋ณ๋ ฌ ๋ฑ) | ์ธ๋ฑ์ค ์ฌ์ฉ๋ง |
| ํ๊ธฐ | /*+ ORDERED */ (์ฃผ์) | FORCE INDEX (idx) (ํค์๋) |
| ๊ฐ์ ๋ ฅ | ์ตํฐ๋ง์ด์ ๊ฐ ๋ฌด์ ๊ฐ๋ฅ | FORCE๋ ๊ฑฐ์ ์ ๋ |
| ํ์คํ | DBMS๋ง๋ค ๋ค๋ฆ | DBMS๋ง๋ค ๋ค๋ฆ |
| Oracle | ๋งค์ฐ ๋ค์ | ์ ์ |
| MySQL | ์ ์ | ํ๋ถ (USE/FORCE/IGNORE) |
ํํธ ์ฌ์ฉ ๊ฐ์ด๋๋ผ์ธ:
์ค๋ฌด ๊ถ์ฅ ํ๋ฆ:
[์ฑ๋ฅ ์ด์] โ ANALYZE TABLE โ EXPLAIN โ ์ธ๋ฑ์ค ์ถ๊ฐ โ ํํธ
(1์์) (๋ถ์) (2์์) (๋ง์ง๋ง)
ILIC ์ ์ฉ:
์๊ธฐ ์ ๊ฒ
WHERE b=... ๊ฐ ๋นํจ์จ์ ์ธ ์ด์ ๋?type ์ปฌ๋ผ์์ ์ข์ ๊ฐ๊ณผ ๋์ ๊ฐ์?Extra ์ปฌ๋ผ์ Using filesort ๊ฐ ์๋ฏธํ๋ ๋ฐ์ ํด๊ฒฐ์ฑ
์?โ โ โ ๋ฉด์ ยท์ค๋ฌด ๋จ๊ณจ (๋ฐ๋์):
โ โ ๋งค์ฐ ๊ถ์ฅ:
[ Part A โ DB ์ด๋ก ๊ณผ ๊ด๋ฆฌ ]
[ ] Phase 1 โ DB ํต์ฌ ์ฉ์ด์ ๋ชจ๋ธ๋ง (Unit 1.1~1.3)
[ ] Phase 2 โ ์ ๊ทํ (Unit 2.1~2.4)
[ ] Phase 3 โ ์ด์ ํ์๊ณผ ์ ๊ทํ ํ๊ฐ (Unit 3.1~3.2)
[ ] Phase 4 โ SQL Injection ๋ณด์ (Unit 4.1~4.2)
[ ] Phase 5 โ RDBMS์ NoSQL (Unit 5.1~5.4)
[ ] Phase 6 โ ๋ถ์ฐ ์์คํ
์ด๋ก + ๋ฝ (Unit 6.1~6.4)
[ Part B โ SQL ์ฑ๋ฅ ์ต์ ํ ]
[ ] Phase 7 โ ์ตํฐ๋ง์ด์ (Unit 7.1~7.3)
[ ] Phase 8 โ ์ธ๋ฑ์ค ๊ธฐ์ด (Unit 8.1~8.3) โ
์ ์
[ ] Phase 9 โ ๋ฉํฐ์ปฌ๋ผ ์ธ๋ฑ์ค์ EXPLAIN (Unit 9.1~9.3)
[ ] Phase 10 โ ์ธ๋ฑ์ค ์ต์ ํ ์ ๋ต (Unit 10.1~10.3)
[ ] ์ข
ํฉ ์๊ธฐ ์ ๊ฒ 38๋ฌธํญ ํต๊ณผ
์ ์ ์ ์ธ๊ฐ:
ํ์ต ์ ๊ฐ์กฐ์ :
12์ฃผ์ฐจ๊น์ง๊ฐ ์๋ฐยทSpringยทJPA์ ์์ชฝ ์ถ์ํ ์๋ค๋ฉด, 13์ฃผ์ฐจ๋ DB ์์ฒด์ ๊น์ด ๋ก ๋ด๋ ค๊ฐ๋ค.
| ์์ญ | ์ฃผ์ฐจ | ์ถ์ํ ์์ค |
|---|---|---|
| ์๋ฐ ์ธ์ด | 1~3์ฃผ์ฐจ | ๊ฐ์ฅ ๋์ |
| ๋์์ฑยทSpring | 4~5์ฃผ์ฐจ | ๋์ |
| Spring DB ์ ๊ทผ | 6~7์ฃผ์ฐจ | ์ค์ |
| AOPยทํธ๋์ญ์ | 8~10์ฃผ์ฐจ | ์ค์ |
| JPAยท์์์ฑ ์ปจํ ์คํธ | 11~12์ฃผ์ฐจ | ์ค |
| DB ํ๋๋ฉํธ | 13์ฃผ์ฐจ (์ง๊ธ) | ๊ฐ์ฅ ๋ฎ์ (DB ์์ฒด) |
์์:
์ด๋ฒ ์ฃผ์ฐจ๋ ์ด๋ก ๋ง ์ฝ์ผ๋ฉด ์ ๋ ์ฒดํ๋์ง ์์ต๋๋ค:
ํนํ Phase 8 (B-tree) ์ Phase 9 (EXPLAIN) ์ ILIC ์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์:
EXPLAIN SELECT * FROM bookings WHERE customer_id = ? AND status = ?;
EXPLAIN ANALYZE ... -- ์ค์ ์๊ฐ ์ธก์ (PostgreSQL/MySQL 8.0+)
์ด๋ฐ ์์ผ๋ก ์ง์ ๊ฒ์ฆํ์ธ์. 1~2์๊ฐ EXPLAIN ๋ค์ํ ์ฟผ๋ฆฌ์ ๋๋ ค๋ณด๋ฉด ์ธ๋ฑ์ค ๊ฐ๊ฐ์ด ํญ๋ฐ์ ์ผ๋ก ๋์ด๋ฉ๋๋ค.