Design Proximity Service

์š”๊ตฌ์‚ฌํ•ญ

  • ์ฃผ์–ด์ง„ ๋ฐ˜๊ฒฝ ๋‚ด ๋…ธ๋“œ(์‚ฌ์—…์žฅ)์„ ์ฐพ๋Š” ์„œ๋น„์Šค

  • ์ตœ๋Œ€ ํ—ˆ์šฉ ๋ฐ˜๊ฒฝ 20km(์„ ํƒ์— ๋”ฐ๋ผ ๊ทธ ์•„๋ž˜๋กœ ์„ค์ • ๊ฐ€๋Šฅ, 0.5, 1, 2, 5, 20km)

  • ๋…ธ๋“œ(์‚ฌ์—…์ž) ์ •๋ณด๋Š” ์‚ฌ์šฉ์ž(์‚ฌ์—…์žฅ ์†Œ์œ ์ฃผ)๊ฐ€ ์ถ”๊ฐ€/์‚ญ์ œ/์ˆ˜์ • ๊ฐ€๋Šฅ

  • ๋ณ€๊ฒฝ๋„๋‹ˆ ์ •๋ณด๋Š” ๋‹ค์Œ๋‚  ๋ฐ˜์˜

๊ธฐ๋Šฅ ๋ชฉ๋ก

์œ„์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถฉ์กฑ ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์‚ฌ์šฉ์ž ์œ„์ฒด์™€ ๊ฒ€์ƒ‰ ๋ฐ˜๊ฒฝ ์ •๋ณด์— ๋งค์น˜๋˜๋Š” ๋…ธ๋“œ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ

  • ์‚ฌ์šฉ์ž๊ฐ€ ๋…ธ๋“œ ์ถ”๊ฐ€/์‚ญ์ œ/์ˆ˜์ • ์‹œ ํ•ด๋‹น ์ •๋ณด๋ฅผ ์ €์žฅ

  • ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ƒ์„ธ ์ •๋ณด ์กฐํšŒ

๋˜ํ•œ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์˜ ์‚ฌํ•ญ๋“ค์„ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค.

  • ๋‚ฎ์€ ์‘๋‹ต ์ง€์—ฐ: ์ฃผ๋ณ€ ๋…ธ๋“œ๋ฅผ ๋น ๋ฅด๊ฒŒ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ

  • ๊ณ ๊ฐ€์šฉ์„ฑ ๋ฐ ๊ทœ๋ชจ ํ™•์žฅ์„ฑ: ํŠธ๋ž˜ํ”ฝ์ด ๊ธ‰์ฆํ•ด๋„ ์„œ๋น„์Šค๊ฐ€ ์ค‘๋‹จ๋˜์ง€ ์•Š์•„์•ผ ํ•จ

๊ฐœ๋žต์  ๊ทœ๋ชจ ์ถ”์ •

DAU 1์–ต ๋ช…, ๋“ฑ๋ก๋œ ๋…ธ๋“œ ์ˆ˜ 2์–ต ๊ฐœ, ํ•˜๋ฃจ 5ํšŒ ๊ฒ€์ƒ‰์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜์˜€์„ ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทœ๋ชจ๋ฅผ ๊ฐ€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • 1์–ต * 5ํšŒ /86,400์ดˆ(1์ผ) = ์•ฝ 5800QPS

API ์„ค๊ณ„

GET /search/nearby

ํŠน์ • ๊ฒ€์ƒ‰ ๊ธฐ์ค€์— ๋งž๋Š” ๋…ธ๋“œ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๋Š” API, ์š”์ฒญ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์š”์ฒญ ๋งค๊ฐœ ๋ณ€์ˆ˜

    • latitude: ์œ„๋„

    • longitude: ๊ฒฝ๋„

    • radius: ๊ฒ€์ƒ‰ ๋ฐ˜๊ฒฝ

  • ๋ฐ˜ํ™˜ ๊ฐ’

    • total: ๊ฒ€์ƒ‰๋œ ๋…ธ๋“œ ์ˆ˜

    • nodes: ๊ฒ€์ƒ‰๋œ ๋…ธ๋“œ ๋ชฉ๋ก(๋„๋ฉ”์ธ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ์ด๋ฆ„ ์‚ฌ์šฉ)

