09. ìžë±ì±
09. ìžë±ì±¶
ìŽì : ì§ì ì²ëЬì ìµì í | ë€ì: ížëìì ìŽë¡
íìµ ëª©í¶
- ìžë±ì±ìŽ ë°ìŽí°ë² ìŽì€ ì±ë¥ì ì€ìí ìŽì ìŽíŽ
- ì ë ¬ë ìžë±ì€(Ordered Indices) 구ë¶: 죌 ìžë±ì€(Primary), íŽë¬ì€í°ë§(Clustering), 볎조 ìžë±ì€(Secondary)
- B-Treeì B+Tree 구조, ì°ì° ë° ë³µì¡ë ë§ì€í°
- íŽì êž°ë° ìžë±ì± êž°ë²: ì ì (Static), íì¥ê°ë¥(Extendible), ì í íŽì±(Linear Hashing)
- ë¹ížë§µ ìžë±ì€(Bitmap Indices)ì ë€ì°šì ìžë±ì€ 구조 ìŽíŽ
- ì€ë¬Žìì ìžë±ì€ ì€ê³ ì§ì¹š ì ì©
1. ìžë±ì±ìŽ ì€ìí ìŽì ¶
Ʞ볞 ë¬žì ¶
100ë§ ê°ì íì ê°ì§ employees í
ìŽëžìŽ ëì€í¬ì ì ì¥ëìŽ ìë€ê³ ê°ì íì. ê° ëì€í¬ ëžë¡ì 10ê°ì íì ëŽìŒë¯ë¡, í
ìŽëžì 10ë§ ê°ì ëžë¡ì ì°šì§íë€. IDë¡ ì§ì í ëª
ì ì°ŸìŒë €ë©Ž:
ìžë±ì€ ììŽ: 몚ë 10ë§ ê° ëžë¡ ì€ìº â O(n) ëì€í¬ I/O
ìžë±ì€ ì¬ì©: ìžë±ì€ í¬ìží° ë°ëŒê°êž° â O(log n) ëì€í¬ I/O
10ë§ ëžë¡ì 겜ì°: - ìì°š ì€ìº: ìµë 10ë§ ë²ì ëžë¡ ìœêž° - B+Tree ìžë±ì€ (ë¶êž° ê³ì 200): ëëµ log_200(1,000,000) â 3 ëžë¡ ìœêž°
ìŽë 33,000ë°°ì I/O ë¹ì© ê°ì ìŽë€.
ìì°š vs. ìžë±ì€ ì ê·Œ¶
ìì°š ì ê·Œ (í
ìŽëž ì€ìº):
ââââââââ¬âââââââ¬âââââââ¬âââââââ¬âââââââ¬âââââââ¬âââââââ
â Blk1 â Blk2 â Blk3 â Blk4 â Blk5 â ... â BlkN â
ââââââââŽâââââââŽâââââââŽâââââââŽâââââââŽâââââââŽâââââââ
â 몚ë ëžë¡ì ìì°šì ìŒë¡ ìœì
ìžë±ì€ ì ê·Œ:
âââââââââââââââââââ
â ìžë±ì€ ë£šíž â â 1 I/O
â [50â100â150] â
ââââ¬âââââââ¬âââââââ¬ââ
â â â
ââââââ ââââââ ââââââ
â늬íâ â늬íâ â늬íâ â 1 I/O (í¬ìží° ë°ëŒê°êž°)
ââââ¬ââ ââââââ ââââââ
â
ââââââââ
â ë°ìŽí°â â 1 I/O (ì€ì ë ìœë ê°ì žì€êž°)
â ëžë¡ â
ââââââââ
ìžë±ì€ë¥Œ ì¬ì©íì§ ìììŒ í ë¶
ìžë±ì€ê° íì ì ìµí ê²ì ìëë€:
- ìì í ìŽëž: ëª ê°ì ëžë¡ì ìì°š ì€ìºíë ê²ìŽ ìžë±ì€ íì ì€ë²í€ëë³Žë€ ë¹ ëŠ
- ëì ì íë 쿌늬(High Selectivity Queries): ì¿ŒëŠ¬ê° ëë¶ë¶ì í(ì: í ìŽëžì 15-20% ìŽì)ì ë°íí멎, ì 첎 ì€ìºìŽ ë ì ë Žíš
- ë¹ë²í ì°êž°: 몚ë INSERT, UPDATE, DELETEë ìžë±ì€ë ì ë°ìŽížíŽìŒ íš
- ë®ì 칎ëëëŠ¬í° ì»¬ëŒ: B+Treeë¡ ë¶ëа 컬ëŒì ìžë±ì±íë ê²ì ëë¹ì (ë¹ížë§µ ìžë±ì€ê° ì ì í ì ìì)
ë¹ì© ëªšëž êž°ìŽ¶
ëì€í¬ ì ê·Œ ë¹ì©ìŽ ì¿ŒëŠ¬ ì±ë¥ì ì§ë°°íë€. ëžë¡ ì ì¡(Block Transfers) (ëì€í¬ ëžë¡ ìœêž°/ì°êž°)곌 íì(Seeks) (ëì€í¬ í€ë ìŽë) ëšìë¡ ìž¡ì íë€.
ë€ì곌 ê°ìŽ ì ìíì:
- b = íìŒì ëžë¡ ì
- n = ë ìœë ì
- f = ëžë¡í¹ í©í°(Blocking Factor) (ëžë¡ë¹ ë ìœë ì), ë°ëŒì b = ân/fâ
| ì ê·Œ ë°©ë² | íê· ë¹ì© (ëë± ê²ì) |
|---|---|
| ì í ì€ìº (믞ì ë ¬) | b/2 ëžë¡ ì ì¡ |
| ì í ì€ìº (ì ë ¬) | âlogâ(b)â (ìŽì§ ê²ì) |
| 죌 ìžë±ì€ (ì ë ¬) | âlogâ(b_i)â + 1, ì¬êž°ì b_i = ìžë±ì€ ëžë¡ |
| B+Tree | âlog_p(b)â + 1, ì¬êž°ì p = ë¶êž° ê³ì |
| íŽì ìžë±ì€ | 1 (ìŽìì ) ~ 2 (ì€ë²íë¡ì° í¬íš) |
2. ì ë ¬ë ìžë±ì€¶
ìžë±ì€ 구조 Ʞ볞¶
ìžë±ì€(Index)ë ê²ì í€ ê°(Search Key Values)ì í¬ìží°(Pointers) (ë ìœë ìë³ì ëë ëžë¡ 죌ì)ì ë§€ííë ë°ìŽí° 구조ë€. ê²ì í€ë ë°ëì Ʞ볞 í€ìŒ íìë ìë€ -- ìŽë€ ìì±ìŽë ìì± ì§í©ìŽë ê²ì í€ë¡ ì¬ì©ë ì ìë€.
ìžë±ì€ ìížëЬ íì:
âââââââââââââââ¬ââââââââââââââ
â ê²ì í€ ê° â ë ìœë â
â â í¬ìží° â
âââââââââââââââŽââââââââââââââ
2.1 죌 ìžë±ì€¶
죌 ìžë±ì€(Primary Index)ë ìì°šì ìŒë¡ ì ë ¬ë íìŒì ì ë ¬ í€(Ordering Key)ì 구ì¶ëë€. íìŒì ìžë±ì±ë ìì±ìŒë¡ 묌늬ì ìŒë¡ ì ë ¬ëë€.
ì§ì IDì ëí 죌 ìžë±ì€ (íìŒìŽ IDë¡ ì ë ¬ëš):
ìžë±ì€: ë°ìŽí° íìŒ:
âââââââ¬âââââââ âââââââââââââââââââââ
â 100 â âââââââââââââââââââ â 100 â Alice â ... â ëžë¡ 1
âââââââŒââââââ†â 105 â Bob â ... â
â 200 â âââââââ âââââââââââââââââââââ€
âââââââŒââââââ†âââââââââââââ â 200 â Carol â ... â ëžë¡ 2
â 300 â âââââââ â 210 â Dave â ... â
âââââââŽâââââââ â âââââââââââââââââââââ€
âââââââââââââ â 300 â Eve â ... â ëžë¡ 3
â 350 â Frank â ... â
âââââââââââââââââââââ
í¹ì±: - ëžë¡ë¹ íëì ìžë±ì€ ìížëЬ (ë ìœëë¹ìŽ ìë) -- ìŽê²ì í¬ì ìžë±ì€(Sparse Index) - ê²ì í€ë íìŒìŽ ì ë ¬ë ê²ê³Œ ëìŒí ìì± - ëë± ê²ì곌 ë²ì 쿌늬ì ë§€ì° íšìšì - í ìŽëžë¹ íëì 죌 ìžë±ì€ë§ ì¡Žì¬ (íìŒì í ê°ì§ ë°©ë²ìŒë¡ë§ ì ë ¬ ê°ë¥)
2.2 íŽë¬ì€í°ë§ ìžë±ì€¶
íŽë¬ì€í°ë§ ìžë±ì€(Clustering Index)ë íìŒìŽ ë¬ŒëŠ¬ì ìŒë¡ ì ë ¬ë ë¹-í€ ìì±ì 구ì¶ëë€. ì¬ë¬ ë ìœëê° ëìŒí ê²ì í€ ê°ì ê³µì í ì ìë€.
ë¶ìì ëí íŽë¬ì€í°ë§ ìžë±ì€:
ìžë±ì€: ë°ìŽí° íìŒ (ë¶ìë¡ ì ë ¬):
ââââââââââââ¬âââââââ âââââââââââââââââââââââââââââ
â Acctg â âââââââââââââââ â Acctg â Alice â 60000 â
ââââââââââââŒââââââ†â Acctg â Bob â 55000 â
â Eng â âââââââ âââââââââââââââââââââââââââââ€
ââââââââââââŒââââââ†ââââââââ â Eng â Carol â 80000 â
â Sales â âââââââ â Eng â Dave â 75000 â
ââââââââââââŽâââââââ â â Eng â Eve â 72000 â
â âââââââââââââââââââââââââââââ€
âââââââ â Sales â Frank â 50000 â
â Sales â Grace â 52000 â
âââââââââââââââââââââââââââââ
í¹ì±: - ê²ì í€ì ê³ ì ê°ë¹ íëì ìžë±ì€ ìížëЬ - ê° í¬ìží°ë íŽë¹ ê°ì í¬íšíë 첫 ë²ì§ž ëžë¡ìŒë¡ ìŽìŽì§ - 귞룹í ë° ì§ê³ 쿌늬ì íšìšì
2.3 볎조 ìžë±ì€¶
볎조 ìžë±ì€(Secondary Index)ë ë¹-ì ë ¬ ìì±ì ëí ë첎 ì ê·Œ 겜ë¡ë¥Œ ì ê³µíë€. íìŒì ìŽ ìì±ìŒë¡ ì ë ¬ëìŽ ìì§ ìë€.
êžì¬ì ëí 볎조 ìžë±ì€:
ìžë±ì€ (êžì¬ë¡ ì ë ¬): ë°ìŽí° íìŒ (IDë¡ ì ë ¬, êžì¬ë¡ë ì ë ¬ ì ëš):
âââââââââ¬âââââââ âââââââââââââââââââââââââââââ
â 50000 â âââââââââââââââââââ â 100 â Alice â 60000 â ëžë¡ 1
âââââââââŒââââââ†â 105 â Bob â 50000 â
â 55000 â âââââââ âââââââââââââââââââââââââââââ€
âââââââââŒââââââ†â â 200 â Carol â 80000 â ëžë¡ 2
â 60000 â ââââââââ â 210 â Dave â 55000 â
âââââââââŒââââââ†ââ âââââââââââââââââââââââââââââ€
â 72000 â âââ ââ â 300 â Eve â 72000 â ëžë¡ 3
â ... â â ââ â 350 â Frank â 75000 â
âââââââââŽâââââ ââ âââââââââââââââââââââââââââââ
âââ (í¬ìží°ê° ëžë¡ 겜ê³ë¥Œ ëì)
í¹ì±: - ë°ì§ ìžë±ì€(Dense Index)ì¬ìŒ íš (ë ìœëë¹ íëì ìížëЬ, ëžë¡ë¹ìŽ ìë) - ë°ìŽí°ê° ê²ì í€ë¡ ì ë ¬ëìŽ ìì§ ìêž° ë묞 - ëìŒí í ìŽëžì ì¬ë¬ 볎조 ìžë±ì€ê° 졎ì¬í ì ìì - ë²ì 쿌늬ì ë íšìšì (ë¹ìì°š ë°ìŽí°ë¡ ìží ëë€ I/O íšíŽ) - ì€ë³µ í€ ê°ì ëíŽ ì¶ê° ê°ì ìì€(í¬ìží° ë²í·)ìŽ ì¬ì©ëêž°ë íš
ë°ì§ vs. í¬ì ìžë±ì€¶
ë°ì§ ìžë±ì€(Dense Index): ë°ìŽí° íìŒì 몚ë ë ìœëì ëíŽ íëì ìžë±ì€ ìížëЬ.
ë°ì§ ìžë±ì€:
âââââââ¬ââââ ââââââââââââââââ
â 100 â âââŒââââ â 100 â Alice â
âââââââŒâââ†â 105 â Bob â âââ 105ì ëí ìížëЬ 졎ì¬
â 105 â âââŒââââ â â
âââââââŒâââ†ââââââââââââââââ€
â 200 â âââŒââââ â 200 â Carol â
âââââââŒâââ†â 210 â Dave â
â 210 â âââŒââââ â â
âââââââŽââââ ââââââââââââââââ
í¬ì ìžë±ì€(Sparse Index): ìŒë¶ ë ìœëì ëí íëì ìžë±ì€ ìížëЬ (ìŒë°ì ìŒë¡ ëžë¡ë¹ íë).
í¬ì ìžë±ì€:
âââââââ¬ââââ ââââââââââââââââ
â 100 â âââŒââââ â 100 â Alice â ëžë¡ 1
â â â â 105 â Bob â (105ì ëí ìížëЬ ìì)
âââââââŒâââ†ââââââââââââââââ€
â 200 â âââŒââââ â 200 â Carol â ëžë¡ 2
â â â â 210 â Dave â (210ì ëí ìížëЬ ìì)
âââââââŽââââ ââââââââââââââââ
ë¹êµ:
| 잡멎 | ë°ì§ ìžë±ì€ | í¬ì ìžë±ì€ |
|---|---|---|
| ê³µê° | ë íŒ (ë ìœëë¹ ìížëЬ) | ë ìì (ëžë¡ë¹ ìížëЬ) |
| ê²ì | ì§ì ì¡°í ê°ë¥ | ëžë¡ ëŽ ì€ìº íìí ì ìì |
| ì구ì¬í | 믞ì ë ¬ íìŒìì ìë | ì ë ¬ë ë°ìŽí° íìŒ íì |
| ì ì§ë³Žì | ìœì /ìì ì ë ë§ì ì ë°ìŽíž | ë ì ì ì ë°ìŽíž |
| ì¬ì© ì¬ë¡ | 볎조 ìžë±ì€ | 죌 ìžë±ì€ |
ë€ëšê³ ìžë±ì€¶
ìžë±ì€ ìì²Žê° ë©ëªšëЬì ë§ì§ ìì ì ëë¡ í¬ë©Ž, ìžë±ì€ì ëí ìžë±ì€ë¥Œ 구ì¶í ì ìë€:
ë 벚 2 (ìžë¶ ìžë±ì€):
ââââââââ¬ââââ
â 1 â âââŒââââ ââââââââ¬ââââ
â 500 â âââŒââ â 1 â âââŒââââ ë°ìŽí° ëžë¡ 1
ââââââââŽââââ â â 100 â âââŒââââ ë°ìŽí° ëžë¡ 2
â â 200 â âââŒââââ ë°ìŽí° ëžë¡ 3
â â ... â â
â ââââââââŽââââ
â ë 벚 1 (ëŽë¶ ìžë±ì€, ííž 1)
â
ââ ââââââââ¬ââââ
â 500 â âââŒââââ ë°ìŽí° ëžë¡ K
â 600 â âââŒââââ ë°ìŽí° ëžë¡ K+1
â ... â â
ââââââââŽââââ
ë 벚 1 (ëŽë¶ ìžë±ì€, ííž 2)
ìŽë ìì°ì€ëœê² ížëЬ 구조 ìžë±ì€, í¹í B-Treeì B+Treeë¡ ìŽìŽì§ë€.
3. B-Tree¶
3.1 구조¶
ì°šì mì B-Tree (ëë degree mì B-Tree)ë ë€ìì ë§ì¡±íë€:
- 몚ë ë
žëë ìµë
mê°ì ììì ê°ì§ - 몚ë ëŽë¶ ë
žë(ë£šíž ì ìž)ë ìµì
âm/2âê°ì ììì ê°ì§ - 룚ížë ìµì 2ê°ì ììì ê°ì§ (늬íê° ìë 겜ì°)
- 몚ë 늬íë ëìŒí ë 벚ì ëíëš
kê°ì ììì ê°ì§ ë¹-늬í ë žëëk-1ê°ì í€ë¥Œ í¬íš
ì°šì 4ì B-Tree (ê° ë
žëë ìµë 3ê°ì í€ ë³Žì ):
âââââââââââ
â 30 â
ââââ¬ââââ¬âââ
ââââââ ââââââ
ââââââââŽâââ ââââââŽâââââââ
â 10 â 20 â â 40 â 50 â
ââ¬ââââ¬ââââ¬â ââ¬ââââ¬âââââ¬ââ
â â â â â â
ââââââââââââ ââââââââ âââââ
â5 ââ15ââ25â â35ââ45â â55 â
â8 ââ ââ â â ââ â â60 â
ââââââââââââ ââââââââ âââââ
ì°žê³ : B-Treeììë (B+Treeì ë¬ëЬ) ë°ìŽí° í¬ìží°ê°
몚ë ë
žëì 졎ì¬íë©°, 늬íë§ìŽ ìë.
ë
žë 구조 (nê°ì í€ë¥Œ ê°ì§ ëŽë¶ ë
žë):
ââââââ¬ââââââ¬âââââ¬ââââââ¬âââââ¬ââââââ¬âââââ
â Pâ â Kâ â Pâ â Kâ â Pâ â ... â Pââââ
â â Dâ â â Dâ â â â â
ââââââŽââââââŽâââââŽââââââŽâââââŽââââââŽâââââ
â â â â
ë¶ížëЬ ë¶ížëЬ ë¶ížëЬ ë¶ížëЬ
< Kâ [Kâ,Kâ) [Kâ,Kâ) ⥠Kâ
ì¬êž°ì:
Páµ¢ = ìì ë
žëì ëí í¬ìží° (ëë 늬íì ê²œì° ë°ìŽí° ëžë¡)
Káµ¢ = ê²ì í€ ê°
Dáµ¢ = í€ Kᵢ륌 ê°ì§ ë°ìŽí° ë ìœëì ëí í¬ìží°
3.2 ê²ì¶
í€ Kì ëí B-Tree ê²ì:
BTREE-SEARCH(node, K):
i = 1
while i †node.n and K > node.key[i]:
i = i + 1
if i †node.n and K == node.key[i]:
return (node, i) // ìŽ ë
žëìì ë°ê²¬
if node is a leaf:
return NOT_FOUND
// ëì€í¬ìì ìì ìœêž°
DISK-READ(node.child[i])
return BTREE-SEARCH(node.child[i], K)
ë³µì¡ë: O(log_m n) ëì€í¬ I/O, ì¬êž°ì nì í€ì ììŽê³ mì ì°šì.
3.3 ìœì ¶
ì°šì mì B-Treeì í€ K ìœì
:
- ì°Ÿêž°: ê²ìì ì¬ì©íì¬ ì ì í 늬í ë žë ì°Ÿêž°
- ìœì : 늬í ëŽì ì ë ¬ë ììë¡ í€ ìœì
- ë
žëê° ì€ë²íë¡ì°í멎 (
mê°ì í€ë¥Œ ê°ì§): - ì€ê° í€ìì ë žë륌 ë ë žëë¡ ë¶í
- ì€ê° í€ë¥Œ ë¶ëªšë¡ ì¹ê²©
- íìì ë¶ëªš ì€ë²íë¡ì°ë¥Œ ì¬ê·ì ìŒë¡ ì²ëЬ
ì: ì°šì 3ì B-Treeì 25 ìœì (ë žëë¹ ìµë 2ê°ì í€):
ìŽì :
ââââââ
â 20 â
âââ¬âââ
ââââââŽââââââ
âââââââ ââââââââ
â10â15â â22â30 â â ë
žëê° êœ ì°ž
âââââââ ââââââââ
ëšê³ 1: í€ 25ë ì€ë¥žìªœ 늬í [22, 30]ì ìíš.
ëšê³ 2: ìœì
â [22, 25, 30] â ì€ë²íë¡ì°! (3ê°ì í€ > ìµë 2)
ëšê³ 3: ì€ê°ê°(25)ìì ë¶í . 25륌 ë¶ëªšë¡ ì¹ê²©.
ìŽí:
ââââââââ
â20â25 â
ââ¬âââ¬âââ
ââââââ â ââââââ
âââââââ ââââ ââââ
â10â15â â22â â30â
âââââââ ââââ ââââ
3.4 ìì ¶
ì°šì mì B-Treeìì í€ K ìì :
K륌 í¬íšíë ë žë ì°Ÿêž°Kê° ëŠ¬íì ììŒë©Ž: ì§ì ì ê±°Kê° ëŽë¶ ë žëì ììŒë©Ž: 늬íìì ì íì(ëë íìì)ë¡ êµì²Ží ë€ì 늬íìì ìì - ë
žëê° ìžëíë¡ì°í멎 (
âm/2â - 1ê° ë¯žë§ì í€): - ê°ë¥í멎 íì ìì ì¬ë¶ë°° (ë¹ëŠ¬êž°)
- ê·žë ì§ ììŒë©Ž íì ì ë³í©íê³ ë¶ëªšìì í€ë¥Œ ëŽëŠŒ
- ë¶ëªš ìžëíë¡ì°ë¥Œ ì¬ê·ì ìŒë¡ ì²ëЬ
ì: ì ížëЬìì 20 ìì (ì°šì 3, ë¹-ë£šíž ë žëë¹ ìµì 1ê°ì í€):
ìŽì :
ââââââââ
â20â25 â
ââ¬âââ¬âââ
ââââââ â ââââââ
âââââââ ââââ ââââ
â10â15â â22â â30â
âââââââ ââââ ââââ
ëšê³ 1: í€ 20ì ëŽë¶ ë
žëì ìì.
ëšê³ 2: ì€ì ì íì(15)ë¡ êµì²Ž.
ëšê³ 3: 늬íìì 15 ìì .
êµì²Ž í:
ââââââââ
â15â25 â
ââ¬âââ¬âââ
ââââââ â ââââââ
ââââ ââââ ââââ
â10â â22â â30â
ââââ ââââ ââââ
3.5 ë³µì¡ë ë¶ì¶
nê°ì í€ë¥Œ ê°ì§ ì°šì mì B-Tree:
| ì°ì° | ëì€í¬ I/O | CPU ìê° |
|---|---|---|
| ê²ì | O(log_m n) | O(m · log_m n) |
| ìœì | O(log_m n) | O(m · log_m n) |
| ìì | O(log_m n) | O(m · log_m n) |
ëìŽ íê³: n ⥠1ê°ì í€ì ìµì ì°šì t = âm/2âì ëíŽ:
h †log_t((n+1)/2)
ìŒë°ì ìž ë¶êž° ê³ì 100-200ìŒë¡, ëìŽ 3-4ì ížëЬë ìììµê°ì ë ìœë륌 ìžë±ì±í ì ìë€.
4. B+Tree¶
4.1 구조ì í¹ì±¶
B+Treeë êŽê³í ë°ìŽí°ë² ìŽì€ìì ê°ì¥ ë늬 ì¬ì©ëë ìžë±ì€ êµ¬ì¡°ë€ (PostgreSQL, MySQL InnoDB, Oracle, SQL Server 몚ë B+Tree ì¬ì©). B-Treeì ì€ìí ì°šìŽì :
- 몚ë ë°ìŽí° í¬ìží°ë 늬í ë žëì ìì -- ëŽë¶ ë žëë í€ì ìì í¬ìží°ë§ ì ì¥
- 늬í ë žëê° ì°ê²°ëš -- íšìšì ìž ë²ì ì€ìºì ìí ìŽì€ ì°ê²° 늬ì€íž
- ëŽë¶ ë žëì í€ê° 늬íì ì€ë³µëš (ëŽë¶ í€ë ê°ìŽë ìí ë§)
B+Tree 구조:
ëŽë¶ ë
žë (ê°ìŽë í€ë§):
ââââââââââââââ
â 30 â 60 â
ââââ¬ââââ¬âââ¬âââ
ââââââââââ â ââââââââââ
â â â
âââââââââââ âââââââââââ âââââââââââ
â 10 â 20 â â 40 â 50 â â 70 â 80 â
âââ¬âââ¬âââ¬ââ âââ¬âââ¬âââ¬ââ âââ¬âââ¬âââ¬ââ
â â â â â â â â â
늬í ë
žë (ì€ì ë°ìŽí°, ì°ê²°ëš):
âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ
â 5,8 âââ10,15âââ20,25âââ30,35âââ40,45âââ50,55âââ60,65âââ70,75âââ80,85â
â â â â â â â â â â â â â â â â â â
â D* â â D* â â D* â â D* â â D* â â D* â â D* â â D* â â D* â
âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ âââââââ
â â
Head 늬í ì²Žìž (ìŽì€ ì°ê²°) Tail
D* = ì€ì ë°ìŽí° ë ìœëì ëí í¬ìží°
ë žë íì¶
ëŽë¶ ë
žë (ì°šì m, ìµë mê°ì í¬ìží°, m-1ê°ì í€):
ââââââ¬ââââââ¬âââââ¬ââââââ¬âââââ¬ââââââ¬âââââ
â Pâ â Kâ â Pâ â Kâ â Pâ â ... â Pââ
ââââââŽââââââŽâââââŽââââââŽâââââŽââââââŽâââââ
subtree(Pâ)ì 몚ë í€ < Kâ
Kâ †subtree(Pâ)ì 몚ë í€ < Kâ
...
Kâââ †subtree(Pâ)ì 몚ë í€
늬í ë
žë (ìµë m-1ê°ì í€-í¬ìží° ì, íì í¬ìží° í¬íš):
ââââââââ¬âââââââ¬âââââââ¬âââââââ¬ââââââââââ
âKâ,DââKâ,DââKâ,Dââ ... â Pââââ â
ââââââââŽâââââââŽâââââââŽâââââââŽââââââââââ
Dáµ¢ = í€ Kᵢ륌 ê°ì§ ë ìœëì ëí í¬ìží°
Pââââ = ë€ì 늬í ë
žëì ëí í¬ìží°
4.2 B+Tree vs. B-Tree ë¹êµ¶
| í¹ì§ | B-Tree | B+Tree |
|---|---|---|
| ë°ìŽí° í¬ìží° | 몚ë ë žëì | 늬í ë žëìë§ |
| í€ ì€ë³µ | ì€ë³µ ìì | ëŽë¶ í€ê° 늬íì ì€ë³µëš |
| 늬í ì°ê²° | ì°ê²° ì ëš | ìŽì€ ì°ê²° 늬ì€íž |
| ë²ì 쿌늬 | ížëŠ¬ë¥Œ ì¬ë¬ ë² íìíŽìŒ íš | 늬í 첎ìžì ë°ëŒê° |
| ë¶êž° ê³ì(Fan-out) | ë®ì (ë°ìŽí° í¬ìží°ê° ê³µê° ì°šì§) | ëì (ëŽë¶ ë žëê° ë ë ì¬íš) |
| ëë± ê²ì | ëŽë¶ ë žëìì ì¡°êž° ì¢ ë£ ê°ë¥ | íì 늬íê¹ì§ ê° |
| ê³µê° ì¬ì© | ì 첎ì ìŒë¡ ìœê° ì ì | ìœê° ë§ì (í€ ì€ë³µ) |
| ì€ì ì¬ì© | ë°ìŽí°ë² ìŽì€ìì ê±°ì ì¬ì© ì ëš | 몚ë 죌ì RDBMSìì íì€ |
4.3 B+Treeìì ê²ì¶
í€ Kì ëí ëë± ê²ì:
BPLUS-SEARCH(root, K):
node = root
while node is not a leaf:
i = smallest index such that K < node.key[i]
if no such i exists:
node = node.child[last] // ê°ì¥ ì€ë¥žìªœ ìì
else:
node = node.child[i] // ìì ië¡ ìŽë
// ìŽì 늬íì ëë¬: K ì€ìº
for each (key, pointer) in node:
if key == K:
return pointer
return NOT_FOUND
ë²ì ê²ì [lo, hi]ì í€:
BPLUS-RANGE-SEARCH(root, lo, hi):
// ëšê³ 1: lo륌 í¬íšíë 늬í ì°Ÿêž°
leaf = find leaf for lo (ëë± ê²ì ë¡ì§ ì¬ì©)
// ëšê³ 2: ì°ê²° 늬ì€ížë¥Œ íµíŽ ëŠ¬í ì€ìº
results = []
while leaf is not null:
for each (key, pointer) in leaf:
if key > hi:
return results
if key >= lo:
results.append(pointer)
leaf = leaf.next // 늬í 첎ìžì ë°ëŒê°!
return results
ìŽê²ìŽ B+Treeê° ë²ì 쿌늬ì ë°ìŽë ìŽì ë€ -- ìì 늬í륌 ì°ŸìŒë©Ž, ì°ê²° 늬ì€ížë¥Œ ë°ëŒê°êž°ë§ í멎 ëë€.
4.4 B+Treeì ìœì ¶
ë°ìŽí° í¬ìží° Dì íšê» í€ K ìœì
:
BPLUS-INSERT(root, K, D):
leaf = find appropriate leaf node
if leaf has room:
insert (K, D) in sorted order in leaf
else:
// 늬í ì€ë²íë¡ì°: ë¶í
Create new leaf L'
Distribute entries evenly: first âm/2â stay, rest go to L'
// ë³µì¬: L'ì 첫 ë²ì§ž í€ê° ë¶ëªšë¡ ê°
parent-key = L'.key[1]
INSERT-IN-PARENT(leaf, parent-key, L')
Update leaf linked list pointers
INSERT-IN-PARENT(left, key, right):
if parent has room:
insert (key, right pointer) in parent
else:
// ëŽë¶ ë
žë ì€ë²íë¡ì°: ë¶í
Create new internal node N'
Distribute: first âm/2â pointers stay, rest go to N'
// ížì: ì€ê° í€ê° ë¶ëªšë¡ ê° (ë³µì¬ëì§ ìì)
middle-key = the key that separates the two halves
INSERT-IN-PARENT(parent, middle-key, N')
ì€ìí 구ë³: - 늬í ë¶í : ë³µì¬ (ë¶ëЬ í€ê° 늬íì ë¶ëªš 몚ëì 졎ì¬) - ëŽë¶ ë¶í : ížì (ë¶ëЬ í€ê° ë¶ëªšë¡ ìŽëíê³ ë¶í ëë ë žëìì ì ê±°ëš)
ì: ì°šì 3ì B+Treeì 7 ìœì (늬íë¹ ìµë 2ê°ì í€):
ìŽì :
ââââââ
â 5 â
ââ¬ââââ
ââââââ ââââââ
âââââââ ââââââââ
â 3,4 â âââ â 5,6 â
âââââââ ââââââââ
ëšê³ 1: í€ 7ì 늬í [5, 6]ì ìíš. 늬íê° êœ ì°ž.
ëšê³ 2: 늬í ë¶í : [5]ì [6, 7]. í€ 6ì ë¶ëªšë¡ ë³µì¬.
ìŽí:
ââââââââ
â 5 â 6â
ââ¬âââ¬âââ
âââââ â âââââ
âââââââ âââââ âââââââ
â 3,4 âââ 5 âââ 6,7 â
âââââââ âââââ âââââââ
4.5 B+Treeìì ìì ¶
í€ K ìì :
BPLUS-DELETE(root, K):
leaf = find leaf containing K
Remove K from leaf
if leaf has enough keys (⥠â(m-1)/2â):
done (첫 ë²ì§ž í€ê° ë³ê²œë멎 ë¶ëªš í€ ì
ë°ìŽíž íìí ì ìì)
else:
// ìžëíë¡ì°
if sibling has extra keys:
redistribute (íì ìì ë¹ëŠŒ)
update parent key
else:
merge with sibling
delete entry from parent
recursively handle parent underflow
늬í ë³í©ì ë¶ëªšìì í€ë¥Œ ì ê±°íë€. ëŽë¶ ë žë ë³í©ì ë¶ëªšìì í€ë¥Œ ëŽëаë€. 룚ížê° ëšìŒ ììë§ ëšìŒë©Ž, ìììŽ ì 룚ížê° ëë€ (ížëЬ ëìŽ ê°ì).
4.6 ëë ë¡ë©¶
ë¹ ížëЬìì íëì© ìœì íì¬ B+Tree륌 구ì¶íë ê²ì ë¹íšìšì ìŽë€. ëë ë¡ë©(Bulk Loading)ì Ʞ졎 ë°ìŽí°ì ìžë±ì€ë¥Œ ìì±í ë ì¬ì©ëë€:
BULK-LOAD(sorted_data, m):
// ëšê³ 1: ê²ì í€ë¡ ë°ìŽí° ì ë ¬ (íìì ìžë¶ ì ë ¬)
// ëšê³ 2: 늬í ë
žë륌 ìì°šì ìŒë¡ ì±ì
for each key in sorted_data:
add to current leaf
if leaf full:
start new leaf
add separator to parent level
// ëšê³ 3: ìí¥ììŒë¡ ëŽë¶ ë 벚 구ì¶
repeat for each level until root is created
ëë ë¡ë©ì ì¥ì : - ëë€ I/O ëì ìì°š I/O - ì±ì ë¹ìš(Fill Factor) ì ìŽ ê°ë¥ (ì: í¥í ìœì ì ìíŽ 90% ì±ì) - O(n log_m n) ì 첎, íì§ë§ ììê° íšì¬ ë ì¢ì
PostgreSQL:
-- CREATE INDEXë í
ìŽëžì ë°ìŽí°ê° ìì ë ëŽë¶ì ìŒë¡ ëë ë¡ë© ì¬ì©
CREATE INDEX idx_emp_salary ON employees(salary);
-- REINDEXë ìžë±ì€ë¥Œ ì¬êµ¬ì¶ (ëë ì
ë°ìŽíž í ì ì©)
REINDEX INDEX idx_emp_salary;
4.7 ëìŽì ì±ë¥ ë¶ì¶
nê°ì ê²ì í€ ê°ì ê°ì§ ì°šì mì B+Tree:
ìµë ëìŽ:
h †âlog_{âm/2â}(n)â
ì€ì ì:
죌ìŽì§: - ëžë¡ í¬êž°: 4 KB - í€ í¬êž°: 8ë°ìŽíž, í¬ìží° í¬êž°: 8ë°ìŽíž - ëŽë¶ ë žë ë¶êž° ê³ì: m = 4096 / (8 + 8) = 256 - 늬í ìížëЬ: (m-1) = 늬íë¹ 255
n = 100,000,000 (1ìµ) ë ìœëì 겜ì°:
ëìŽ = âlogâââ(100,000,000)â = âlogâââ(10âž)â â â8/2.1â â 4
ë°ëŒì 1ìµ ê° ì€ ìŽë€ ë ìœëë 4ë²ì ëì€í¬ ìœêž°ë¡ ì°Ÿì ì ìë€. ì€ì ë¡ ë£šížì ìì ë 벚ì ë©ëªšëЬì ìºìëìŽ, ìŽë¥Œ 1-2ë²ì ëì€í¬ ìœêž°ë¡ ì€ìŒ ì ìë€.
5. íŽì êž°ë° ìžë±ì±¶
5.1 ì ì íŽì±¶
íŽì ìžë±ì€ë íŽì íšì h(K)륌 ì¬ì©íì¬ ê²ì í€ ê°ì ë²í· 죌ìì ì§ì ë§€ííë€.
íŽì íšì hê° í€ K륌 ë²í· ë²ížì ë§€í:
Key: "Alice" â h("Alice") = 2
Key: "Bob" â h("Bob") = 0
Key: "Carol" â h("Carol") = 2 (ì¶©ë!)
ë²í· ë°°ìŽ:
âââââââââââ
â ë²í· 0 â â [Bob, ...]
âââââââââââ€
â ë²í· 1 â â [empty]
âââââââââââ€
â ë²í· 2 â â [Alice, ...] â [Carol, ...] (ì€ë²íë¡ì° 첎ìž)
âââââââââââ€
â ë²í· 3 â â [Dave, ...]
âââââââââââ
í¹ì±: - ìŽìì ìž ê²œì°: O(1) ì¡°í -- í ë²ì ëì€í¬ ìœêž° - ì€ë²íë¡ì° ì²ëЬ: 첎ìŽë (ì€ë²íë¡ì° ë²í·ì ì°ê²° 늬ì€íž) - ìœì : ê³ ì ë ë²í· ì. íìŒìŽ ìŠê°í멎 ì±ë¥ ì í
íŽì íšì ì구ì¬í: 1. ê· ìŒ ë¶í¬: í€ê° ë²í· ì 첎ì ê· ë±íê² ë¶ì°ëìŽìŒ íš 2. ê²°ì ì : ëìŒí í€ë íì ëìŒí ë²í·ì ë§€í 3. ë¹ ë¥ž ê³ì°: O(1) ìê°
5.2 íì¥ ê°ë¥ íŽì±¶
íì¥ ê°ë¥ íŽì±(Extendible Hashing)ì ì 첎 íìŒì ì¬êµ¬ì±íì§ ìê³ íìì ë°ëŒ í¬êž°ê° 2ë°°ê° ëë ëë í 늬륌 ì¬ì©íì¬ ë°ìŽí° ìŠê°ì ì ìíë€.
죌ì ê°ë
:
- ì ì ê¹ìŽ(Global Depth) (d): ëë í ëŠ¬ê° ì¬ì©íë íŽì ê°ì ë¹íž ì
- ë¡ì»¬ ê¹ìŽ(Local Depth) (dáµ¢): ë²í· iê° ì¬ì©íë ë¹íž ì
- ëë í 늬 í¬êž° = 2^d ìížëЬ
ì ì ê¹ìŽ d = 2ìž ì:
íŽì ê° (2ì§ì): ëë í 늬 (d=2):
h(Kâ) = 01001... ââââââ¬ââââââââââââ
h(Kâ) = 10110... â 00 â âââ ë²í· A (ë¡ì»¬ ê¹ìŽ 2)
h(Kâ) = 00101... â 01 â âââ ë²í· B (ë¡ì»¬ ê¹ìŽ 2)
h(Kâ) = 11010... â 10 â âââ ë²í· C (ë¡ì»¬ ê¹ìŽ 1)
h(Kâ
) = 10011... â 11 â âââ ë²í· C (ë¡ì»¬ ê¹ìŽ 1)
ââââââŽââââââââââââ
ì°žê³ : ìížëЬ 10곌 11 몚ë ë²í· C륌 ê°ëЬíŽ
Cì ë¡ì»¬ ê¹ìŽ (1) < ì ì ê¹ìŽ (2)ìŽêž° ë묞.
ë²í· Cìë 첫 ë²ì§ž ë¹ížë§ ì€ìíš.
ë²í· ì€ë²íë¡ì° ì ë²í· ë¶í :
ë²í· B (ë¡ì»¬ ê¹ìŽ 2)ê° ì€ë²íë¡ì°í멎:
ìŒìŽì€ 1: ë¡ì»¬ ê¹ìŽ < ì ì ê¹ìŽ
â ë²í· ë¶í , ë¡ì»¬ ê¹ìŽ ìŠê°
â ìížëЬ ì¬ë¶ë°°
â ëë í 늬 í¬ìží° ì
ë°ìŽíž
ìŒìŽì€ 2: ë¡ì»¬ ê¹ìŽ == ì ì ê¹ìŽ
â ëë í 늬륌 2ë°°ë¡ (ì ì ê¹ìŽ 1 ìŠê°)
â ë²í· ë¶í , ë¡ì»¬ ê¹ìŽ ìŠê°
â ìížëЬ ì¬ë¶ë°°
â ëë í 늬 í¬ìží° ì
ë°ìŽíž
ì¥ì : - ì€ë²íë¡ì° ì²Žìž ìì (ë¶í ìŽ ìŠê° ì²ëЬ) - ì¡°íë¹ ìµë 2ë²ì ëì€í¬ ì ê·Œ (ëë í 늬 1ë², ë²í· 1ë²) - ì°ìíê² ìŠê°
ëšì : - ë°ìŽí°ê° ì¹ì°ì¹ë©Ž ëë í ëŠ¬ê° ì»€ì§ ì ìì - ëë í 늬 2ë°° íì¥ì ë¹ìžì§ë§ ëë¬Œê² ë°ì
5.3 ì í íŽì±¶
ì í íŽì±(Linear Hashing)ì ëë í 늬륌 ìì í íŒíë€. ë²í·ì ë¶í í¬ìží°ë¡ ì ìŽëë ëŒìŽë ë¡ë¹ ë°©ììŒë¡ í ë²ì íëì© ë¶í ëë€.
íµì¬ ììŽëìŽ:
- ë€ì ë¶í í ë²í·ì ì¶ì íë ë¶í í¬ìží° s ì ì§
- ë ê°ì íŽì íšì ì¬ì©: hâ(K) = K mod N곌 hâ(K) = K mod 2N
- ë²í·ìŽ ì€ë²íë¡ì°í멎, ë¶í í¬ìží°ì ë²í·ì ë¶í (ì€ë²íë¡ì°ë ë²í·ìŽ ìë)
N=4 ë²í·, ë¶í í¬ìží° s=1ìž ìí:
ë²í·:
ââââââââââââ
â ë²í· 0 â â [hâ(K)=0ìž ë ìœë] (ìŽë¯ž ë¶í ëš, hâ ì¬ì©)
ââââââââââââ€
â ë²í· 1 â â [hâ(K)=1ìž ë ìœë] â ë¶í í¬ìží° s
ââââââââââââ€
â ë²í· 2 â â [hâ(K)=2ìž ë ìœë] (ìì§ ë¶í ì ëš, hâ ì¬ì©)
ââââââââââââ€
â ë²í· 3 â â [hâ(K)=3ìž ë ìœë] (ìì§ ë¶í ì ëš, hâ ì¬ì©)
ââââââââââââ€
â ë²í· 4 â â [hâ(K)=4ìž ë ìœë] (ë²í· 0 ë¶í ë¡ ìì±ëš)
ââââââââââââ
ì¡°í ìê³ ëŠ¬ìŠ:
b = hâ(K) // ì: K mod 4
if b < s: // ë²í·ìŽ ìŽë¯ž ë¶í ëš
b = hâ(K) // ëì K mod 8 ì¬ì©
search bucket b
ìžì ë¶í í ê¹:
- ìŽë€ ë²í·ìŽ ì€ë²íë¡ì°í멎 ë¶í ìŽ ížëŠ¬ê±°ëš
- ë¶í í¬ìží°ì ë²í·ìŽ ë¶í ëš (ì€ë²íë¡ì°ë ë²í·ìŽ ìë!)
- ì€ë²íë¡ì°ë ë²í·ì ììë¡ ì€ë²íë¡ì° ì²Žìž ì¬ì©
- ë¶í í¬ìží° ì ì§: s = s + 1
- s = NìŽë©Ž, ëŒìŽë ìë£: N = 2N, s = 0, íŽì íšì ì ì§
ì¥ì : - ëë í 늬 ë¶íì - ë¶ëë¬ìŽ ìŠê° (í ë²ì íëì ë²í·) - 볎ì¥ë O(1) íê· ì ê·Œ
ëšì : - ìì ì€ë²íë¡ì° ì²Žìž - ë¶í ìŽ ì€ì ì€ë²íë¡ì°ë ë²í·ì ìŠì ìííì§ ëª»í ì ìì
íŽì vs. B+Tree ë¹êµ¶
| êž°ì€ | íŽì ìžë±ì€ | B+Tree ìžë±ì€ |
|---|---|---|
| ëë± ì¿ŒëŠ¬ | O(1) -- ì°ì | O(log n) -- ì¢ì |
| ë²ì 쿌늬 | ì§ì ì íš | ì°ì (늬í 첎ìž) |
| ì ë ¬ë ìí | ì§ì ì íš | ìì°ì€ë¬ì (늬í ì€ìº) |
| ëì ìŠê° | íì¥ ê°ë¥/ì í | ë¶í 곌 ë³í© |
| ê³µê° ì¬ì© | ê³µê° ëë¹ ê°ë¥ (ë¹ ë²í·) | ì¢ì íì© (~67%) |
| 구í | ë ëšì | ë ë³µì¡ |
| RDBMSìì ìŒë°ì | PostgreSQL (íŽì), Redis | 몚ë 죌ì RDBMS |
6. ë¹ížë§µ ìžë±ì€¶
6.1 ê°ë ¶
ë¹ížë§µ ìžë±ì€(Bitmap Index)ë ìžë±ì±ë ìì±ì ê° ê³ ì ê°ì ëíŽ ë¹íž 벡í°ë¥Œ ìì±íë€. ê° ë¹ížë í ìŽëžì íì íŽë¹íë€.
í
ìŽëž: employees (8ê° í)
âââââââ¬ââââââââ¬âââââââââ¬âââââââââ
â RID â Name â Dept â Gender â
âââââââŒââââââââŒâââââââââŒâââââââââ€
â 0 â Alice â Eng â F â
â 1 â Bob â Sales â M â
â 2 â Carol â Eng â F â
â 3 â Dave â HR â M â
â 4 â Eve â Eng â F â
â 5 â Frank â Sales â M â
â 6 â Grace â HR â F â
â 7 â Hank â Eng â M â
âââââââŽââââââââŽâââââââââŽâââââââââ
Deptì ëí ë¹ížë§µ ìžë±ì€:
Eng: [1, 0, 1, 0, 1, 0, 0, 1] (í 0,2,4,7)
Sales: [0, 1, 0, 0, 0, 1, 0, 0] (í 1,5)
HR: [0, 0, 0, 1, 0, 0, 1, 0] (í 3,6)
Genderì ëí ë¹ížë§µ ìžë±ì€:
F: [1, 0, 1, 0, 1, 0, 1, 0] (í 0,2,4,6)
M: [0, 1, 0, 1, 0, 1, 0, 1] (í 1,3,5,7)
6.2 ë¹ížë§µ ì°ì°¶
ë¹íž ì°ì°ì ì¬ì©íì¬ ë¹ížë§µì ê²°í©íì¬ ì¿ŒëŠ¬ì ëµí ì ìë€:
쿌늬: 몚ë ì¬ì± ìì§ëìŽ ì°Ÿêž°
Dept=Eng: [1, 0, 1, 0, 1, 0, 0, 1]
AND
Gender=F: [1, 0, 1, 0, 1, 0, 1, 0]
âââââââââââââââââââââââââââââââââââââ
결곌: [1, 0, 1, 0, 1, 0, 0, 0] â í 0, 2, 4
(Alice, Carol, Eve)
쿌늬: Sales ëë HRì 몚ë ì§ì ì°Ÿêž°
Dept=Sales: [0, 1, 0, 0, 0, 1, 0, 0]
OR
Dept=HR: [0, 0, 0, 1, 0, 0, 1, 0]
âââââââââââââââââââââââââââââââââââââ
결곌: [0, 1, 0, 1, 0, 1, 1, 0] â í 1, 3, 5, 6
쿌늬: 몚ë ë¹-ìì§ëìŽ ì°Ÿêž°
NOT Dept=Eng: NOT [1, 0, 1, 0, 1, 0, 0, 1]
âââââââââââââââââââââââââââââââââââââââââââââ
결곌: [0, 1, 0, 1, 0, 1, 1, 0] â í 1, 3, 5, 6
6.3 ë¹ížë§µ ìžë±ì€ë¥Œ ì¬ì©íŽìŒ í ë¶
ìŽìì ìž ê²œì°: - ë®ì 칎ëëëŠ¬í° ìì± (Gender: 2ê° ê°, Status: 3-5ê° ê°) - ë°ìŽí° ìšìŽíì°ì§ - ëë¶ë¶ ìœêž° ì ì© ì ê·Œ - ë³µì¡í ë€ì€ ìì± ì¿ŒëŠ¬ (AND/OR ì¡°í©) - 칎ìŽíž 쿌늬 (WHEREê° ìë COUNT) -- ì€ì ë ë¹ížë§ ìžêž° - ì€í ì€í€ë§(Star Schema) í©íž í ìŽëžì ë§ì ì°šì ìžë í€
ìŽìì ìŽì§ ìì 겜ì°: - ëì 칎ëëëŠ¬í° ìì± (ì: ê³ ì ID -- ê°ë¹ íëì ë¹ížë§µ!) - OLTP - ë¹ë²í ì ë°ìŽíž (몚ë ìœì ë§ë€ ë¹ížë§µ ì ë°ìŽížë ë¹ì) - ëì ëìì± í겜 (ë¹ížë§µ ì êžìŽ ë§ì íì ìí¥)
6.4 ë¹ížë§µ ìì¶¶
ëí í ìŽëžì ê²œì° ë¹ížë§µìŽ ë§€ì° ì»€ì§ ì ìë€. ìì¶ êž°ë²ìŽ ëììŽ ëë€:
ë° êžžìŽ ìžìœë©(Run-Length Encoding, RLE):
ì볞: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
RLE: (0, 11), (1, 1), (0, 4) â "11ê°ì 0, 1ê°ì 1, 4ê°ì 0"
ìë ì ë ¬ íìŽëžëЬë(Word-Aligned Hybrid, WAH): Oracle ë° ë€ë¥ž ìì€í ìì ì¬ì©. ëìŒí ìë(32 ëë 64ë¹íž)ì ìíì€ë¥Œ ìì¶í멎ì ìì¶ë ííë¡ íšìšì ìž ë¹íž ì°ì°ì íì©íë€.
ë¡ìŽë§ ë¹ížë§µ(Roaring Bitmaps): ë¹ížë§µì ì²í¬ë¡ ë¶í íê³ ê° ì²í¬ì ëíŽ ìµì ì íí(ë°°ìŽ, ë¹ížë§µ, ëë ë°)ì ì¬ì©íë íëì ìž ìì¶ êž°ë². Apache Lucene, Apache Spark ë° ë€ë¥ž ìì€í ìì ë늬 ì¬ì©ëë€.
6.5 ê³µê° ë¶ì¶
nê° í곌 cê° ê³ ì ê°ì ê°ì§ ìì±ì ê°ì§ í
ìŽëž:
ë¹ìì¶ ë¹ížë§µ í¬êž° = n à c ë¹íž = nc/8 ë°ìŽíž
B+Treeì ë¹êµ:
B+Tree ìžë±ì€ í¬êž° â n à (key_size + pointer_size) ë°ìŽíž
ì: 100ë§ í, 5ê° ê°ì ê°ì§ ìì±: - ë¹ížë§µ: 1,000,000 x 5 / 8 = 625,000 ë°ìŽíž â 610 KB - B+Tree: 1,000,000 x (8 + 8) = 16,000,000 ë°ìŽíž â 15.3 MB
ë®ì 칎ëëëŠ¬í° ìì±ì ê²œì° ë¹ížë§µì 25ë°° ë ìë€.
7. ë€ì°šì ìžë±ì±¶
7.1 ë¬žì ¶
íì€ B+Treeì íŽì ìžë±ì€ë 1ì°šì ê²ì í€ì ì ìëíë€. íì§ë§ ë§ì 쿌늬ë ì¬ë¬ ì°šìì í¬íšíë€:
-- ê³µê° ì¿ŒëŠ¬
SELECT * FROM restaurants
WHERE latitude BETWEEN 37.7 AND 37.8
AND longitude BETWEEN -122.5 AND -122.4;
-- ë€ì€ ìì± ë²ì 쿌늬
SELECT * FROM products
WHERE price BETWEEN 10 AND 50
AND weight BETWEEN 0.5 AND 2.0;
(latitude, longitude)ì ëí B+Treeë latitudeìì íšìšì ìŒë¡ íí°ë§í ì ìì§ë§ longitudeì ëíŽìë ìŒì¹íë 몚ë ìížëŠ¬ë¥Œ ì€ìºíŽìŒ íë€. ì§ì í ë€ì°šì ìžë±ì€ë ë ì°šìì ëìì ì²ëЬíë€.
7.2 R-Tree¶
R-Tree (Rectangle Tree)ë ê°ì¥ ë늬 ì¬ì©ëë ê³µê° ìžë±ì€ë€. ìµì ê²œê³ ì¬ê°í(Minimum Bounding Rectangles, MBR)ì ì¬ì©íì¬ ë°ìŽí°ë¥Œ 구ì±íë€.
R-Tree 구조:
룚íž: [MBRâ, MBRâ]
ââââââââââââââââââââââââââââââââââââââââ
â âââââââââââââ ââââââââââââââââ â
â â MBRâ â â MBRâ â â
â â ââââ ââââ â â âââââ ââââ â â
â â âP1â âP2â â â âP3 â âP4â â â
â â ââââ ââââ â â âââââ ââââ â â
â â ââââ â â ââââ â â
â â âP5â â â âP6â â â
â â ââââ â â ââââ â â
â âââââââââââââ ââââââââââââââââ â
ââââââââââââââââââââââââââââââââââââââââ
ê° ëŽë¶ ë
žë: [MBRâ, ptrâ, MBRâ, ptrâ, ...]
ê° ëŠ¬í ë
žë: [MBRâ, oidâ, MBRâ, oidâ, ...]
í¹ì±:
- ê· í ížëЬ (몚ë 늬íê° ëìŒí ë 벚ì)
- ê° ë
žëë âm/2âì m ì¬ìŽì ìížëŠ¬ë¥Œ í¬íš
- 죌ìŽì§ ë 벚ì MBRìŽ ê²¹ì¹ ì ìì
- ê²ìì ì¬ë¬ 겜ë¡ë¥Œ ë°ëŒê°ìŒ í ì ìì (B+Treeì ë¬ëЬ)
ì°ì°: - ê²ì: 룚ížìì ìì, MBRìŽ ì¿ŒëŠ¬ ì¬ê°í곌 ê²¹ì¹ë 몚ë ìììŒë¡ ëŽë €ê° - ìœì : MBRìŽ ê°ì¥ ì ê² íëëìŽìŒ íë ë¶ížëŠ¬ë¥Œ ì í; íìì ë¶í - ì¬ì©ì²: PostgreSQL (GiST ìžë±ì€), Oracle Spatial, PostGIS
7.3 kd-Tree¶
kd-tree (k-ì°šì ížëЬ)ë ê° ë 벚ìì ë¶í ì°šìì êµëë¡ íì¬ ê³µê°ì ë¶í íë€.
2D kd-tree ì (x, ê·ž ë€ì y, ê·ž ë€ì xë¡ ë¶í , ...):
ë°ìŽí° í¬ìžíž: (2,3), (5,4), (9,6), (4,7), (8,1), (7,2)
(7,2) x=7ìì ë¶í
/ \
(5,4) (9,6) y=4, y=6ìì ë¶í
/ \ \
(2,3) (4,7) (8,1) x=2, x=4, x=8ìì ë¶í
ê³µê° ë¶í :
âââââââââââââââââââââââââ
â â â
â (2,3) â (9,6) â
â · â · â
ââââââââ(5,4)ââââââ â
â · â â â
â (4,7) â â (8,1) â
â â â · â
âââââââââŽââââŽââââââââââââ
x=7 (ë¶í ì )
í¹ì±: - ìŽì§ ížëЬ (ê° ë žëê° ê³µê°ì ë°ìŒë¡ ë¶í ) - ë®ì ì°šì ë°ìŽí°ì íšìšì (d †20) - ê²ì: O(n^(1-1/d) + k) ì¬êž°ì kë 결곌 ì - ëì ë°ìŽí°ì ëíŽ ê· íìŽ ë§ì§ ìì (k-d-B ížëЬì ê°ì ë³í ì¬ì©)
ê³µê° ìžë±ì€ ë¹êµ:
| í¹ì§ | R-Tree | kd-Tree |
|---|---|---|
| ì°šì | ìŽë€ dìë ìë | ë®ì dì ìµì |
| ëì ì ë°ìŽíž | ì¢ì (ìŽë¥Œ ìíŽ ì€ê³ëš) | ëìš (ë¶ê· í ê°ë¥) |
| ëì€í¬ êž°ë° | ì (ìŽë¥Œ ìíŽ ì€ê³ëš) | ìë ìž-ë©ëªšëЬ |
| 겹칚 | 겹칚 íì© | 겹칚 ìì |
| ì¬ì© ì¬ë¡ | GIS, ê³µê° ë°ìŽí°ë² ìŽì€ | k-NN ê²ì, ìž-ë©ëªšëЬ |
8. ìžë±ì€ ì í곌 ì€ê³ ì§ì¹š¶
8.1 ìžë±ì€ ì í ë¬žì ¶
ì¬ë°ë¥ž ìžë±ì€ë¥Œ ì ííë ê²ì ì±ë¥ì ì€ìíë€. ìžë±ì€ ì í 묞ì ë ë€ìì 묻ëë€: ìí¬ë¡ë(쿌늬 ì§í©)ê° ì£ŒìŽì¡ì ë, ìŽë€ ìžë±ì€ë¥Œ ìì±íŽìŒ íëê°?
ê³ ë €í ììž: 1. 쿌늬 íšíŽ: WHERE, JOIN, ORDER BY, GROUP BYì ìŽë€ 컬ëŒìŽ ëíëëê°? 2. ì ë°ìŽíž ë¹ë: INSERT, UPDATE, DELETEê° ìŒë§ë ì죌 ì€íëëê°? 3. ë°ìŽí° ë¶í¬: ê° ì»¬ëŒì 칎ëë늬í°ì ì íë 4. ì ì¥ ìì°: ê° ìžë±ì€ë ëì€í¬ ê³µê°ê³Œ ì ì§ë³Žì ì€ë²í€ëê° ë¬ 5. ìêŽêŽê³: ì죌 íšê» 쿌늬ëë 컬ëŒ
8.2 컀ë²ë§ ìžë±ì€¶
컀ë²ë§ ìžë±ì€(Covering Index)ë 쿌늬ì íìí 몚ë 컬ëŒì í¬íšíë¯ë¡, ë°ìŽí°ë² ìŽì€ê° í ìŽëžì ì ê·Œíì§ ìê³ ìžë±ì€ë§ìŒë¡ 쿌늬ì ëµí ì ìë€ (ìžë±ì€ ì ì© ì€ìº).
-- 쿌늬:
SELECT name, salary FROM employees WHERE department = 'Eng';
-- ë¹-컀ë²ë§ ìžë±ì€ (í
ìŽëž ì ê·Œ íì):
CREATE INDEX idx_dept ON employees(department);
-- ìžë±ì€ë¥Œ íµíŽ ìŒì¹íë íì ì°Ÿì ë€ì, í
ìŽëžìì name, salary륌 ê°ì žìŽ
-- 컀ë²ë§ ìžë±ì€ (í
ìŽëž ì ê·Œ ë¶íì):
CREATE INDEX idx_dept_covering ON employees(department, name, salary);
-- íìí 몚ë 컬ëŒìŽ ìžë±ì€ì ìì
PostgreSQL INCLUDE 구묞:
-- INCLUDE 컬ëŒì 늬í ë 벚ì ì ì¥ëì§ë§ ê²ì í€ìë ìì
CREATE INDEX idx_dept_incl ON employees(department) INCLUDE (name, salary);
-- departmentë ê²ì í€; name곌 salaryë íìŽë¡ëë§
ìŽì : - í ìŽëž ì ê·Œ ì ê±° (ë§ëí I/O ì ê°) - ì죌 ì€íëë 쿌늬ì í¹í íšê³Œì
ížë ìŽëì€í: - ë í° ìžë±ì€ í¬êž° - ì ë°ìŽíž ì ë ë§ì ì»¬ëŒ ì ì§ë³Žì
8.3 ë³µí© (ë€ì€ 컬ëŒ) ìžë±ì€¶
ë³µí© ìžë±ì€(Composite Index)ë ì¬ë¬ 컬ëŒì 구ì¶ëë€. ì»¬ëŒ ììê° ë§€ì° ì€ìíë€.
CREATE INDEX idx_dept_salary ON employees(department, salary);
ìŽ ìžë±ì€ë ë€ìì ì ì©íë€:
-- ì 첎 ìžë±ì€ ì¬ì© (ë ì»¬ëŒ ëªšë):
SELECT * FROM employees WHERE department = 'Eng' AND salary > 80000;
-- ìžë±ì€ ì ëì¬ ì¬ì© (departmentë§):
SELECT * FROM employees WHERE department = 'Eng';
-- ìŽ ìžë±ì€ë¥Œ íšìšì ìŒë¡ ì¬ì©íì§ ìì:
SELECT * FROM employees WHERE salary > 80000; -- salaryë ì ëì¬ê° ìë
ìµì¢ ì ëì¬ ê·ì¹: (A, B, C)ì ëí ë³µí© ìžë±ì€ë ë€ì 쿌늬ì ì¬ì©ë ì ìë€:
- A
- A, B
- A, B, C
íì§ë§ ë€ììë íšìšì ìŽì§ ìë€:
- B ëšë
- C ëšë
- B, C
8.4 ë¶ë¶ ìžë±ì€¶
ë¶ë¶ ìžë±ì€(Partial Index)ë 조걎ìë¡ ì ìë íì ë¶ë¶ì§í©ë§ ìžë±ì±íë€.
-- íì± ì§ìë§ ìžë±ì± (90%ê° ë¹íì±ìŽë©Ž ìžë±ì€ê° íšì¬ ìì)
CREATE INDEX idx_active_emp ON employees(name)
WHERE status = 'active';
-- ìµê·Œ ì£Œë¬žë§ ìžë±ì±
CREATE INDEX idx_recent_orders ON orders(customer_id)
WHERE order_date > '2025-01-01';
-- ë¹-NULL ê°ë§ ìžë±ì±
CREATE INDEX idx_email ON users(email)
WHERE email IS NOT NULL;
ìŽì : - ë ìì ìžë±ì€ í¬êž° (ë ì ì ìížëЬ) - ë ë¹ ë¥ž ì ì§ë³Žì (ë ì ì ì ë°ìŽíž) - ë ëì ìºì íì©
8.5 ííì ìžë±ì€¶
ìŒë¶ ë°ìŽí°ë² ìŽì€ë ê³ì°ë ííì ìžë±ì±ì ì§ìíë€:
-- PostgreSQL: ííì ìžë±ì€
CREATE INDEX idx_lower_email ON users(lower(email));
-- ëì묞ì êµ¬ë¶ ìë ê²ìì ì ì©:
SELECT * FROM users WHERE lower(email) = 'alice@example.com';
-- íìì€í¬íìì ì°ë ì¶ì¶í ìžë±ì€:
CREATE INDEX idx_order_year ON orders(EXTRACT(YEAR FROM order_date));
8.6 ì€ì©ì ì§ì¹š¶
ê·ì¹ 1: WHERE, JOIN, ORDER BYì ì»¬ëŒ ìžë±ì±
-- ìŽ ì¿ŒëŠ¬ë customer_id, order_date, statusì ìžë±ì€ë¡ ìŽìµ
SELECT o.* FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE o.order_date > '2025-01-01'
ORDER BY o.status;
ê·ì¹ 2: ì íë ê³ ë € - ëì ì íë (ìŒì¹íë íìŽ ì ì) = ì¢ì ìžë±ì€ í볎 - ë®ì ì íë (ëë¶ë¶ì íìŽ ìŒì¹) = ëì ìžë±ì€ í볎 - 겜í ë²ì¹: ìžë±ì€ë íì 15-20% 믞ë§ì ì íí ë ì ì©
ê·ì¹ 3: 곌ëí ìžë±ì± íŒíêž°
ê° ìžë±ì€ ë¹ì©:
- ëì€í¬ ê³µê° (ìžë±ì€ 구조 í¬êž°)
- ìœì
ì€ë²í€ë: ~ìžë±ì€ë¹ 1ë²ì B+Tree ìœì
- ì
ë°ìŽíž ì€ë²í€ë: ìžë±ì€ë¹ 구 ìì + ì ìœì
- ì§ê³µ/ì ì§ë³Žì ì€ë²í€ë
ìŒë°ì ìž ì§ì¹š: í
ìŽëžë¹ 3-5ê° ìžë±ì€, ê±°ì 10ê°ë¥Œ ëì§ ìì
ê·ì¹ 4: EXPLAINì ì¬ì©íì¬ ìžë±ì€ ì¬ì© íìž
EXPLAIN ANALYZE SELECT * FROM employees WHERE department = 'Eng';
-- ì°Ÿì ê²:
-- "Index Scan" ëë "Index Only Scan" â ìžë±ì€ê° ì¬ì©ëš
-- "Seq Scan" â ìžë±ì€ê° ì¬ì©ëì§ ìì (ëë 졎ì¬íì§ ìì)
-- "Bitmap Index Scan" â ë€ì€ 조걎 쿌늬ì ë¹ížë§µ ìžë±ì€ ì¬ì©ëš
ê·ì¹ 5: ìžë±ì€ 몚ëí°ë§ ë° ì ì§ë³Žì
-- PostgreSQL: ìžë±ì€ ì¬ì© íµê³ íìž
SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read
FROM pg_stat_user_indexes
ORDER BY idx_scan ASC;
-- idx_scan = 0ìž ìžë±ì€ë ì¬ì©ëì§ ììŒë©° ìì ê°ë¥
-- ìžë±ì€ í¬êž° íìž
SELECT pg_size_pretty(pg_relation_size('idx_emp_salary'));
-- ëšížíë ìžë±ì€ ì¬êµ¬ì¶
REINDEX INDEX idx_emp_salary;
9. 죌ì ë°ìŽí°ë² ìŽì€ì ìžë±ì€ 구조¶
PostgreSQL¶
-- B+Tree (Ʞ볞ê°)
CREATE INDEX idx_btree ON table(column);
-- íŽì (ëë± ê²ìë§, v10ë¶í° WAL ë¡ê¹
ëš)
CREATE INDEX idx_hash ON table USING hash(column);
-- GiST (ìŒë°íë ê²ì ížëЬ(Generalized Search Tree) -- R-Tree, ì 묞 ê²ì ë±)
CREATE INDEX idx_gist ON table USING gist(geom_column);
-- GIN (ìŒë°íë ì ìžë±ì€(Generalized Inverted Index) -- ë°°ìŽ, JSONB, ì 묞 ê²ì)
CREATE INDEX idx_gin ON table USING gin(jsonb_column);
-- BRIN (ëžë¡ ë²ì ìžë±ì€(Block Range Index) -- ëí ì ë ¬ í
ìŽëž)
CREATE INDEX idx_brin ON table USING brin(timestamp_column);
-- SP-GiST (ê³µê° ë¶í GiST(Space-Partitioned GiST) -- kd-ížëЬ, êž°ì ížëЬ)
CREATE INDEX idx_spgist ON table USING spgist(point_column);
MySQL InnoDB¶
- Ʞ볞 í€ = íŽë¬ì€í°ë B+Tree ìžë±ì€ (ë°ìŽí°ê° 늬í ë
žëì ì ì¥ëš)
- 볎조 ìžë±ì€ë Ʞ볞 í€ ê°ì ì ì¥ (í í¬ìží°ê° ìë)
- ìŽë 볎조 ìžë±ì€ ì¡°íê° ë ë²ì B+Tree íìì íìë¡ íšì ì믞:
1. 볎조 ìžë±ì€ â Ʞ볞 í€ ê°
2. Ʞ볞 ìžë±ì€ â ì€ì í ë°ìŽí°
ììœ í¶
| ìžë±ì€ íì | ìµì ì©ë | íê³ |
|---|---|---|
| B+Tree | ë²ì©, ë²ì, ORDER BY | ë€ì°šììë ë³ë¡ |
| íŽì | ì íí ëë± ì¡°í | ë²ì ì§ì ìì |
| ë¹ížë§µ | ë®ì 칎ëë늬í°, ë¶ì | OLTP, ëì 칎ëë늬í°ì ëìš |
| GiST/R-Tree | ê³µê°, êž°í ë°ìŽí° | ê²¹ì¹šìŽ ê²ìì ëëŠ¬ê² í ì ìì |
| GIN | ì 묞 ê²ì, ë°°ìŽ, JSONB | í° ìžë±ì€, ë늰 ì ë°ìŽíž |
| BRIN | ë§€ì° í°, ìì° ì ë ¬ í ìŽëž | ë®ì ì ë°ë |
10. ì°ìµë¬žì ¶
ê°ë ì ì§ë¬ž¶
ì°ìµë¬žì 1: 볎조 ìžë±ì€ë ë°ì§íŽìŒ íë ë°ë©Ž 죌 ìžë±ì€ë í¬ìí ì ìë ìŽì 륌 ì€ëª íëŒ (ë ìœëë¹ íëì ìížëЬ vs. ëžë¡ë¹ íëì ìížëЬ).
ì°ìµë¬žì 2: í ìŽëžì 500,000ê°ì ë ìœëê° ê°ê° 4 KB ëžë¡ì ì ì¥ëìŽ ìë€. ê° ë ìœëë 200ë°ìŽížë€. Ʞ볞 í€ì ëí B+Tree ìžë±ì€ë 8ë°ìŽíž í€ì 8ë°ìŽíž í¬ìží°ë¥Œ ì¬ì©íë€. ê° ìžë±ì€ ë žëë íëì ëžë¡(4 KB)ìŽë€.
(a) íëì ë°ìŽí° ëžë¡ì ëª ê°ì ë ìœëê° ë§ëê°? (b) í ìŽëžì ëª ê°ì ë°ìŽí° ëžë¡ì ì°šì§íëê°? (c) B+Treeì ìµë ë¶êž° ê³ì(ì°šì)ë? (d) B+Treeì ìµë ëìŽë? (e) ìžë±ì€ë¥Œ ì¬ì©í ëë± ê²ì vs. ì 첎 í ìŽëž ì€ìºì ëª ë²ì ëì€í¬ I/Oê° íìíê°?
ì°ìµë¬žì 3: B-Treeì B+Tree륌 ë¹êµíëŒ. ê±°ì 몚ë ë°ìŽí°ë² ìŽì€ ìì€í ìŽ B-Tree ëì B+Tree륌 ì¬ì©íë ìŽì ë?
ì°ìµë¬žì 4: 1ì²ë§ íì ê°ì§ í
ìŽëžìì 8ê°ì ê³ ì ê°ì ê°ì§ color 컬ëŒì ë¹ížë§µ ìžë±ì€ê° ìì±ëìë€.
(a) ë¹ížë§µ ìžë±ì€ì ìŽ ë¹ìì¶ í¬êž°ë? (b) íì 0.1%ë§ color = 'purple'ìŽë©Ž, ë° êžžìŽ ìžìœë©ì ì¬ì©íì¬ purple ë¹ížë§µì ìŒë§ë ìì¶í ì ìëê°? (c) ìŽë¥Œ ëìŒí 컬ëŒì B+Tree ìžë±ì€ì ë¹êµíëŒ.
ì€ì©ì ì§ë¬ž¶
ì°ìµë¬žì 5: ë€ì 쿌늬 ìí¬ë¡ëì ëí ìžë±ì± ì ëµì ì€ê³íëŒ:
-- Q1 (ížëíœì 90%): ì íí ì¡°í
SELECT * FROM users WHERE email = ?;
-- Q2 (ížëíœì 5%): ì ë ¬ì í¬íší ë²ì ì€ìº
SELECT name, created_at FROM users
WHERE created_at > ? ORDER BY created_at DESC LIMIT 20;
-- Q3 (ížëíœì 3%): ë€ì€ ì»¬ëŒ íí°
SELECT * FROM users
WHERE country = ? AND age BETWEEN ? AND ?;
-- Q4 (ížëíœì 2%): í
ì€íž ê²ì
SELECT * FROM users WHERE name ILIKE '%smith%';
ê° ì¿ŒëŠ¬ì ëíŽ ëª ìíëŒ: (a) ìŽë€ ìžë±ì€(ëë ìžë±ì€ë€)륌 ìì±í ê²ìžê°? (b) ìŽë€ íì ì ìžë±ì€(B+Tree, íŽì, GIN ë±)? (c) ë³µí©, 컀ë²ë§, ëë ë¶ë¶ ìžë±ì€ë¥Œ ì¬ì©í ê²ìžê°?
ì°ìµë¬žì 6: ì ì ê¹ìŽ 2, ë²í· ì©ë 2ìž ë€ì íì¥ ê°ë¥ íŽì ëë í ëŠ¬ê° ì£ŒìŽì¡ë€:
ëë í 늬: ë²í·:
00 â ë²í· A [h=00110, h=00010] (ë¡ì»¬ ê¹ìŽ 2)
01 â ë²í· B [h=01100] (ë¡ì»¬ ê¹ìŽ 2)
10 â ë²í· C [h=10001, h=10110] (ë¡ì»¬ ê¹ìŽ 2)
11 â ë²í· D [h=11000] (ë¡ì»¬ ê¹ìŽ 2)
íŽì ê° h = 00001ì ê°ì§ ë ìœë륌 ìœì
í í ëë í 늬ì ë²í·ì ìí륌 볎ì¬ëŒ.
ì°ìµë¬žì 7: 4ê°ì ìŽêž° ë²í·(N=4), ë¶í í¬ìží° s=0, ë²í· ì©ë 2ìž ì í íŽì± ë°©ìì ê³ ë €íëŒ. íŽì íšìë hâ(K) = K mod 4ì hâ(K) = K mod 8ìŽë€. ë€ììŒë¡ ìì:
ë²í· 0: [8, 16] (êœ ì°ž)
ë²í· 1: [5]
ë²í· 2: [10]
ë²í· 3: [7, 15] (êœ ì°ž)
í€ 12, 9, 3ì (íëì©) ìœì í í ìí륌 볎ì¬ëŒ.
ë¶ì ì§ë¬ž¶
ì°ìµë¬žì 8: ì°šì m곌 nê°ì í€ë¥Œ ê°ì§ B+Treeì ëìŽê° ìµë âlog_{âm/2â}(n)âìì ìŠëª
íëŒ.
ì°ìµë¬žì 9: ë°ìŽí°ë² ìŽì€ êŽëЬìê° 5ì²ë§ íì ê°ì§ í
ìŽëžìì SELECT COUNT(*) FROM orders WHERE status = 'pending' ì¿ŒëŠ¬ê° 2ìŽ ê±žëŠ°ë€ë ê²ì ë°ê²¬íë€. status 컬ëŒì 5ê°ì ê³ ì ê°ì ê°ì§ë€. ìžë±ì± ì ëµì ê¶ì¥íê³ ê°ì ì ì¶ì íëŒ.
ì°ìµë¬žì 10: sensor_data í
ìŽëžì 10ìµ ê°ì í, ì»¬ëŒ (sensor_id, timestamp, value, location_x, location_y)ê° ìê³ , ë€ì 쿌늬 íšíŽìŽ ìë€:
- ìê° ë²ì 쿌늬:
WHERE timestamp BETWEEN ? AND ? - ìŒìë³ ì¿ŒëŠ¬:
WHERE sensor_id = ? AND timestamp BETWEEN ? AND ? - ê³µê° ì¿ŒëŠ¬:
WHERE location_x BETWEEN ? AND ? AND location_y BETWEEN ? AND ? - ì§ê³:
SELECT sensor_id, AVG(value) FROM ... GROUP BY sensor_id
í¬êŽì ìž ìžë±ì± ì ëµì ì€ê³íëŒ. B+Tree, BRIN, GiST, ë³µí© ìžë±ì€ë¥Œ ê³ ë €íëŒ. ì íì ì ë¹ííëŒ.
ìŽì : ì§ì ì²ëЬì ìµì í | ë€ì: ížëìì ìŽë¡