10_Oct_2021 πŸ°μ—˜λ¦¬μŠ€ AI νŠΈλž™ TIL: 자료ꡬ쑰 (ν•΄μ‹œ ν…Œμ΄λΈ”)

μœ ν™˜μ΅Β·2021λ…„ 10μ›” 13일
1

ν•΄μ‹œν…Œμ΄λΈ”

각 데이터λ₯Ό κ³ μœ ν•œ key에 λŒ€μ‘ν•˜λ„λ‘ μ €μž₯ν•˜λŠ” κ°œλ…μ΄λ‹€.

# key-value Store에 μ €μž₯된 데이터에 key둜 μ ‘κ·Ό

{key: 32501, value: {
	name: Alex,
    	score: 100,
    	...
	}
}

key-Value μŒμ„ μž…λ ₯ν•˜λŠ” 연산은 put, νŠΉμ • key의 valueλ₯Ό μ‘°νšŒν•˜λŠ” 연산은 get이라고 μ •μ˜ν•œλ‹€.

λ°°μ—΄μ˜ indexλ₯Ό key둜 μ΄μš©ν•˜κΈ°

배열에 valueλ₯Ό μ €μž₯ν•˜κ³ , λ°°μ—΄μ˜ 인덱슀λ₯Ό Key둜 μ΄μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•œλ‹€λ©΄:

DB = kvStore()
DB.put(2,7)

myVal = [0,0,7,0,3,0,0,]

DB.get(4)
# 3

이런 μ‹μœΌλ‘œ κ°€λŠ₯ν•  것이닀.

κ·ΈλŸ¬λ‚˜ μ—¬λŸ¬ κ²½μš°μ—μ„œ 문제점이 λ°œμƒν•œλ‹€.

  • λ°°μ—΄μ˜ 크기λ₯Ό λ²—μ–΄λ‚œ μΈλ±μŠ€μ— μš”μ†Œλ₯Ό μΆ”κ°€ν•΄μ•Ό ν•  경우 λ°œμƒν•œλ‹€.
DB.put(100,2)

기쑴의 λ°°μ—΄μ˜ ν¬κΈ°λŠ” 7인데, 인덱슀 100λ²ˆμ— 값을 μΆ”κ°€ν•΄μ•Όν•˜λŠ” 경우, λ°°μ—΄μ˜ 크기λ₯Ό 101κΉŒμ§€ 늘렀 인덱슀 100의 곡간을 λ§Œλ“€μ–΄ μ€€ 후에야 μš”μ†Œλ₯Ό 넣을 수 μžˆλ‹€. λ”°λΌμ„œ, λΉ„νš¨μœ¨μ μ΄λ‹€.

  • valueκ°€ μ—†λŠ” μΈλ±μŠ€μ— getν•˜λŠ” κ²½μš°μ—λ„ λ¬Έμ œκ°€ λ°œμƒν•œλ‹€. ``
    db.get(3)
    myVal = [1,null,7,null,5] `` μœ„μ™€ 같은 이유둜, λ°°μ—΄λ‘œ ν•΄μ‹œν…Œμ΄λΈ”μ„ κ΅¬ν˜„ν•œλ‹€λ©΄
    • μ΅œμ„ μ˜ 경우, 자료의 μ“°κΈ° 연산이 λΉ λ₯΄λ‹€
    • 자료의 읽기 연산이 λΉ λ₯΄λ‹€.
    와 같은 μž₯점이 μžˆμ§€λ§Œ , λ‹¨μ μœΌλ‘œλŠ”
    • 'μžλ£Œκ°€ 없을 경우'λ₯Ό ν‘œν˜„ν•˜λŠ” 것이 쉽지 μ•Šλ‹€
    • 곡간이 μ§€λ‚˜μΉ˜κ²Œ 낭비될 μˆ˜μžˆλ‹€.
    λŠ” 점이 κ³΅μ‘΄ν•œλ‹€.

2개의 배열을 ν™œμš©ν•˜λŠ” 경우

keyλ₯Ό μ €μž₯ν•˜λŠ” λ°°μ—΄κ³Ό valueλ₯Ό μ €μž₯ν•˜λŠ” 배열을 λ”°λ‘œ μƒμ„±ν•˜μ—¬ μ €μž₯ν•˜λŠ” 방법을 μ±„νƒν•œλ‹€λ©΄

DB =kvStore()
DB.put(4,8)

# ν‚€λ₯Ό μ €μž₯ν•˜λŠ” λ°°μ—΄
myKey = [2,3]

#값을 μ €μž₯ν•˜λŠ” λ°°μ—΄
myVal = [1,7]

#곡간을 μ–΄λ§ˆλ¬΄μ‹œν•˜κ²Œ 늘릴 ν•„μš”κ°€ μ—†λ‹€.
DB.put(100,2)

myKey = [2,3,100]

myVal = [1,7,2]

DB.get(3)

# 3의 인덱슀 번호 1을 κΈ°μ–΅ν•˜κ³ 
myKey = [2,3,100]

# 같은 인덱슀 μœ„μΉ˜μ˜ 값을 μ°ΎλŠ”λ‹€.
myVal = [1,7,8]