๋…ธ๋“œ์˜ ์ƒ์„ธ ์ •๋ณด ์กฐํšŒ ๋ฐ ์ถ”๊ฐ€/์‚ญ์ œ/์ˆ˜์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ API๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋…ธ๋“œ ๊ด€๋ จ API

  • GET /nodes/:id: ๋…ธ๋“œ ์ƒ์„ธ ์ •๋ณด ์กฐํšŒ

  • POST /nodes: ๋…ธ๋“œ ์ถ”๊ฐ€

  • PUT /nodes/:id: ๋…ธ๋“œ ์ˆ˜์ •

  • DELETE /nodes/:id: ๋…ธ๋“œ ์‚ญ์ œ

๋ฐ์ดํ„ฐ ๋ชจ๋ธ

๋Œ€๋ถ€๋ถ„์˜ ๊ทผ์ ‘์„ฑ ์„œ๋น„์Šค๋Š” ๋‹ค์Œ ๊ธฐ๋Šฅ์˜ ์ด์šฉ ๋นˆ๋„๊ฐ€ ๊ต‰์žฅํžˆ ๋†’๋‹ค.

  • ์ฃผ๋ณ€ ๋…ธ๋“œ ๊ฒ€์ƒ‰

  • ๋…ธ๋“œ ์ƒ์„ธ ์ •๋ณด ์กฐํšŒ

์ฝ๊ธฐ ์—ฐ์‚ฐ์ด ๋งŽ์ด ์ˆ˜ํ–‰๋˜๋Š” ๋ฐ˜๋ฉด, ๋…ธ๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์ˆ˜์ •๋˜๋Š” ์“ฐ๊ธฐ ์—ฐ์‚ฐ์˜ ๋นˆ๋„๋Š” ๋‚ฎ๊ธฐ ๋•Œ๋ฌธ์— MySQL๊ณผ ๊ฐ™์€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ ํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„ํ‚คํ…์ฒ˜

์œ„์น˜ ๊ธฐ๋ฐ˜ ์„œ๋น„์Šค์˜ ๊ณ„๋žต์  ์„ค๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

Proximity Service Architecture

๊ฐ ์ปดํฌ๋„ŒํŠธ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  • ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ: ์œ ์ž… ํŠธ๋ž˜ํ”ฝ์„ ์ž๋™์œผ๋กœ ์•Œ๋งž๋Š” ์„œ๋น„์Šค๋กœ ์ „๋‹ฌ

  • ์œ„์น˜ ๊ธฐ๋ฐ˜ ์„œ๋น„์Šค(Location-Based Service): ์œ„์น˜์™€ ๋ฐ˜๊ฒฝ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด ์ฃผ๋ณ€ ๋…ธ๋“œ ๊ฒ€์ƒ‰

    • ์“ฐ๊ธฐ ์š”์ฒญ์ด ์—†๋Š” ์ฝ๊ธฐ ์š”์ฒญ๋งŒ ์ฒ˜๋ฆฌํ•˜๋Š” ์„œ๋น„์Šค

    • ๋†’์€ QPS

    • ๋ฌด์ƒํƒœ ์„œ๋น„์Šค๋กœ ์ˆ˜ํ‰์  ๊ทœ๋ชจ ํ™•์žฅ ์šฉ์ด

  • ๋…ธ๋“œ ์„œ๋น„์Šค: ๋…ธ๋“œ ์ถ”๊ฐ€/์‚ญ์ œ/์ˆ˜์ •์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์„œ๋น„์Šค

    • ์ƒ๋Œ€์ ์œผ๋กœ ๋‚ฎ์€ QPS

    • ๋…ธ๋“œ ์ƒ์„ธ ์กฐํšŒ๊ฐ€ ๋นˆ๋ฒˆํžˆ ๋ฐœ์ƒํ•˜๋Š” ์‹œ๊ฐ„๋Œ€์— QPS๊ฐ€ ๋†’์•„์งˆ ์ˆ˜ ์žˆ์Œ

    • ๋ฌด์ƒํƒœ ์„œ๋น„์Šค๋กœ ์ˆ˜ํ‰์  ๊ทœ๋ชจ ํ™•์žฅ ์šฉ์ด

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํด๋Ÿฌ์Šคํ„ฐ: ์ฃผ-๋ถ€(primary-secondary) ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ

    • ์ฃผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์“ฐ๊ธฐ ์š”์ฒญ ์ฒ˜๋ฆฌ / ๋ถ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ฝ๊ธฐ ์š”์ฒญ ์ฒ˜๋ฆฌ

    • ๋ณต์ œ์— ์‹œ๊ฐ„์ด ์†Œ์š”๋˜์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋น„์Šค๋Š” ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š์•„๋„ ๋ฌด๋ฐฉ

์ฃผ์š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋‘ ๊ฐœ์˜ ์„œ๋ฒ„(LBS / ๋…ธ๋“œ ์„œ๋น„์Šค)๊ฐ€ ๋ฌด์ƒํƒœ ์„œ๋น„์Šค๋กœ ์„ค๊ณ„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŠธ๋ž˜ํ”ฝ์— ๋”ฐ๋ฅธ ์ˆ˜ํ‰์  ๊ทœ๋ชจ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ฃผ๋ณ€ ๋…ธ๋“œ ๊ฒ€์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋งŽ์€ ํšŒ์‚ฌ๊ฐ€ Redis Geohash๋‚˜ PostGIS ํ™•์žฅ ์„ค์น˜ํ•œ Postgres ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ํ™œ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ๋•Œ๋ฌธ์— ์ง์ ‘์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ, ๋Œ€๋žต์ ์ธ ์œ„์น˜ ์ƒ‰์ธ์„ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋“ค์„ ์•Œ์•„๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1. 2์ฐจ์› ๊ฒ€์ƒ‰

์ฃผ์–ด์ง„ ๋ฐ˜๊ฒฝ ์•ˆ์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ, ์ง๊ด€์ ์ด์ง€๋งŒ ๋‹จ์ˆœํ•˜๊ณ  ๋А๋ฆฌ๋‹ค.

SELECT *
FROM nodes
WHERE (latitute BETWEEN :my_lat - :radius AND :my_lat + :radius)
  AND (longitude BETWEEN :my_lon - :radius AND :my_lon + :radius)

์กฐํšŒํ•˜๊ธฐ ์œ„ํ•ด์„  ์œ„ ์ฟผ๋ฆฌ๊ฐ€ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ, ํ…Œ์ด๋ธ” ์ „๋ถ€๋ฅผ ์ฝ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋А๋ฆฌ๋‹ค. latitute์™€ longitude ์ปฌ๋Ÿผ์— ์ธ๋ฑ์Šค๋ฅผ ๊ฑธ๋”๋ผ๋„ ๋‘ ๊ฐœ์˜ ๊ต์ง‘ํ•ฉ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋А๋ฆฌ๋‹ค.

๊ฒฐ๊ตญ์—” ํ•œ ์ฐจ์›์˜ ๊ฒ€์ƒ‰ ์†๋„๋งŒ ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— 2์ฐจ์›์—์„œ์˜ ๊ฒ€์ƒ‰์—์„œ๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ๋‹ค.

2. ๊ท ๋“ฑ ๊ฒฉ์ž

์ง€๋„๋ฅผ ๋‹จ์ˆœํžˆ ์ž‘์€ ๊ฒฉ์ž ๋˜๋Š” ๊ตฌํš์œผ๋กœ ๋‚˜๋ˆ„์–ด ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ, ๊ฐ ๊ตฌํš์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•ด ๋‘๊ณ  ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ• ๋˜ํ•œ ๋…ธ๋“œ๋“ค์˜ ๋ถ„ํฌ๊ฐ€ ๊ท ๋“ฑํ•˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์— ํšจ์œจ์ ์ด์ง€ ์•Š๋‹ค.

3. ์ง€์˜คํ•ด์‹œ

2์ฐจ์›์˜ ์œ„๋„ ๊ฒฝ๋„ ๋ฐ์ดํ„ฐ๋ฅผ 1์ฐจ์› ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ, ์ง€๋„๋ฅผ ์ž‘์€ ๊ฒฉ์ž๋กœ ๋ถ„ํ• ํ•ด๊ฐ€๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋‘ ๊ฐœ์˜ ๋น„ํŠธ๋กœ ๋‚˜๋ˆ„์—ˆ์„ ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜๋‰  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