μœ„ λ°©λ²•μ˜ μž₯단점

μž₯점:

  • κ³΅κ°„μ˜ λ‚­λΉ„κ°€ μ—†λ‹€.
  • μžλ£Œκ°€ μ—†λŠ” κ²½μš°λ„ ν‘œν˜„ν•  수 μžˆλ‹€.

단점:

  • 자료의 읽기 연산이 λŠλ¦¬λ‹€.

  • 자료의 μ“°κΈ° 연산도 λŠλ¦¬λ‹€.

    ν•΄μ‹œ (hash)

    ν•΄μ‹œλž€ μž„μ˜ 데이터에 ν•΄μ‹œ ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ κ³ μ •λœ 길이의 λ°μ΄ν„°λ‘œ λ³€ν™˜ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€.

    λ³€ν™˜ν•˜λŠ” κ³Όμ • 자체λ₯Ό ν•΄μ‹±(hashing), λ³€ν™˜λœ 값을 ν•΄μ‹œ 값이라고 λΆ€λ₯Έλ‹€.

ν•΄μ‹± μ˜ˆμ‹œ (SHA-256 μ•Œκ³ λ¦¬μ¦˜)

ν•΄μ‹œ μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ μ•Œλ €μ§„ λŒ€ν‘œμ μΈ μ˜ˆμ‹œλŠ” SHA-256이 μžˆλ‹€.

원본 : a
ν•΄μ‹œ κ°’: ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
#μ•”ν˜Έν™”

python λ‚΄μž₯ ν•¨μˆ˜

파이썬 λ‚΄μž₯ ν•¨μˆ˜ hash()λ₯Ό μ΄μš©ν•˜μ—¬ μž„μ˜μ˜ κ°’μ˜ ν•΄μ‹œ κ°’(μ •μˆ˜)을 μ•Œ 수 μžˆλ‹€.
파이썬의 hash() ν•¨μˆ˜λŠ” λ³΄μ•ˆμ„ 이유둜 ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ λ°˜ν™˜κ°’μ΄ 달라진닀.


ν•΄μ‹œλ₯Ό μ΄μš©ν•˜μ—¬ Key-Value Storeλ₯Ό κ΅¬ν˜„ν•  수 μžˆλŠ”λ°, ν•΄μ‹œλ₯Ό μ΄μš©ν•˜μ—¬ κ΅¬ν˜„λœ
Key-Value Storeλ₯Ό ν•΄μ‹œ ν…Œμ΄λΈ”(Hash Table) λ˜λŠ” λ”•μ…”λ„ˆλ¦¬(Dictionary)라고 ν•œλ‹€.

가끔 μΈλ±μŠ€κ°€ κ²ΉμΉ˜λŠ” ν•΄μ‹œ 좩돌의 λ¬Έμ œλ„ λ°œμƒν•˜κΈ°λ„ ν•œλ‹€..

ν•΄μ‹œ ν•¨μˆ˜μ˜ 좩돌 문제 (λΉ„λ‘˜κΈ°μ§‘μ˜ 원리)

쒋은 ν•΄μ‹œ ν•¨μˆ˜λŠ” μ€‘λ³΅λ˜λŠ” ν•΄μ‹œ 값이 μ΅œλŒ€ν•œ 없도둝 ν•΄μ„œ, λ˜λ„λ‘ 좩돌이 λ°œμƒν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜μ΄λ‹€.

κ·ΈλŸ¬λ‚˜ ν•΄μ‹œ ν•¨μˆ˜μ˜ λ°˜ν™˜ κ°’μ˜ 경우의 μˆ˜λŠ” μœ ν•œν•˜κ³ , μž…λ ₯κ°’μ˜ 경우의 μˆ˜λŠ” λ¬΄ν•œν•˜κΈ° λ•Œλ¬Έμ— μΆ©λŒμ€ μ–΄μ©” 수 없이 λ°œμƒν•œλ‹€.

λΉ„λ‘˜κΈ° μ§‘μ˜ 원리:

n개의 λΉ„λ‘˜κΈ° 집에 (n+1)마리의 λΉ„λ‘˜κΈ°λ₯Ό ν•œ 집에 ν•œ λ§ˆλ¦¬μ”© λ„£λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” 원리λ₯Ό λ§ν•œλ‹€.
λΉ„λ‘˜κΈ°κ°€ μ΅œλŒ€ 1λ§ˆλ¦¬μ”© λ“€μ–΄μžˆλŠ” λΉ„λ‘˜κΈ° 집이 n개 μžˆλ‹€λ©΄ 전체 λΉ„λ‘˜κΈ°μ§‘μ—λŠ” λΉ„λ‘˜κΈ°κ°€ λ§Žμ•„μ•Ό n마리 μ‘΄μž¬ν•œλ‹€.
λ”°λΌμ„œ (n+1)마리의 λΉ„λ‘˜κΈ°λ₯Ό n개의 λΉ„λ‘˜κΈ°μ§‘μ— ν•œ λ§ˆλ¦¬μ”© λ„£λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€.