| 01 | 11 |
|----+----|
| 00 | 10 |

์ด๊ฑธ ๋‹ค์‹œ ์žฌ๊ท€์ ์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋‚˜๊ฐ€๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.

| 01 01 | 01 11 | 11 01 | 11 11 |
|-------+-------+-------+-------|
| 01 00 | 01 10 | 11 00 | 11 10 |
|-------+-------+-------+-------|
| 00 00 | 00 11 | 10 01 | 10 11 |
|-------+-------+-------+-------|
| 00 00 | 00 10 | 10 00 | 10 10 |

์ด ์ ˆ์ฐจ๋ฅผ ์›ํ•˜๋Š” ์ •๋ฐ€๋„(precision)๋ฅผ ์–ป์„ ๋•Œ ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๋ฉด, ๋Š˜์–ด๋‚˜๋Š” ๋น„ํŠธ ์ˆ˜ ๋งŒํผ ๋” ์ •๋ฐ€ํ•œ ์œ„์น˜ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์ง€์˜คํ•ด์‹œ ๊ธธ์ด
๊ฒฉ์ž ๋„ˆ๋น„ * ๋†’์ด

1

5,009.4km * 4,992.6km(์ง€๊ตฌ ์ „์ฒด)

2

1,252.3km * 624.1km

3

156.5km * 156km

4

39.1km * 19.5km

5

4.9km * 4.9km

6

1.2km * 609.4m

7

152.9m * 152.4m

8

38.2m * 19m

9

4.8m * 4.8m

10

1.2m * 59.5cm

11

14.9cm * 14.9cm

12

3.7cm * 1.9cm

์ด๋ ‡๊ฒŒ ๋‚˜์˜จ ์ง€์˜คํ•ด์‹œ๋Š” ํ†ต์ƒ์ ์œผ๋กœ base32 ํ‘œํ˜„๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๊ธธ์ด 6์˜ ์ง€์˜คํ•ด์‹œ: 1001 11010 01001 10001 11111 11110 -> 9q9hvu

์ง€์ •ํ•œ ๋ฐ˜๊ฒฝ์œผ๋กœ ๊ทธ๋ฆฐ ์›์„ ๋ฎ๋Š” ์ตœ์†Œ ํฌ๊ธฐ ๊ฒฉ์ž๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ตœ์  ์ •๋ฐ€๋„๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์š”๊ตฌ ์‚ฌํ•ญ์˜ ๋ฐ˜๊ฒฝ๊ณผ ์ง€์˜คํ•ด์‹œ ๊ด€๊ณ„๋ฅผ ํ‘œ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋ฐ˜๊ฒฝ
์ง€์˜ค ํ•ด์‹œ ๊ธธ์ด

0.5km

6

1km

5

2km

5

5km

4

20km

4

์ด์™€ ๊ฐ™์ด ์ง€์˜คํ•ด์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋…ธ๋“œ ๊ฒ€์ƒ‰์„ ํšจ์œจ์ ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š” ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์ธ์ ‘ ๊ฒฉ์ž์˜ ํšจ์œจ์ ์ธ ํƒ์ƒ‰: ์ง€์˜คํ•ด์‹œ๋Š” ๊ณต๊ฐ„์„ ๊ณ„์ธต์ ์œผ๋กœ ๋ถ„ํ• ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํŠน์ • ์œ„์น˜์˜ ์ธ์ ‘ ๊ฒฉ์ž๋ฅผ ์‰ฝ๊ฒŒ ๊ณ„์‚ฐ ๊ฐ€๋Šฅ

  2. ๋ฌธ์ž์—ด ๋น„๊ต๋ฅผ ํ†ตํ•œ ๊ฒ€์ƒ‰ ์†๋„ ํ–ฅ์ƒ: ์ง€์˜คํ•ด์‹œ๋Š” base 32 ๋ฌธ์ž์—ด๋กœ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์–ด ๋ฌธ์ž์—ด ๋น„๊ต๋ฅผ ํ†ตํ•ด ๋น ๋ฅด๊ฒŒ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ

์˜ˆ๋ฅผ๋“ค์–ด ํ˜„์žฌ ์œ„์น˜์˜ ์ง€์˜คํ•ด์‹œ ์ฝ”๋“œ๊ฐ€ 9q9hv์ธ ๊ฒฝ์šฐ ํ•ด๋‹น ์ง€์˜คํ•ด์‹œ ํ˜น์€ ์ธ์ ‘ ์ง€์˜คํ•ด์‹œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋…ธ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์ธ์ ‘ํ•œ ๋ชจ๋“  ๊ฒฉ์ž์˜ ์ง€์˜คํ•ด์‹œ ์ฝ”๋“œ๊ฐ€ ๊ณตํ†ต ์ ‘๋‘์–ด๋ฅผ ๊ฐ€์ง€์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ถ”๊ฐ€์ ์ธ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์ด ํ•„์š”ํ•˜๋‹ค.

4. ์ฟผ๋“œํŠธ๋ฆฌ

๊ฒฉ์ž์˜ ๋‚ด์šฉ์ด ํŠน์ • ๊ธฐ์ค€์„ ๋งŒ์กฑํ•  ๋•Œ๊นŒ์ง€ 2์ฐจ์› ๊ณต๊ฐ„์„ ์žฌ๊ท€์ ์œผ๋กœ ์‚ฌ๋ถ„๋ฉด ๋ถ„ํ• ํ• ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์— ๋†“์ด๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘ํ•˜๋Š” ์‹œ์ ์— LBS ์„œ๋ฒ„ ์•ˆ์— ๊ตฌ์ถ•๋œ๋‹ค.

200๋ฐฑ๋งŒ๊ฐœ์˜ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๋•Œ, ์•„๋ž˜์™€ ๊ฐ™์ด ๊ณ„์†ํ•ด์„œ ๋ถ„ํ• ํ•ด ๋‚˜๊ฐ€๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

|-----------------------|
|                       |
|         200๋งŒ๊ฐœ        |
|                       |
|-----------------------|
            |
            |
            โ†“
|-----------------------|
| NW(40๋งŒ๊ฐœ) | NE(30๋งŒ๊ฐœ) |
|-----------+-----------|
| SW(70๋งŒ๊ฐœ) | SE(60๋งŒ๊ฐœ) |
|-----------------------|

์ด๋ฅผ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

    200๋งŒ๊ฐœ
  /  /   \  \
40๋งŒ 30๋งŒ 70๋งŒ 60๋งŒ
   / / \ \
 12 4  5  9   

์ด ๊ณผ์ •์„ ์˜์‚ฌ ์ฝ”๋“œ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

class Quadtree {

    public void buildQuadtree(TreeNode node) {
        if (countNumberOfBusinessesInCurrentGrid(node) > 100) {
            node.subdivide();
            for (TreeNode child : node.getChildren()) {
                buildQuadtree(child);
            }
        }
    }
}

์‹ค์ œ๋กœ ์ฟผ๋“œํŠธ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ์ฃผ๋ณ€ ๋…ธ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์„œ๋ฒ„ ์‹คํ–‰ ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ์ฟผ๋“œํŠธ๋ฆฌ ์ธ๋ฑ์Šค ๊ตฌ์ถ•

  2. ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ์กฐํšŒ ์‹œ์ž‘

  3. ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ ์ค‘ ๊ฒ€์ƒ‰ ๋ฐ˜๊ฒฝ์— ํฌํ•จ๋˜๋Š” ๋…ธ๋“œ ํ™•์ธ ํ›„ ์žฌ๊ท€์ ์œผ๋กœ ํƒ์ƒ‰

  4. ๋ง๋‹จ ๋…ธ๋“œ์— ๋„๋‹ฌํ•˜๋ฉด ํ•ด๋‹น ๋…ธ๋“œ์˜ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜

๋ง๋‹จ ๋…ธ๋“œ์— 100๊ฐœ ์ดํ•˜์˜ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•  ๋•Œ ๊นŒ์ง€ ๊ณ„์†ํ•ด์„œ ๋ถ„ํ• ํ•œ๋‹ค๊ณ  ํ•˜๊ฒŒ๋˜๋ฉด, ๋ฉ”๋ชจ๋ฆฌ๋Š” ์•ฝ 2GB ์ •๋„, ๊ตฌ์ถ•์—๋Š” ๋ช‡ ๋ถ„ ์ •๋„ ์†Œ์š”๋œ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ์—๋Š” ํฐ ๋ฌธ์ œ๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ์œผ๋‚˜, ๊ตฌ์ถ•์—๋Š” ์‹œ๊ฐ„์ด ์–ด๋А์ •๋„ ์†Œ์š”๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋™์‹œ์— ๋งŽ์€ ์„œ๋ฒ„ ๋ฐฐํฌํ•˜์—ฌ ํŠธ๋ž˜ํ”ฝ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•˜๋Š” ์ผ์ด ์—†๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.