μ˜ˆμ‹œ:
μ—°λ½μ²˜μ— μžˆλŠ” μ‚¬λžŒ 366λͺ…μ˜ 생일을 μ˜¬ν•΄ 달λ ₯에 적을 경우, μ˜¬ν•΄κ°€ μœ€λ…„μ΄ μ•„λ‹ˆκ³ , 2μ›” 29일이 생일인 μ‚¬λžŒμ΄ μ—†λ‹€λ©΄ ν•œ λ‚ μ§œμ— 두 μ‚¬λžŒμ˜ 이름을 적어야 ν•˜λŠ” κ²½μš°κ°€ λ°˜λ“œμ‹œ 생긴닀.

ν•΄μ‹œ 좩돌 ν•΄κ²° 방법: κ°œλ³„ 체이닝

κ°œλ³„ 체이닝

κ°œλ³„ 체이닝 방식을 μ‚¬μš©ν•˜λ©΄, 볡수의 킀값이 ν•΄μ‹œ ν•¨μˆ˜λ₯Ό 톡해 Key-Value Storeμ—μ„œ 같은 ν‚€λ‘œ μ €μž₯이 λœλ‹€ ν•˜λ”λΌλ„, 값을 μ—°κ²°(체이닝)ν•˜μ—¬ μΆ©λŒμ„ ν”Όν•  수 μžˆλ‹€. getν•¨μˆ˜λ₯Ό 톡해 Key-Value Store에 같은 ν‚€λ‘œ μ €μž₯된 볡수의 값이 μ‘΄μž¬ν•  경우, μ°ΎλŠ” 값이 아닐 경우 체이닝 된 λ‹€λ₯Έ 값을 찾을 수 μžˆλ‹€.

μ •λ¦¬ν•œλ‹€λ©΄, κ°œλ³„ 체이닝은 Key-Value Store의 각 인덱슀λ₯Ό 'μ—°κ²° 리슀트'둜 λ§Œλ“€μ–΄μ„œ λ™μΌν•œ 인덱슀의 값듀을 μ—°κ²°ν•˜λŠ” 방법이닀.

μ˜€ν”ˆ μ–΄λ“œλ ˆμ‹± (Open Addressing)

좩돌이 λ°œμƒν–ˆμ„ λ•Œ 자료λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•΄ 빈 곡간을 νƒμƒ‰ν•˜λŠ” 방식.
λ”°λΌμ„œ λͺ¨λ“  μ›μ†Œκ°€ μžμ‹ μ˜ ν•΄μ‹œ κ°’κ³Ό μΌμΉ˜ν•˜λŠ” μΈλ±μŠ€μ— μ €μž₯λœλ‹€λŠ” 보μž₯은 μ—†λ‹€.

좩돌이 λ°œμƒν•  경우, μžλ£ŒλŠ” κ°€μž₯ κ°€κΉŒμš΄ 빈 곡간을 νƒμƒ‰ν•˜μ—¬ μ›λž˜ μΈλ±μŠ€μ™€λŠ” λ‹€λ₯Έ μΈλ±μŠ€μ— μ €μž₯λœλ‹€.

μ˜€ν”ˆ μ–΄λ“œλ ˆμ‹±μ—μ„œ 빈 곡간을 μ°ΎλŠ” 방법은 μ—¬λŸ¬ 가지가 μžˆμ§€λ§Œ κ°€μž₯ κ°„λ‹¨ν•˜κ³  λŒ€ν‘œμ μΈ 방법은 'μ„ ν˜• 탐사 방식'.

μ›λž˜ 인덱슀의 λ‹€μŒ μΈλ±μŠ€λΆ€ν„° νƒμƒ‰ν•˜μ—¬ κ°€μž₯ κ°€κΉŒμš΄ 빈 곡간을 μ°ΎλŠ” 방법이닀.

ν•΄λ‹Ή 방법은 Pythonμ—μ„œ λ”•μ…”λ„ˆλ¦¬μ˜ ν•΄μ‹œ κ°’ 좩돌이 λ°œμƒν•˜μ˜€μ„ λ•Œ ν•΄κ²°ν•˜λ„λ‘ κ΅¬ν˜„λ˜μ–΄ μžˆλ‹€.

ν•œ 쀄평: λŒ€κ°•μœΌλ‘œλ§Œ μ•Œκ³  μžˆμ—ˆλ˜ ν•΄μ‹œ ν…Œμ΄λΈ” μžλ£Œκ΅¬μ‘°μ™€ 좩돌 문제의 ν•΄κ²° 방법에 λŒ€ν•œ κΈ°λ°˜μ„ λ‹€μ§ˆ 수 μžˆμ–΄ μœ μ΅ν•œ ν•™μŠ΅μ΄μ—ˆλ‹€.

profile
μ‚¬μš©μžμ˜ 편의λ₯Ό 더 μƒκ°ν•˜κ³  νŽΈμ•ˆν•œ UI/UX κ°œλ°œμ„ κΏˆκΎΈλŠ” ν”„λ‘ νŠΈμ—”λ“œ 개발자 μ§€λ§μƒμž…λ‹ˆλ‹€.

0개의 λŒ“κΈ€