๋น„๊ต

1๋ฒˆ์˜ 2์ฐจ์› ๊ฒ€์ƒ‰๊ณผ 2๋ฒˆ์˜ ๊ท ๋“ฑ ๊ฒฉ์ž๋Š” ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ํ•ฉํ•˜์ง€ ์•Š์•„ ์‹ค์ œ๋กœ ๋งŽ์€ ์„œ๋น„์Šค๋“ค์ด ๋‚˜๋จธ์ง€ ์ง€์˜คํ•ด์‹œ๋‚˜ ์ฟผ๋“œํŠธ๋ฆฌ ๋ฐฉ์‹(ํ˜น์€ ํ˜ผ์šฉ)์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ์ง€์˜คํ•ด์‹œ์™€ ์ฟผ๋“œํŠธ๋ฆฌ๋ฅผ ๋น„๊ตํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์ง€์˜คํ•ด์‹œ

    • ๊ตฌํ˜„๊ณผ ์‚ฌ์šฉ์ด ์‰ฌ์›€

    • ์ง€์ • ๋ฐ˜๊ฒฝ ์ด๋‚ด ๋…ธ๋“œ ๊ฒ€์ƒ‰ ์šฉ์ด

    • ์ •๋ฐ€๋„๋ฅผ ๊ณ ์ •ํ•˜๋ฉด ๊ฒฉ์ž ํฌ๊ธฐ๋„ ๊ณ ์ •๋˜์–ด ๋™์ ์œผ๋กœ ๊ฒฉ์ž ํฌ๊ธฐ ์กฐ์ • ๋ถˆ๊ฐ€๋Šฅ(๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋ณต์žกํ•œ ๊ตฌํ˜„ ํ•„์š”)

    • ์ƒ‰์ธ ๊ฐฑ์‹  ์šฉ์ด(๋…ธ๋“œ ์‚ญ์ œ ์‹œ ์—ด ํ•˜๋‚˜๋งŒ ์ œ๊ฑฐํ•˜๋ฉด ๋จ)

  • ์ฟผ๋“œ ํŠธ๋ฆฌ

    • ๊ตฌํ˜„์ด ๋ณต์žกํ•˜๊ณ  ํŠธ๋ฆฌ ๊ตฌ์ถ• ์‹œ๊ฐ„์ด ํ•„์š”

    • ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋…ธ๋“œ ๊ฒ€์ƒ‰ ์šฉ์ด

    • ํŠธ๋ฆฌ ํ˜•ํƒœ์˜ ์ž๋ฃŒ๊ตฌ์กฐ๊ธฐ ๋•Œ๋ฌธ์— ์‚ญ์ œ ์‹œ ๋ณต์žกํ•œ ๊ตฌํ˜„ ํ•„์š”

์ƒ์„ธ ์„ค๊ณ„

์ง€๋ฆฌ ์ •๋ณด ์ƒ‰์ธ ํ…Œ์ด๋ธ” ๊ตฌ์ถ• ๋ฐฉ๋ฒ•

๋…ธ๋“œ ์ƒ์„ธ ์ •๋ณด ํ…Œ์ด๋ธ”: ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ์„œ๋ฒ„์— ๋‹ด์„ ์ˆ˜ ์—†์„ ์ˆ˜๋„ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ƒค๋”ฉ์„ ๊ณ ๋ คํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ง€๋ฆฌ ์ •๋ณด ์ƒ‰์ธ ํ…Œ์ด๋ธ”(์ง€์˜คํ•ด์‹œ ์“ด๋‹ค๊ณ  ๊ฐ€์ •)์˜ ๊ฒฝ์šฐ ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ๋ฐ, ์šฐ์„  ์•„๋ž˜ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌ์ถ• ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ํ•ด๋‹น ์ง€์˜ค ํ•ด์‹œ์— ์—ฐ๊ฒฐ๋˜๋Š” ์‚ฌ์—…์žฅ ID๋ฅผ ๋ฐฐ์—ด๋กœ ๊ด€๋ฆฌ

  • ๋…ธ๋“œ ID์— ์ง€์˜คํ•ด์‹œ๋ฅผ ๊ฐ๊ฐ ์ €์žฅ

๋‘ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋” ๊ถŒ์žฅํ•˜๋Š”๋ฐ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ๋ฐฐ์—ด๋กœ ๊ด€๋ฆฌ๋˜๋Š” ๊ฒฝ์šฐ ๋…ธ๋“œ ์ •๋ณด ๊ฐฑ์‹  ์‹œ ๋ฐฐ์—ด์„ ์ฝ์€ ํ›„ ๊ฐฑ์‹ ํ•  ๋…ธ๋“œ ID๋ฅผ ์ฐพ๋Š” ๋ณ„๋„์˜ ๊ณผ์ • ํ•„์š”

  • ๋…ธ๋“œ ID์— ์ง€์˜คํ•ด์‹œ๋ฅผ ์ €์žฅํ•˜๋ฉด ์‰ฝ๊ฒŒ ์กฐํšŒํ•˜๊ณ  ์ •๋ณด๋ฅผ ์ถ”๊ฐ€/์ˆ˜์ •/์‚ญ์ œ ๊ฐ€๋Šฅ

์ง€๋ฆฌ ์ •๋ณด ์ƒ‰์ธ ํ…Œ์ด๋ธ” ๊ทœ๋ชจ ํ™•์žฅ์„ฑ

๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„์˜ ๋ถ€ํ•˜ ๋ถ„์‚ฐ์—๋Š” ์ƒค๋”ฉ๊ณผ ์‚ฌ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋Š˜๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ์ง€์˜คํ•ด์‹œ ํ…Œ์ด๋ธ”์€ ์ƒค๋”ฉ์ด ๊นŒ๋‹ค๋กญ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋Š˜๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐœ๋ฐœ๋„ ์‰ฝ๊ณ  ๊ด€๋ฆฌ๊ฐ€ ๊ฐ„ํŽธํ•˜๋‹ค.

์ตœ์ข… ๋™์ž‘ ํ๋ฆ„

์ง€์˜คํ•ด์‹œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, ์‚ฌ์šฉ์ž๊ฐ€ ์ฃผ๋ณ€ ๋…ธ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์นœ๋‹ค.

  1. ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ์— ์ฃผ๋ณ€ ๋…ธ๋“œ ๊ฒ€์ƒ‰ ์š”์ฒญ

  2. ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๋Š” LBS ์„œ๋ฒ„์— ์š”์ฒญ ์ „๋‹ฌ

  3. ์ฃผ์–ด์ง„ ์‚ฌ์šฉ์ž ์œ„์น˜์™€ ๋ฐ˜๊ฒฝ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด ์ง€์˜คํ•ด์‹œ ๊ธธ์ด ๊ณ„์‚ฐ(500m์ธ ๊ฒฝ์šฐ ๊ธธ์ด๋Š” 6)

  4. ์ธ์ ‘ํ•œ ์ง€์˜คํ•ด์‹œ๋ฅผ ๊ณ„์‚ฐํ•œ ๋’ค List์— ์ €์žฅ(listOfGeohashes= [9q9hvu, 9q9hvv, 9q9hvs ...])

  5. ํ•ด๋‹น ๋ฆฌ์ŠคํŠธ์— ์žˆ๋Š” ์ง€์˜คํ•ด์‹œ ๊ฐ๊ฐ์— ๋Œ€ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(ํ˜น์€ ์บ์‹œ)์— ์กฐํšŒ ์š”์ฒญ

  6. ์กฐํšŒ๋œ ๋…ธ๋“œ ID๋“ค์„ ํ†ตํ•ด ๋…ธ๋“œ ์ƒ์„ธ ์ •๋ณด ์กฐํšŒ

  7. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ๊ฐ€๊ณต(ํ•ด๋‹น ๋…ธ๋“œ ์ •๋ณด, ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ) ํ›„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฐ˜ํ™˜

์ฐธ๊ณ ์ž๋ฃŒ

Last updated

Was this helpful?