์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐ŸŽฏ MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„์™€ ์ปฌ๋ ‰์…˜ ์ตœ์ ํ™”

๐ŸŽฏ MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„์™€ ์ปฌ๋ ‰์…˜ ์ตœ์ ํ™”

์นœ๊ตฌ์ฒ˜๋Ÿผ ํŽธํ•˜๊ฒŒ ๋ฐฐ์šฐ๋Š” NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„์˜ ๋ชจ๋“  ๊ฒƒ

์•ˆ๋…•! ์˜ค๋Š˜์€ MongoDB๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ˆ„๊ตฌ๋‚˜ ํ•œ ๋ฒˆ์ฏค ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜๋Š” ์Šคํ‚ค๋งˆ ์„ค๊ณ„์™€ ์ปฌ๋ ‰์…˜ ์ตœ์ ํ™”์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด๋ณผ๊นŒ ํ•ด. ๐Ÿ˜Š
์‚ฌ์‹ค MongoDB๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋ฉด "์–ด? ์Šคํ‚ค๋งˆ๊ฐ€ ์—†๋‹ค๊ณ ? ๊ทธ๋Ÿผ ๋ง‰ ๋„ฃ์œผ๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋ƒ?"๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ์‰ฌ์šด๋ฐ, ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์•„.
์˜คํžˆ๋ ค ์ž์œ ๋„๊ฐ€ ๋†’์€ ๋งŒํผ ๋” ์‹ ์ค‘ํ•˜๊ฒŒ ์„ค๊ณ„ํ•ด์•ผ ๋‚˜์ค‘์— ์„ฑ๋Šฅ ๋ฌธ์ œ๋‚˜ ์œ ์ง€๋ณด์ˆ˜ ์ง€์˜ฅ์— ๋น ์ง€์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€.

ํŠนํžˆ ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์™€ ๊ฑฐ๋ž˜ ์ •๋ณด๋ฅผ ๋‹ค๋ฃฌ๋‹ค๋ฉด, ์ฒ˜์Œ๋ถ€ํ„ฐ ์ œ๋Œ€๋กœ ๋œ ์„ค๊ณ„๊ฐ€ ์ •๋ง ์ค‘์š”ํ•ด.
๊ทธ๋ž˜์„œ ์˜ค๋Š˜์€ ์‹ค๋ฌด์—์„œ ๋ฐ”๋กœ ์จ๋จน์„ ์ˆ˜ ์žˆ๋Š” MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ์›์น™๋ถ€ํ„ฐ ์ปฌ๋ ‰์…˜ ์ตœ์ ํ™” ๊ธฐ๋ฒ•๊นŒ์ง€ ์ฐจ๊ทผ์ฐจ๊ทผ ์•Œ์•„๋ณผ ๊ฑฐ์•ผ. ๐Ÿš€

๐Ÿ“Œ ์ด ๊ธ€์—์„œ ๋‹ค๋ฃฐ ๋‚ด์šฉ
  • โœ… MongoDB์˜ ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ์ฒ ํ•™๊ณผ ๊ด€๊ณ„ํ˜• DB์™€์˜ ์ฐจ์ด์ 
  • โœ… ์ž„๋ฒ ๋””๋“œ vs ๋ ˆํผ๋Ÿฐ์Šค ํŒจํ„ด ์„ ํƒ ๊ธฐ์ค€
  • โœ… ์‹ค์ „ ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ํŒจํ„ด๊ณผ ์•ˆํ‹ฐํŒจํ„ด
  • โœ… ์ธ๋ฑ์Šค ์ „๋žต๊ณผ ์ฟผ๋ฆฌ ์ตœ์ ํ™”
  • โœ… ์ปฌ๋ ‰์…˜ ์ƒค๋”ฉ๊ณผ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
  • โœ… ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง๊ณผ ํŠœ๋‹ ํŒ

๐ŸŽจ MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„์˜ ์ฒ ํ•™

๋จผ์ € MongoDB์˜ ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ์ฒ ํ•™๋ถ€ํ„ฐ ์ดํ•ดํ•ด๋ณด์ž.
๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(RDBMS)๋ฅผ ์‚ฌ์šฉํ•ด๋ดค๋‹ค๋ฉด, ์ •๊ทœํ™”(Normalization)๋ผ๋Š” ๊ฐœ๋…์— ์ต์ˆ™ํ•  ๊ฑฐ์•ผ.
๋ฐ์ดํ„ฐ ์ค‘๋ณต์„ ์ตœ์†Œํ™”ํ•˜๊ณ , ํ…Œ์ด๋ธ”์„ ์ž˜๊ฒŒ ์ชผ๊ฐœ์„œ JOIN์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹ ๋ง์ด์•ผ.

ํ•˜์ง€๋งŒ MongoDB๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ํŒจํ„ด์„ ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„ํ•ด์•ผ ํ•ด.
"์ด ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ์กฐํšŒํ•  ๊ฒƒ์ธ๊ฐ€?"๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์งˆ๋ฌธ์ด์ง€.
์™œ๋ƒํ•˜๋ฉด MongoDB๋Š” JOIN ์—ฐ์‚ฐ์ด ์ œํ•œ์ ์ด๊ณ (lookup์€ ์žˆ์ง€๋งŒ ์„ฑ๋Šฅ์ด ์ข‹์ง€ ์•Š์•„), ์ฝ๊ธฐ ์„ฑ๋Šฅ์„ ์ตœ์šฐ์„ ์œผ๋กœ ๊ณ ๋ คํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์•ผ.

๐Ÿ’ก ํ•ต์‹ฌ ์›์น™

1. ํ•จ๊ป˜ ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ํ•จ๊ป˜ ์ €์žฅํ•˜๋ผ
๊ด€๊ณ„ํ˜• DB์ฒ˜๋Ÿผ ๋‚˜๋ˆ„์ง€ ๋ง๊ณ , ์ž์ฃผ ๊ฐ™์ด ์ฝํžˆ๋Š” ๋ฐ์ดํ„ฐ๋Š” ํ•œ ๋ฌธ์„œ์— ๋„ฃ์–ด.

2. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋น„์œจ์„ ๊ณ ๋ คํ•˜๋ผ
์ฝ๊ธฐ๊ฐ€ ๋งŽ์œผ๋ฉด ๋น„์ •๊ทœํ™”๋ฅผ, ์“ฐ๊ธฐ๊ฐ€ ๋งŽ์œผ๋ฉด ์ •๊ทœํ™”๋ฅผ ๊ณ ๋ คํ•ด.

3. ๋ฌธ์„œ ํฌ๊ธฐ์™€ ์„ฑ์žฅ ํŒจํ„ด์„ ์˜ˆ์ธกํ•˜๋ผ
MongoDB ๋ฌธ์„œ๋Š” ์ตœ๋Œ€ 16MB ์ œํ•œ์ด ์žˆ์–ด. ๋ฌดํ•œ์ • ์ปค์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฐฐ์—ด์€ ์ฃผ์˜!
MongoDB vs RDBMS ์„ค๊ณ„ ์ฒ ํ•™ RDBMS ๋ฐฉ์‹ ์ •๊ทœํ™” ์ค‘์‹ฌ ๋ฐ์ดํ„ฐ ์ค‘๋ณต ์ตœ์†Œํ™” ํ…Œ์ด๋ธ” ๋ถ„๋ฆฌ JOIN์œผ๋กœ ์—ฐ๊ฒฐ ์“ฐ๊ธฐ ์ตœ์ ํ™” Users id | name | email Orders (JOIN ํ•„์š”) id | user_id | ... MongoDB ๋ฐฉ์‹ ์ ‘๊ทผ ํŒจํ„ด ์ค‘์‹ฌ ๋น„์ •๊ทœํ™” ํ—ˆ์šฉ ๋ฌธ์„œ์— ์ž„๋ฒ ๋”ฉ JOIN ์ตœ์†Œํ™” ์ฝ๊ธฐ ์ตœ์ ํ™” Users (์ž„๋ฒ ๋””๋“œ) id, name, email orders: [ order_id, amount, ... ]

๐Ÿ”„ ์ž„๋ฒ ๋””๋“œ vs ๋ ˆํผ๋Ÿฐ์Šค: ์˜์›ํ•œ ๊ณ ๋ฏผ

MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜๋Š” ๋ถ€๋ถ„์ด ๋ฐ”๋กœ ์ด๊ฑฐ์•ผ.
"๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฌธ์„œ ์•ˆ์— ๋„ฃ์„๊นŒ(์ž„๋ฒ ๋””๋“œ), ์•„๋‹ˆ๋ฉด ๋ณ„๋„ ์ปฌ๋ ‰์…˜์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์ฐธ์กฐํ• ๊นŒ(๋ ˆํผ๋Ÿฐ์Šค)?" ๐Ÿค”

์ •๋‹ต์€... ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฑฐ์•ผ! (์ด๊ฒŒ ์ œ์ผ ๋‹ต๋‹ตํ•˜์ง€? ใ…Žใ…Ž)
ํ•˜์ง€๋งŒ ๋ช…ํ™•ํ•œ ์„ ํƒ ๊ธฐ์ค€์ด ์žˆ์œผ๋‹ˆ๊นŒ ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ.

๐Ÿ“ฆ ์ž„๋ฒ ๋””๋“œ ํŒจํ„ด (Embedded Documents)

์ž„๋ฒ ๋””๋“œ ํŒจํ„ด์€ ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์˜ ๋ฌธ์„œ ์•ˆ์— ์ค‘์ฒฉ์‹œํ‚ค๋Š” ๋ฐฉ์‹์ด์•ผ.
๋งˆ์น˜ JSON ๊ฐ์ฒด ์•ˆ์— ๋˜ ๋‹ค๋ฅธ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์„ ๋„ฃ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์•ผ.

{
  "_id": ObjectId("507f1f77bcf86cd799439011"),
  "name": "๊น€๊ฐœ๋ฐœ",
  "email": "dev@example.com",
  "address": {
    "street": "ํ…Œํ—ค๋ž€๋กœ 123",
    "city": "์„œ์šธ",
    "zipcode": "06234"
  },
  "orders": [
    {
      "order_id": "ORD001",
      "product": "MongoDB ์™„๋ฒฝ๊ฐ€์ด๋“œ",
      "amount": 35000,
      "date": ISODate("2024-01-15")
    },
    {
      "order_id": "ORD002",
      "product": "Node.js ์‹ค์ „ ํ”„๋กœ์ ํŠธ",
      "amount": 42000,
      "date": ISODate("2024-01-20")
    }
  ]
}
โœ… ์ž„๋ฒ ๋””๋“œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€ ๊ฒฝ์šฐ

1. ์ผ๋Œ€์ผ(1:1) ๊ด€๊ณ„
์‚ฌ์šฉ์ž์™€ ์ฃผ์†Œ์ฒ˜๋Ÿผ ํ•ญ์ƒ ํ•จ๊ป˜ ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ

2. ์ผ๋Œ€๋‹ค(1:N) ๊ด€๊ณ„ ์ค‘ "๋‹ค"๊ฐ€ ์ ์€ ๊ฒฝ์šฐ
๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ์™€ ๋Œ“๊ธ€(๋Œ“๊ธ€์ด ์ˆ˜์‹ญ ๊ฐœ ์ดํ•˜์ผ ๋•Œ)

3. ์ž์‹ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ถ€๋ชจ ์—†์ด ๋…๋ฆฝ์ ์œผ๋กœ ์กฐํšŒ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
์ฃผ๋ฌธ ํ•ญ๋ชฉ์€ ์ฃผ๋ฌธ ์—†์ด ์กฐํšŒํ•  ์ผ์ด ๊ฑฐ์˜ ์—†์ง€

4. ์›์ž์  ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ
ํ•œ ๋ฒˆ์˜ ์“ฐ๊ธฐ ์ž‘์—…์œผ๋กœ ๋ชจ๋“  ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•  ๋•Œ

์ž„๋ฒ ๋””๋“œ ํŒจํ„ด์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ์ฝ๊ธฐ ์„ฑ๋Šฅ์ด์•ผ.
ํ•œ ๋ฒˆ์˜ ์ฟผ๋ฆฌ๋กœ ๋ชจ๋“  ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ ์—„์ฒญ ๋น ๋ฅด์ง€! โšก
์žฌ๋Šฅ๋„ท์—์„œ ์‚ฌ์šฉ์ž ํ”„๋กœํ•„๊ณผ ๊ธฐ๋ณธ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ค„ ๋•Œ, ํ•œ ๋ฒˆ์— ๋‹ค ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ํ›จ์”ฌ ์ข‹์•„์งˆ ๊ฑฐ์•ผ.

โš ๏ธ ์ž„๋ฒ ๋””๋“œ ํŒจํ„ด์˜ ์ฃผ์˜์‚ฌํ•ญ

๋ฌธ์„œ ํฌ๊ธฐ ์ œํ•œ: MongoDB๋Š” ๋ฌธ์„œ๋‹น ์ตœ๋Œ€ 16MB๊นŒ์ง€๋งŒ ์ €์žฅ ๊ฐ€๋Šฅํ•ด.
๋ฐฐ์—ด์ด ๋ฌดํ•œ์ • ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ž„๋ฒ ๋””๋“œ๋Š” ์œ„ํ—˜ํ•ด!

์ค‘๋ณต ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ: ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฌธ์„œ์— ์ž„๋ฒ ๋””๋“œ๋˜๋ฉด,
์—…๋ฐ์ดํŠธํ•  ๋•Œ ๋ชจ๋“  ๋ฌธ์„œ๋ฅผ ์ฐพ์•„์„œ ์ˆ˜์ •ํ•ด์•ผ ํ•ด.

์“ฐ๊ธฐ ์„ฑ๋Šฅ: ํฐ ๋ฌธ์„œ๋ฅผ ์ž์ฃผ ์—…๋ฐ์ดํŠธํ•˜๋ฉด ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์–ด.

๐Ÿ”— ๋ ˆํผ๋Ÿฐ์Šค ํŒจํ„ด (References)

๋ ˆํผ๋Ÿฐ์Šค ํŒจํ„ด์€ ๊ด€๊ณ„ํ˜• DB์˜ ์™ธ๋ž˜ํ‚ค(Foreign Key)์ฒ˜๋Ÿผ,
๋‹ค๋ฅธ ๋ฌธ์„œ์˜ ID๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฐฉ์‹์ด์•ผ.

// users ์ปฌ๋ ‰์…˜
{
  "_id": ObjectId("507f1f77bcf86cd799439011"),
  "name": "๊น€๊ฐœ๋ฐœ",
  "email": "dev@example.com"
}

// orders ์ปฌ๋ ‰์…˜
{
  "_id": ObjectId("507f191e810c19729de860ea"),
  "user_id": ObjectId("507f1f77bcf86cd799439011"),
  "product": "MongoDB ์™„๋ฒฝ๊ฐ€์ด๋“œ",
  "amount": 35000,
  "date": ISODate("2024-01-15")
}

// ์กฐํšŒํ•  ๋•Œ๋Š” $lookup ์‚ฌ์šฉ
db.users.aggregate([
  {
    $lookup: {
      from: "orders",
      localField: "_id",
      foreignField: "user_id",
      as: "user_orders"
    }
  }
])
โœ… ๋ ˆํผ๋Ÿฐ์Šค ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€ ๊ฒฝ์šฐ

1. ๋‹ค๋Œ€๋‹ค(N:M) ๊ด€๊ณ„
ํ•™์ƒ๊ณผ ์ˆ˜์—…, ์ƒํ’ˆ๊ณผ ์นดํ…Œ๊ณ ๋ฆฌ์ฒ˜๋Ÿผ ์–‘๋ฐฉํ–ฅ ๊ด€๊ณ„

2. ์ผ๋Œ€๋‹ค(1:N) ๊ด€๊ณ„ ์ค‘ "๋‹ค"๊ฐ€ ๋งค์šฐ ๋งŽ์€ ๊ฒฝ์šฐ
์‚ฌ์šฉ์ž์™€ ๋กœ๊ทธ ๋ฐ์ดํ„ฐ(์ˆ˜์ฒœ~์ˆ˜๋งŒ ๊ฑด)

3. ์ž์‹ ๋ฐ์ดํ„ฐ๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ์ž์ฃผ ์กฐํšŒ๋˜๋Š” ๊ฒฝ์šฐ
์ƒํ’ˆ ์ •๋ณด๋Š” ์ฃผ๋ฌธ๊ณผ ๋ณ„๊ฐœ๋กœ๋„ ์ž์ฃผ ์กฐํšŒ๋˜์ง€

4. ๋ฐ์ดํ„ฐ ์ค‘๋ณต์„ ์ตœ์†Œํ™”ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
๊ฐ™์€ ์ƒํ’ˆ ์ •๋ณด๊ฐ€ ์ˆ˜์ฒœ ๊ฐœ ์ฃผ๋ฌธ์— ์ค‘๋ณต๋˜๋ฉด ๋น„ํšจ์œจ์ ์ด์•ผ

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

๐ŸŽฏ ์‹ค์ „ ํŒ: ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์ ‘๊ทผ๋ฒ•

์‹ค๋ฌด์—์„œ๋Š” ์ž„๋ฒ ๋””๋“œ์™€ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„!

์˜ˆ๋ฅผ ๋“ค์–ด, ์ฃผ๋ฌธ ๋ฌธ์„œ์— ์ƒํ’ˆ ID๋Š” ๋ ˆํผ๋Ÿฐ์Šค๋กœ ์ €์žฅํ•˜๋˜,
์ž์ฃผ ์กฐํšŒ๋˜๋Š” ์ƒํ’ˆ๋ช…๊ณผ ๊ฐ€๊ฒฉ์€ ์Šค๋ƒ…์ƒท์œผ๋กœ ์ž„๋ฒ ๋””๋“œํ•ด๋‘๋Š” ๊ฑฐ์•ผ.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„์˜ ์กฐํšŒ๋Š” ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ,
์ƒ์„ธ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•  ๋•Œ๋งŒ ์ƒํ’ˆ ์ปฌ๋ ‰์…˜์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์–ด.
์ž„๋ฒ ๋””๋“œ vs ๋ ˆํผ๋Ÿฐ์Šค ์„ ํƒ ๊ฐ€์ด๋“œ ์ž„๋ฒ ๋””๋“œ ์„ ํƒ ํ•จ๊ป˜ ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ ์ž์‹ ๋ฐ์ดํ„ฐ๊ฐ€ ์ ์Œ (์ˆ˜์‹ญ ๊ฐœ ์ดํ•˜) ์ฝ๊ธฐ ์„ฑ๋Šฅ์ด ์ค‘์š” ์›์ž์  ์—…๋ฐ์ดํŠธ ํ•„์š” ์ž์‹์ด ๋ถ€๋ชจ ์—†์ด ์กฐํšŒ ์•ˆ๋จ ๋ ˆํผ๋Ÿฐ์Šค ์„ ํƒ ์ž์‹ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์Œ (์ˆ˜๋ฐฑ ๊ฐœ ์ด์ƒ) ์ž์‹์ด ๋…๋ฆฝ์ ์œผ๋กœ ์กฐํšŒ๋จ ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„ ๋ฐ์ดํ„ฐ ์ค‘๋ณต ์ตœ์†Œํ™” ํ•„์š” ๋ฌธ์„œ ํฌ๊ธฐ ์ œํ•œ ์šฐ๋ ค ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์ ‘๊ทผ๋ฒ• (์ถ”์ฒœ!) ๋ ˆํผ๋Ÿฐ์Šค + ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ์Šค๋ƒ…์ƒท ์ž„๋ฒ ๋”ฉ ์ฃผ๋ฌธ ๋ฌธ์„œ ์˜ˆ์‹œ product_id: ObjectId (๋ ˆํผ๋Ÿฐ์Šค) product_name: ์ƒํ’ˆ๋ช… (์Šค๋ƒ…์ƒท) product_price: 35000 (์Šค๋ƒ…์ƒท) ์žฅ์  ๋Œ€๋ถ€๋ถ„ ์กฐํšŒ๋Š” ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ ์ƒ์„ธ ์ •๋ณด ํ•„์š”์‹œ๋งŒ ์กฐ์ธ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๊ท ํ˜• ์ตœ์ ํ™”

๐ŸŽฏ ์‹ค์ „ ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ํŒจํ„ด

์ด์ œ ์‹ค๋ฌด์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ํŒจํ„ด๋“ค์„ ์•Œ์•„๋ณด์ž.
MongoDB ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ ๊ถŒ์žฅํ•˜๋Š” ๊ฒ€์ฆ๋œ ํŒจํ„ด๋“ค์ด์•ผ! ๐Ÿ“š

๐ŸŒณ ๊ณ„์ธต ๊ตฌ์กฐ ํŒจํ„ด (Tree Pattern)

์นดํ…Œ๊ณ ๋ฆฌ, ์กฐ์ง๋„, ๋Œ“๊ธ€ ์Šค๋ ˆ๋“œ์ฒ˜๋Ÿผ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•ด.
์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”๋ฐ, ์ƒํ™ฉ์— ๋งž๊ฒŒ ์„ ํƒํ•˜๋ฉด ๋ผ.

1๏ธโƒฃ Parent Reference (๋ถ€๋ชจ ์ฐธ์กฐ)

๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ถ€๋ชจ์˜ ID๋งŒ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹. ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ณ  ์ง๊ด€์ ์ด์•ผ.
{
  "_id": "MongoDB",
  "parent": "Databases"
}
{
  "_id": "Databases",
  "parent": "Programming"
}
{
  "_id": "Programming",
  "parent": null
}

๋ถ€๋ชจ๋ฅผ ์ฐพ๊ธฐ๋Š” ์‰ฝ์ง€๋งŒ, ์ž์‹๋“ค์„ ์ฐพ์œผ๋ ค๋ฉด ์ฟผ๋ฆฌ๊ฐ€ ํ•„์š”ํ•ด.
ํŠธ๋ฆฌ๋ฅผ ์œ„์—์„œ ์•„๋ž˜๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค๋ฉด ๋‹ค๋ฅธ ํŒจํ„ด์„ ๊ณ ๋ คํ•ด๋ด.

2๏ธโƒฃ Child Reference (์ž์‹ ์ฐธ์กฐ)

๋ถ€๋ชจ๊ฐ€ ์ž์‹๋“ค์˜ ID ๋ฐฐ์—ด์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹.
{
  "_id": "Programming",
  "children": ["Databases", "Web", "Mobile"]
}
{
  "_id": "Databases",
  "children": ["MongoDB", "PostgreSQL", "MySQL"]
}

์ž์‹์„ ์ฐพ๊ธฐ๋Š” ์‰ฝ์ง€๋งŒ, ์ž์‹์ด ๋„ˆ๋ฌด ๋งŽ์œผ๋ฉด ๋ฐฐ์—ด์ด ์ปค์ ธ์„œ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์–ด.

3๏ธโƒฃ Array of Ancestors (์กฐ์ƒ ๋ฐฐ์—ด)

๋ฃจํŠธ๋ถ€ํ„ฐ ํ˜„์žฌ ๋…ธ๋“œ๊นŒ์ง€์˜ ์ „์ฒด ๊ฒฝ๋กœ๋ฅผ ๋ฐฐ์—ด๋กœ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹.
ํŠน์ • ๋…ธ๋“œ์˜ ๋ชจ๋“  ํ•˜์œ„ ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๋•Œ ์œ ์šฉํ•ด!
{
  "_id": "MongoDB",
  "ancestors": ["Programming", "Databases"],
  "parent": "Databases"
}

// ํŠน์ • ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋ชจ๋“  ํ•˜์œ„ ํ•ญ๋ชฉ ์ฐพ๊ธฐ
db.categories.find({ ancestors: "Programming" })
๐Ÿ’ก ์žฌ๋Šฅ๋„ท ์ ์šฉ ์˜ˆ์‹œ

์žฌ๋Šฅ๋„ท์˜ ์นดํ…Œ๊ณ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž.
"IT/ํ”„๋กœ๊ทธ๋ž˜๋ฐ > ์›น๊ฐœ๋ฐœ > ํ”„๋ก ํŠธ์—”๋“œ > React"

Array of Ancestors ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด,
"IT/ํ”„๋กœ๊ทธ๋ž˜๋ฐ" ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋ชจ๋“  ํ•˜์œ„ ์žฌ๋Šฅ์„ ํ•œ ๋ฒˆ์— ์กฐํšŒํ•  ์ˆ˜ ์žˆ์–ด!
์‚ฌ์šฉ์ž๊ฐ€ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ์„ฑ๋Šฅ์ด ํ›จ์”ฌ ์ข‹์•„์ง€๊ฒ ์ง€? ๐Ÿ˜Š

๐Ÿ“Š ๋ฒ„ํ‚ท ํŒจํ„ด (Bucket Pattern)

์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ๋‚˜ ๋กœ๊ทธ์ฒ˜๋Ÿผ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ €์žฅํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด์ด์•ผ.
๋ฐ์ดํ„ฐ๋ฅผ ์ผ์ • ๋‹จ์œ„๋กœ ๋ฌถ์–ด์„œ(๋ฒ„ํ‚ท) ์ €์žฅํ•˜๋Š” ๊ฑฐ์ง€.

// ๋น„ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•: ๊ฐ ์ธก์ •๊ฐ’๋งˆ๋‹ค ๋ฌธ์„œ ์ƒ์„ฑ
{
  "sensor_id": "sensor1",
  "timestamp": ISODate("2024-01-15T10:00:00Z"),
  "temperature": 22.5
}
{
  "sensor_id": "sensor1",
  "timestamp": ISODate("2024-01-15T10:01:00Z"),
  "temperature": 22.7
}
// ... ์ˆ˜๋ฐฑ๋งŒ ๊ฐœ์˜ ๋ฌธ์„œ

// ๋ฒ„ํ‚ท ํŒจํ„ด: 1์‹œ๊ฐ„ ๋‹จ์œ„๋กœ ๋ฌถ๊ธฐ
{
  "sensor_id": "sensor1",
  "start_time": ISODate("2024-01-15T10:00:00Z"),
  "end_time": ISODate("2024-01-15T11:00:00Z"),
  "measurements": [
    { "timestamp": ISODate("2024-01-15T10:00:00Z"), "temp": 22.5 },
    { "timestamp": ISODate("2024-01-15T10:01:00Z"), "temp": 22.7 },
    { "timestamp": ISODate("2024-01-15T10:02:00Z"), "temp": 22.6 },
    // ... 60๊ฐœ์˜ ์ธก์ •๊ฐ’
  ],
  "count": 60,
  "avg_temp": 22.8
}
โœ… ๋ฒ„ํ‚ท ํŒจํ„ด์˜ ์žฅ์ 

๋ฌธ์„œ ์ˆ˜ ๊ฐ์†Œ: ์ˆ˜๋ฐฑ๋งŒ ๊ฐœ โ†’ ์ˆ˜๋งŒ ๊ฐœ๋กœ ์ค„์–ด๋“ค์–ด
์ธ๋ฑ์Šค ํฌ๊ธฐ๊ฐ€ ์ž‘์•„์ง€๊ณ  ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋ผ.

์ง‘๊ณ„ ๋ฐ์ดํ„ฐ ์‚ฌ์ „ ๊ณ„์‚ฐ: ํ‰๊ท , ํ•ฉ๊ณ„ ๋“ฑ์„ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•ด๋‘๋ฉด
๋ถ„์„ ์ฟผ๋ฆฌ๊ฐ€ ํ›จ์”ฌ ๋นจ๋ผ์ ธ.

๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ: ๊ด€๋ จ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ๋ฌธ์„œ์— ์žˆ์–ด์„œ
๋””์Šคํฌ I/O๊ฐ€ ์ค„์–ด๋“ค์–ด.

์žฌ๋Šฅ๋„ท์—์„œ ์‚ฌ์šฉ์ž ํ™œ๋™ ๋กœ๊ทธ๋‚˜ ๊ฑฐ๋ž˜ ํ†ต๊ณ„๋ฅผ ์ €์žฅํ•  ๋•Œ ๋ฒ„ํ‚ท ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด,
๋Œ€์‹œ๋ณด๋“œ ์„ฑ๋Šฅ์ด ์—„์ฒญ๋‚˜๊ฒŒ ๊ฐœ์„ ๋  ๊ฑฐ์•ผ! ๐Ÿ“ˆ

๐Ÿ”„ ํ™•์žฅ ํŒจํ„ด (Extended Reference Pattern)

๋ ˆํผ๋Ÿฐ์Šค ํŒจํ„ด์˜ ๋‹จ์ (์กฐํšŒ ์‹œ ์กฐ์ธ ํ•„์š”)์„ ๋ณด์™„ํ•˜๋Š” ํŒจํ„ด์ด์•ผ.
์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํ•„๋“œ๋งŒ ๋ณต์‚ฌํ•ด์„œ ์ €์žฅํ•˜๋Š” ๊ฑฐ์ง€.

// orders ์ปฌ๋ ‰์…˜
{
  "_id": ObjectId("..."),
  "user": {
    "id": ObjectId("507f1f77bcf86cd799439011"),
    "name": "๊น€๊ฐœ๋ฐœ",  // ์ž์ฃผ ํ‘œ์‹œ๋˜๋Š” ์ •๋ณด๋งŒ ๋ณต์‚ฌ
    "email": "dev@example.com"
    // ์ „ํ™”๋ฒˆํ˜ธ, ์ฃผ์†Œ ๋“ฑ ์ƒ์„ธ ์ •๋ณด๋Š” ์ œ์™ธ
  },
  "product": {
    "id": ObjectId("..."),
    "name": "MongoDB ์™„๋ฒฝ๊ฐ€์ด๋“œ",
    "price": 35000,
    "thumbnail": "https://..."
    // ์ƒ์„ธ ์„ค๋ช…, ์žฌ๊ณ  ๋“ฑ์€ ์ œ์™ธ
  },
  "order_date": ISODate("2024-01-15"),
  "status": "delivered"
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฃผ๋ฌธ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค„ ๋•Œ ์ถ”๊ฐ€ ์กฐํšŒ ์—†์ด ๋ฐ”๋กœ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์–ด.
์‚ฌ์šฉ์ž ์ด๋ฆ„์ด๋‚˜ ์ƒํ’ˆ๋ช…์ด ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ฌผ๊ณ , ๋ฐ”๋€Œ๋”๋ผ๋„ ์ฃผ๋ฌธ ๋‚ด์—ญ์€ ๋‹น์‹œ์˜ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒŒ ๋งž์œผ๋‹ˆ๊นŒ ๋ฌธ์ œ์—†์ง€! ๐Ÿ‘

๐ŸŽฏ ํŒจํ„ด ์„ ํƒ ๊ฐ€์ด๋“œ

๊ณ„์ธต ๊ตฌ์กฐ: ์นดํ…Œ๊ณ ๋ฆฌ, ์กฐ์ง๋„, ๋Œ“๊ธ€ โ†’ Tree Pattern
์‹œ๊ณ„์—ด ๋ฐ์ดํ„ฐ: ๋กœ๊ทธ, ์„ผ์„œ ๋ฐ์ดํ„ฐ, ํ†ต๊ณ„ โ†’ Bucket Pattern
์ž์ฃผ ์กฐํšŒ๋˜๋Š” ๊ด€๊ณ„: ์ฃผ๋ฌธ-์‚ฌ์šฉ์ž, ๊ฒŒ์‹œ๊ธ€-์ž‘์„ฑ์ž โ†’ Extended Reference
๋‹คํ˜•์„ฑ ๋ฐ์ดํ„ฐ: ์—ฌ๋Ÿฌ ํƒ€์ž…์˜ ์ œํ’ˆ โ†’ Polymorphic Pattern
๋ฒ„์ „ ๊ด€๋ฆฌ: ๋ฌธ์„œ ์ด๋ ฅ ์ถ”์  โ†’ Document Versioning Pattern

โš ๏ธ ํ”ผํ•ด์•ผ ํ•  ์•ˆํ‹ฐํŒจํ„ด

์ข‹์€ ํŒจํ„ด๋งŒํผ ์ค‘์š”ํ•œ ๊ฒŒ ๋‚˜์œ ํŒจํ„ด์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด์•ผ.
์‹ค๋ฌด์—์„œ ์ž์ฃผ ๋ณด๋Š” ์•ˆํ‹ฐํŒจํ„ด๋“ค์„ ์•Œ์•„๋ณด์ž. ๐Ÿšซ

โŒ ์•ˆํ‹ฐํŒจํ„ด 1: ๋ฌดํ•œ์ • ์ปค์ง€๋Š” ๋ฐฐ์—ด

{ "user_id": 1, "activities": [ ... ์ˆ˜์ฒœ ๊ฐœ ... ] }

๋ฌธ์„œ ํฌ๊ธฐ 16MB ์ œํ•œ์— ๊ฑธ๋ฆฌ๊ณ , ๋ฐฐ์—ด ๋์— ์ถ”๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ์ „์ฒด ๋ฌธ์„œ๋ฅผ ๋‹ค์‹œ ์จ์•ผ ํ•ด.
ํ•ด๊ฒฐ: ๋ฒ„ํ‚ท ํŒจํ„ด์ด๋‚˜ ๋ณ„๋„ ์ปฌ๋ ‰์…˜์œผ๋กœ ๋ถ„๋ฆฌ!
โŒ ์•ˆํ‹ฐํŒจํ„ด 2: ๋Œ€๋Ÿ‰์˜ ์ปฌ๋ ‰์…˜ ์ƒ์„ฑ

์‚ฌ์šฉ์ž๋งˆ๋‹ค ๋ณ„๋„ ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ (user_1_orders, user_2_orders...)

๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ œํ•œ์— ๊ฑธ๋ฆฌ๊ณ , ๊ด€๋ฆฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ด์ ธ.
ํ•ด๊ฒฐ: ํ•˜๋‚˜์˜ ์ปฌ๋ ‰์…˜์— user_id ํ•„๋“œ๋กœ ๊ตฌ๋ถ„!
โŒ ์•ˆํ‹ฐํŒจํ„ด 3: ๋ถˆํ•„์š”ํ•œ ์ธ๋ฑ์Šค ๋‚จ๋ฐœ

"ํ˜น์‹œ ๋ชฐ๋ผ์„œ" ๋ชจ๋“  ํ•„๋“œ์— ์ธ๋ฑ์Šค๋ฅผ ๊ฑฐ๋Š” ๊ฒฝ์šฐ.

์“ฐ๊ธฐ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ๋–จ์–ด์ง€๊ณ , ๋””์Šคํฌ ๊ณต๊ฐ„๋„ ๋‚ญ๋น„๋ผ.
ํ•ด๊ฒฐ: ์‹ค์ œ ์ฟผ๋ฆฌ ํŒจํ„ด์„ ๋ถ„์„ํ•ด์„œ ํ•„์š”ํ•œ ์ธ๋ฑ์Šค๋งŒ ์ƒ์„ฑ!
โŒ ์•ˆํ‹ฐํŒจํ„ด 4: ๊ด€๊ณ„ํ˜• DB ์‚ฌ๊ณ ๋ฐฉ์‹ ๊ทธ๋Œ€๋กœ ์ ์šฉ

๋ชจ๋“  ๊ฒƒ์„ ์ •๊ทœํ™”ํ•˜๊ณ  JOIN์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋ ค๋Š” ์‹œ๋„.

MongoDB์˜ ๊ฐ•์ ์„ ์ „ํ˜€ ์‚ด๋ฆฌ์ง€ ๋ชปํ•ด.
ํ•ด๊ฒฐ: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฝ๊ธฐ ํŒจํ„ด์„ ์ค‘์‹ฌ์œผ๋กœ ์žฌ์„ค๊ณ„!
โŒ ์•ˆํ‹ฐํŒจํ„ด 5: ObjectId๋ฅผ ๋ฌธ์ž์—ด๋กœ ์ €์žฅ

{ "user_id": "507f1f77bcf86cd799439011" } (๋ฌธ์ž์—ด)

์ธ๋ฑ์Šค ํšจ์œจ์ด ๋–จ์–ด์ง€๊ณ , ์ €์žฅ ๊ณต๊ฐ„๋„ ๋” ์ฐจ์ง€ํ•ด.
ํ•ด๊ฒฐ: ObjectId ํƒ€์ž… ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ!

๐Ÿš€ ์ธ๋ฑ์Šค ์ „๋žต๊ณผ ์ฟผ๋ฆฌ ์ตœ์ ํ™”

์Šคํ‚ค๋งˆ ์„ค๊ณ„๊ฐ€ ๋๋‚ฌ๋‹ค๋ฉด, ์ด์ œ ์ธ๋ฑ์Šค ์ „๋žต์„ ์„ธ์šธ ์ฐจ๋ก€์•ผ.
์•„๋ฌด๋ฆฌ ์ž˜ ์„ค๊ณ„๋œ ์Šคํ‚ค๋งˆ๋ผ๋„ ์ธ๋ฑ์Šค๊ฐ€ ์—†์œผ๋ฉด ์„ฑ๋Šฅ์ด ํ˜•ํŽธ์—†๊ฑฐ๋“ ! ๐Ÿ˜…

๐Ÿ“‘ ์ธ๋ฑ์Šค ๊ธฐ๋ณธ ์›์น™

MongoDB์˜ ์ธ๋ฑ์Šค๋Š” B-Tree ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด.
๊ด€๊ณ„ํ˜• DB์™€ ๋น„์Šทํ•˜์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ MongoDB๋งŒ์˜ ํŠน์ง•์ด ์žˆ์–ด.

๐ŸŽฏ ์ธ๋ฑ์Šค ์ƒ์„ฑ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•
// ๋‹จ์ผ ํ•„๋“œ ์ธ๋ฑ์Šค
db.users.createIndex({ email: 1 })  // ์˜ค๋ฆ„์ฐจ์ˆœ
db.users.createIndex({ created_at: -1 })  // ๋‚ด๋ฆผ์ฐจ์ˆœ

// ๋ณตํ•ฉ ์ธ๋ฑ์Šค (Compound Index)
db.orders.createIndex({ user_id: 1, order_date: -1 })

// ๊ณ ์œ  ์ธ๋ฑ์Šค (Unique Index)
db.users.createIndex({ email: 1 }, { unique: true })

// ๋ถ€๋ถ„ ์ธ๋ฑ์Šค (Partial Index) - ์กฐ๊ฑด์— ๋งž๋Š” ๋ฌธ์„œ๋งŒ ์ธ๋ฑ์‹ฑ
db.orders.createIndex(
  { status: 1 },
  { partialFilterExpression: { amount: { $gt: 10000 } } }
)

// TTL ์ธ๋ฑ์Šค - ์ผ์ • ์‹œ๊ฐ„ ํ›„ ์ž๋™ ์‚ญ์ œ
db.sessions.createIndex(
  { created_at: 1 },
  { expireAfterSeconds: 3600 }  // 1์‹œ๊ฐ„ ํ›„ ์‚ญ์ œ
)
โœ… ์ธ๋ฑ์Šค ์ƒ์„ฑ ์šฐ์„ ์ˆœ์œ„

1์ˆœ์œ„: ๊ณ ์œ ์„ฑ ์ œ์•ฝ์ด ํ•„์š”ํ•œ ํ•„๋“œ
์ด๋ฉ”์ผ, ์‚ฌ์šฉ์ž๋ช… ๋“ฑ โ†’ Unique Index

2์ˆœ์œ„: WHERE ์ ˆ์— ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํ•„๋“œ
user_id, status, category ๋“ฑ

3์ˆœ์œ„: ์ •๋ ฌ(ORDER BY)์— ์‚ฌ์šฉ๋˜๋Š” ํ•„๋“œ
created_at, updated_at ๋“ฑ

4์ˆœ์œ„: ๋ฒ”์œ„ ์ฟผ๋ฆฌ์— ์‚ฌ์šฉ๋˜๋Š” ํ•„๋“œ
price, date ๋“ฑ

๐ŸŽจ ๋ณตํ•ฉ ์ธ๋ฑ์Šค ์„ค๊ณ„์˜ ์˜ˆ์ˆ 

๋ณตํ•ฉ ์ธ๋ฑ์Šค๋Š” ํ•„๋“œ ์ˆœ์„œ๊ฐ€ ์ •๋ง ์ค‘์š”ํ•ด!
ESR ๊ทœ์น™์„ ๊ธฐ์–ตํ•˜๋ฉด ์‰ฌ์›Œ. ๐Ÿ“

๐Ÿ’ก ESR ๊ทœ์น™ (Equality, Sort, Range)

E (Equality): ๋™๋“ฑ ๋น„๊ต ํ•„๋“œ๋ฅผ ๋จผ์ €
{ status: "active" }

S (Sort): ์ •๋ ฌ ํ•„๋“œ๋ฅผ ๋‘ ๋ฒˆ์งธ
sort({ created_at: -1 })

R (Range): ๋ฒ”์œ„ ์กฐ๊ฑด ํ•„๋“œ๋ฅผ ๋งˆ์ง€๋ง‰
{ price: { $gte: 10000, $lte: 50000 } }

์ตœ์  ์ธ๋ฑ์Šค:
db.products.createIndex({ status: 1, created_at: -1, price: 1 })
// ์ฟผ๋ฆฌ ์˜ˆ์‹œ
db.products.find({
  status: "active",
  price: { $gte: 10000, $lte: 50000 }
}).sort({ created_at: -1 })

// ์ž˜๋ชป๋œ ์ธ๋ฑ์Šค (๋น„ํšจ์œจ์ )
db.products.createIndex({ price: 1, status: 1, created_at: -1 })
// Range ํ•„๋“œ๊ฐ€ ์•ž์— ์˜ค๋ฉด ๋’ค์˜ ํ•„๋“œ๋“ค์„ ์ œ๋Œ€๋กœ ํ™œ์šฉ ๋ชปํ•จ!

// ์˜ฌ๋ฐ”๋ฅธ ์ธ๋ฑ์Šค
db.products.createIndex({ status: 1, created_at: -1, price: 1 })

๐Ÿ” ์ฟผ๋ฆฌ ์„ฑ๋Šฅ ๋ถ„์„

์ธ๋ฑ์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด, ์‹ค์ œ๋กœ ์ž˜ ์‚ฌ์šฉ๋˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ด.
explain() ๋ฉ”์„œ๋“œ๊ฐ€ ์ตœ๊ณ ์˜ ์นœ๊ตฌ์•ผ! ๐Ÿ”Ž

// ์‹คํ–‰ ๊ณ„ํš ํ™•์ธ
db.orders.find({ user_id: ObjectId("...") })
  .sort({ order_date: -1 })
  .explain("executionStats")

// ์ฃผ์š” ํ™•์ธ ์‚ฌํ•ญ
{
  "executionStats": {
    "executionTimeMillis": 5,  // ์‹คํ–‰ ์‹œ๊ฐ„ (๋‚ฎ์„์ˆ˜๋ก ์ข‹์Œ)
    "totalDocsExamined": 10,   // ๊ฒ€์‚ฌํ•œ ๋ฌธ์„œ ์ˆ˜
    "totalKeysExamined": 10,   // ๊ฒ€์‚ฌํ•œ ์ธ๋ฑ์Šค ํ‚ค ์ˆ˜
    "nReturned": 10,           // ๋ฐ˜ํ™˜๋œ ๋ฌธ์„œ ์ˆ˜
    "executionStages": {
      "stage": "FETCH",
      "inputStage": {
        "stage": "IXSCAN",     // ์ธ๋ฑ์Šค ์Šค์บ” (์ข‹์Œ!)
        "indexName": "user_id_1_order_date_-1"
      }
    }
  }
}
๐ŸŽฏ ์„ฑ๋Šฅ ์ง€ํ‘œ ํ•ด์„

COLLSCAN: ์ปฌ๋ ‰์…˜ ์ „์ฒด ์Šค์บ” โ†’ ๋‚˜์จ! ์ธ๋ฑ์Šค ํ•„์š”
IXSCAN: ์ธ๋ฑ์Šค ์Šค์บ” โ†’ ์ข‹์Œ!
FETCH: ์ธ๋ฑ์Šค๋กœ ์ฐพ์€ ํ›„ ๋ฌธ์„œ ๊ฐ€์ ธ์˜ค๊ธฐ โ†’ ์ •์ƒ

์ด์ƒ์ ์ธ ๋น„์œจ:
totalKeysExamined โ‰ˆ nReturned (์ธ๋ฑ์Šค ํšจ์œจ 100%)
totalDocsExamined โ‰ˆ nReturned (๋ถˆํ•„์š”ํ•œ ๋ฌธ์„œ ๊ฒ€์‚ฌ ์—†์Œ)

๐ŸŽช ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค (Covered Query)

์ธ๋ฑ์Šค๋งŒ์œผ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์™„์ „ํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๋ฌธ์„œ๋ฅผ ์ฝ์„ ํ•„์š”๊ฐ€ ์—†์–ด์ ธ์„œ ์—„์ฒญ ๋นจ๋ผ! โšก
์ด๊ฑธ ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค๋ผ๊ณ  ํ•ด.

// ์ธ๋ฑ์Šค ์ƒ์„ฑ
db.users.createIndex({ email: 1, name: 1, status: 1 })

// ์ปค๋ฒ„๋ง ์ฟผ๋ฆฌ (์ธ๋ฑ์Šค๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ)
db.users.find(
  { status: "active" },
  { email: 1, name: 1, status: 1, _id: 0 }  // _id: 0 ์ค‘์š”!
)

// explain ๊ฒฐ๊ณผ์—์„œ ํ™•์ธ
{
  "executionStats": {
    "totalDocsExamined": 0,  // ๋ฌธ์„œ๋ฅผ ํ•˜๋‚˜๋„ ์•ˆ ์ฝ์Œ!
    "executionStages": {
      "stage": "PROJECTION_COVERED",  // ์ปค๋ฒ„๋ง!
      "inputStage": {
        "stage": "IXSCAN"
      }
    }
  }
}

์ฃผ์˜ํ•  ์ ์€ _id ํ•„๋“œ๋ฅผ ์ œ์™ธํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฑฐ์•ผ.
_id๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จ๋˜๋Š”๋ฐ, ์ธ๋ฑ์Šค์— ์—†์œผ๋ฉด ๋ฌธ์„œ๋ฅผ ์ฝ์–ด์•ผ ํ•˜๊ฑฐ๋“ !

โš™๏ธ ์ปฌ๋ ‰์…˜ ์ƒค๋”ฉ๊ณผ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

๋ฐ์ดํ„ฐ๊ฐ€ ์ •๋ง ๋งŽ์•„์ง€๋ฉด (์ˆ˜์–ต ๊ฑด ์ด์ƒ), ๋‹จ์ผ ์„œ๋ฒ„๋กœ๋Š” ํ•œ๊ณ„๊ฐ€ ์™€.
์ด๋•Œ ํ•„์š”ํ•œ ๊ฒŒ ์ƒค๋”ฉ(Sharding)์ด์•ผ! ๐ŸŒ

๐Ÿ—‚๏ธ ์ƒค๋”ฉ์ด๋ž€?

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

MongoDB ์ƒค๋”ฉ ์•„ํ‚คํ…์ฒ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ Mongos (์ฟผ๋ฆฌ ๋ผ์šฐํ„ฐ) Shard 1 user_id: 0 ~ 333 ๋ฐ์ดํ„ฐ 1/3 Primary Secondary 1 Secondary 2 Shard 2 user_id: 334 ~ 666 ๋ฐ์ดํ„ฐ 1/3 Primary Secondary 1 Secondary 2 Shard 3 user_id: 667 ~ 999 ๋ฐ์ดํ„ฐ 1/3 Primary Secondary 1 Secondary 2

๐Ÿ”‘ ์ƒค๋“œ ํ‚ค ์„ ํƒ

์ƒค๋”ฉ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒฐ์ •์ด ์ƒค๋“œ ํ‚ค(Shard Key) ์„ ํƒ์ด์•ผ.
์ƒค๋“œ ํ‚ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถ„์‚ฐ์‹œํ‚ฌ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ธฐ์ค€์ด๊ฑฐ๋“ .

์ข‹์€ ์ƒค๋“œ ํ‚ค์˜ ์กฐ๊ฑด

1. ๋†’์€ ์นด๋””๋„๋ฆฌํ‹ฐ (Cardinality): ๊ณ ์œ ํ•œ ๊ฐ’์ด ๋งŽ์•„์•ผ ํ•ด
โŒ ๋‚˜์จ: status (active/inactive ๋‘ ๊ฐ€์ง€๋ฟ)
โœ… ์ข‹์Œ: user_id (์ˆ˜๋ฐฑ๋งŒ ๊ฐœ์˜ ๊ณ ์œ ๊ฐ’)

2. ๊ท ๋“ฑํ•œ ๋ถ„์‚ฐ: ๋ฐ์ดํ„ฐ๊ฐ€ ํŠน์ • ์ƒค๋“œ์— ๋ชฐ๋ฆฌ์ง€ ์•Š์•„์•ผ ํ•ด
โŒ ๋‚˜์จ: created_at (์ตœ๊ทผ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ์ƒค๋“œ์— ์ง‘์ค‘)
โœ… ์ข‹์Œ: hashed(user_id) (ํ•ด์‹œ๋กœ ๊ท ๋“ฑ ๋ถ„์‚ฐ)

3. ์ฟผ๋ฆฌ ํŒจํ„ด๊ณผ ์ผ์น˜: ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ํ•„ํ„ฐ ์กฐ๊ฑด์ด์–ด์•ผ ํ•ด
โœ… ์ข‹์Œ: ๋Œ€๋ถ€๋ถ„์˜ ์ฟผ๋ฆฌ๊ฐ€ user_id๋กœ ํ•„ํ„ฐ๋งํ•œ๋‹ค๋ฉด user_id๋ฅผ ์ƒค๋“œ ํ‚ค๋กœ
// ์ƒค๋”ฉ ํ™œ์„ฑํ™”
sh.enableSharding("mydb")

// ํ•ด์‹œ ์ƒค๋“œ ํ‚ค (๊ท ๋“ฑ ๋ถ„์‚ฐ์— ์œ ๋ฆฌ)
sh.shardCollection("mydb.users", { user_id: "hashed" })

// ๋ฒ”์œ„ ์ƒค๋“œ ํ‚ค (๋ฒ”์œ„ ์ฟผ๋ฆฌ์— ์œ ๋ฆฌ)
sh.shardCollection("mydb.orders", { user_id: 1, order_date: 1 })

// ๋ณตํ•ฉ ์ƒค๋“œ ํ‚ค
sh.shardCollection("mydb.logs", { 
  app_id: 1, 
  timestamp: 1 
})
โš ๏ธ ์ƒค๋“œ ํ‚ค ์„ ํƒ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

ํ•œ ๋ฒˆ ์ •ํ•˜๋ฉด ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€! (MongoDB 5.0 ์ด์ „)
MongoDB 5.0๋ถ€ํ„ฐ๋Š” resharding์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์—„์ฒญ๋‚œ ๋น„์šฉ์ด ๋“ค์–ด.

๋‹จ์กฐ ์ฆ๊ฐ€ํ•˜๋Š” ํ‚ค๋Š” ํ”ผํ•ด:
ObjectId, ํƒ€์ž„์Šคํƒฌํ”„ ๊ฐ™์€ ๊ฐ’์€ ์ตœ์‹  ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ ์ƒค๋“œ์— ๋ชฐ๋ ค.
ํ•ด์‹œ ์ƒค๋“œ ํ‚ค๋ฅผ ๊ณ ๋ คํ•ด๋ด!

์ฟผ๋ฆฌ์— ์ƒค๋“œ ํ‚ค ํฌํ•จ:
์ƒค๋“œ ํ‚ค๊ฐ€ ์—†๋Š” ์ฟผ๋ฆฌ๋Š” ๋ชจ๋“  ์ƒค๋“œ๋ฅผ ๋’ค์ ธ์•ผ ํ•ด์„œ ๋А๋ ค.

๐Ÿ“Š ์ฒญํฌ์™€ ๋ฐธ๋Ÿฐ์‹ฑ

MongoDB๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฒญํฌ(Chunk)๋ผ๋Š” ๋‹จ์œ„๋กœ ๋‚˜๋ˆ ์„œ ๊ด€๋ฆฌํ•ด.
๊ธฐ๋ณธ์ ์œผ๋กœ ์ฒญํฌ ํฌ๊ธฐ๋Š” 64MB์ด๊ณ , ์ฒญํฌ๊ฐ€ ๋„ˆ๋ฌด ์ปค์ง€๋ฉด ์ž๋™์œผ๋กœ ๋ถ„ํ• ๋ผ.

๊ทธ๋ฆฌ๊ณ  ๋ฐธ๋Ÿฐ์„œ(Balancer)๊ฐ€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ฒญํฌ๋ฅผ ์ƒค๋“œ ๊ฐ„์— ์ด๋™์‹œ์ผœ์„œ
๋ฐ์ดํ„ฐ๊ฐ€ ๊ท ๋“ฑํ•˜๊ฒŒ ๋ถ„์‚ฐ๋˜๋„๋ก ๊ด€๋ฆฌํ•ด์ค˜. ์™„์ „ ์ž๋™์ด์•ผ! ๐Ÿค–

๐Ÿ’ก ์‹ค์ „ ํŒ: ๋ฐธ๋Ÿฐ์‹ฑ ์œˆ๋„์šฐ ์„ค์ •

๋ฐธ๋Ÿฐ์‹ฑ์€ I/O๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•ด์„œ ์„œ๋น„์Šค์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์–ด.
ํŠธ๋ž˜ํ”ฝ์ด ์ ์€ ์‹œ๊ฐ„๋Œ€์—๋งŒ ๋ฐธ๋Ÿฐ์‹ฑํ•˜๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ฒŒ ์ข‹์•„!

sh.setBalancerState(true)
db.settings.update(
{ _id: "balancer" },
{ $set: { activeWindow: { start: "01:00", stop: "05:00" } } }

)

๐Ÿ“ˆ ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง๊ณผ ํŠœ๋‹

์Šคํ‚ค๋งˆ ์„ค๊ณ„์™€ ์ธ๋ฑ์Šค ์ตœ์ ํ™”๊ฐ€ ๋๋‚ฌ๋‹ค๋ฉด, ์ด์ œ ์ง€์†์ ์ธ ๋ชจ๋‹ˆํ„ฐ๋ง์ด ํ•„์š”ํ•ด.
์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ๋ฐ์ดํ„ฐ ํŒจํ„ด์ด ๋ฐ”๋€Œ๊ณ , ์ƒˆ๋กœ์šด ๋ณ‘๋ชฉ์ด ์ƒ๊ธฐ๊ฑฐ๋“ ! ๐Ÿ‘€

๐Ÿ” ์ฃผ์š” ๋ชจ๋‹ˆํ„ฐ๋ง ์ง€ํ‘œ

1๏ธโƒฃ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ

db.currentOp() - ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์ฟผ๋ฆฌ ํ™•์ธ
db.system.profile.find() - ๋А๋ฆฐ ์ฟผ๋ฆฌ ๋กœ๊ทธ ๋ถ„์„

๋А๋ฆฐ ์ฟผ๋ฆฌ(100ms ์ด์ƒ)๋ฅผ ์ฐพ์•„์„œ ์ธ๋ฑ์Šค ์ถ”๊ฐ€๋‚˜ ์ฟผ๋ฆฌ ๊ฐœ์„ ์„ ํ•ด์•ผ ํ•ด.
// ํ”„๋กœํŒŒ์ผ๋ง ํ™œ์„ฑํ™” (๋ ˆ๋ฒจ 1: 100ms ์ด์ƒ ์ฟผ๋ฆฌ๋งŒ ๊ธฐ๋ก)
db.setProfilingLevel(1, { slowms: 100 })

// ๋А๋ฆฐ ์ฟผ๋ฆฌ ํ™•์ธ
db.system.profile.find({
  millis: { $gt: 100 }
}).sort({ ts: -1 }).limit(10).pretty()

// ํŠน์ • ์ปฌ๋ ‰์…˜์˜ ๋А๋ฆฐ ์ฟผ๋ฆฌ
db.system.profile.find({
  ns: "mydb.users",
  millis: { $gt: 100 }
})
2๏ธโƒฃ ์ธ๋ฑ์Šค ์‚ฌ์šฉ๋ฅ 

๋งŒ๋“ค์–ด๋‘” ์ธ๋ฑ์Šค๊ฐ€ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ด.
์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ธ๋ฑ์Šค๋Š” ์“ฐ๊ธฐ ์„ฑ๋Šฅ๋งŒ ๋–จ์–ด๋œจ๋ฆฌ๋‹ˆ๊นŒ ์‚ญ์ œํ•˜๋Š” ๊ฒŒ ์ข‹์•„!
// ์ธ๋ฑ์Šค ์‚ฌ์šฉ ํ†ต๊ณ„
db.users.aggregate([
  { $indexStats: {} }
])

// ๊ฒฐ๊ณผ ์˜ˆ์‹œ
{
  "name": "email_1",
  "key": { "email": 1 },
  "host": "server1:27017",
  "accesses": {
    "ops": 15234,      // ์‚ฌ์šฉ ํšŸ์ˆ˜
    "since": ISODate("2024-01-01T00:00:00Z")
  }
}

// ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ธ๋ฑ์Šค ์ฐพ๊ธฐ
db.users.aggregate([
  { $indexStats: {} },
  { $match: { "accesses.ops": 0 } }
])
3๏ธโƒฃ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰

MongoDB๋Š” ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์บ์‹ฑํ•ด.
Working Set(์ž์ฃผ ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ)์ด ๋ฉ”๋ชจ๋ฆฌ์— ๋“ค์–ด๊ฐ€์•ผ ์„ฑ๋Šฅ์ด ์ข‹์•„!
// ์„œ๋ฒ„ ์ƒํƒœ ํ™•์ธ
db.serverStatus()

// ์ฃผ์š” ๋ฉ”๋ชจ๋ฆฌ ์ง€ํ‘œ
{
  "mem": {
    "resident": 2048,    // ์‹ค์ œ ์‚ฌ์šฉ ์ค‘์ธ ๋ฉ”๋ชจ๋ฆฌ (MB)
    "virtual": 4096,     // ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ
    "mapped": 3072       // ๋งคํ•‘๋œ ๋ฉ”๋ชจ๋ฆฌ
  },
  "wiredTiger": {
    "cache": {
      "bytes currently in the cache": 1073741824,  // 1GB
      "maximum bytes configured": 2147483648,      // 2GB
      "pages evicted": 1234  // ์บ์‹œ์—์„œ ์ œ๊ฑฐ๋œ ํŽ˜์ด์ง€ (๋‚ฎ์„์ˆ˜๋ก ์ข‹์Œ)
    }
  }
}

pages evicted ๊ฐ’์ด ๊ณ„์† ์ฆ๊ฐ€ํ•œ๋‹ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค๋Š” ์‹ ํ˜ธ์•ผ.
์บ์‹œ ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜, ์„œ๋ฒ„๋ฅผ ์ฆ์„คํ•ด์•ผ ํ•ด! ๐Ÿ’ช

4๏ธโƒฃ ์—ฐ๊ฒฐ ์ˆ˜

๋™์‹œ ์—ฐ๊ฒฐ ์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์œผ๋ฉด ์„ฑ๋Šฅ์ด ๋–จ์–ด์ ธ.
์ปค๋„ฅ์…˜ ํ’€๋ง์„ ์ œ๋Œ€๋กœ ์„ค์ •ํ–ˆ๋Š”์ง€ ํ™•์ธํ•ด๋ด.
// ํ˜„์žฌ ์—ฐ๊ฒฐ ์ˆ˜ ํ™•์ธ
db.serverStatus().connections

{
  "current": 52,      // ํ˜„์žฌ ์—ฐ๊ฒฐ ์ˆ˜
  "available": 838808, // ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์—ฐ๊ฒฐ ์ˆ˜
  "totalCreated": 1234 // ์ƒ์„ฑ๋œ ์ด ์—ฐ๊ฒฐ ์ˆ˜
}

// ์—ฐ๊ฒฐ๋ณ„ ์ƒํƒœ ํ™•์ธ
db.currentOp(true)

๐Ÿ› ๏ธ ์‹ค์ „ ํŠœ๋‹ ํŒ

โœ… ์ฝ๊ธฐ ์„ฑ๋Šฅ ๊ฐœ์„ 

1. ์ ์ ˆํ•œ ์ธ๋ฑ์Šค ์ƒ์„ฑ
์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ฟผ๋ฆฌ ํŒจํ„ด์„ ๋ถ„์„ํ•ด์„œ ๋ณตํ•ฉ ์ธ๋ฑ์Šค ์ƒ์„ฑ

2. ์ปค๋ฒ„๋ง ์ธ๋ฑ์Šค ํ™œ์šฉ
ํ•„์š”ํ•œ ํ•„๋“œ๋งŒ projectionํ•˜๊ณ , _id ์ œ์™ธ

3. Read Preference ์„ค์ •
์ฝ๊ธฐ ์ „์šฉ ์ฟผ๋ฆฌ๋Š” Secondary์—์„œ ์ฝ๋„๋ก ์„ค์ •

4. ์ ์ ˆํ•œ ๋ฐฐ์น˜ ํฌ๊ธฐ
cursor.batchSize()๋กœ ํ•œ ๋ฒˆ์— ๊ฐ€์ ธ์˜ฌ ๋ฌธ์„œ ์ˆ˜ ์กฐ์ ˆ
โœ… ์“ฐ๊ธฐ ์„ฑ๋Šฅ ๊ฐœ์„ 

1. ๋ถˆํ•„์š”ํ•œ ์ธ๋ฑ์Šค ์ œ๊ฑฐ
์ธ๋ฑ์Šค๊ฐ€ ๋งŽ์„์ˆ˜๋ก ์“ฐ๊ธฐ๊ฐ€ ๋А๋ ค์ ธ

2. Write Concern ์กฐ์ •
์ค‘์š”ํ•˜์ง€ ์•Š์€ ๋กœ๊ทธ๋Š” w:0 ๋˜๋Š” w:1๋กœ ์„ค์ •

3. Bulk Write ์‚ฌ์šฉ
์—ฌ๋Ÿฌ ๋ฌธ์„œ๋ฅผ ํ•œ ๋ฒˆ์— ์“ฐ๋ฉด ํ›จ์”ฌ ๋นจ๋ผ

4. ๋ฌธ์„œ ํฌ๊ธฐ ์ตœ์†Œํ™”
๋ถˆํ•„์š”ํ•œ ํ•„๋“œ ์ œ๊ฑฐ, ์งง์€ ํ•„๋“œ๋ช… ์‚ฌ์šฉ
// Bulk Write ์˜ˆ์‹œ
const bulk = db.users.initializeUnorderedBulkOp();

for (let i = 0; i < 10000; i++) {
  bulk.insert({
    name: `User ${i}`,
    email: `user${i}@example.com`,
    created_at: new Date()
  });
}

bulk.execute();  // ํ•œ ๋ฒˆ์— ์‹คํ–‰!

// Write Concern ์„ค์ •
db.logs.insertOne(
  { message: "User logged in", timestamp: new Date() },
  { writeConcern: { w: 0 } }  // ํ™•์ธ ์•ˆ ๊ธฐ๋‹ค๋ฆผ (๋น ๋ฆ„!)
)

๐Ÿ“Š ๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ

MongoDB๋ฅผ ์ œ๋Œ€๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋ ค๋ฉด ์ข‹์€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•ด.
๋ฌด๋ฃŒ๋ถ€ํ„ฐ ์œ ๋ฃŒ๊นŒ์ง€ ๋‹ค์–‘ํ•œ ์˜ต์…˜์ด ์žˆ์–ด! ๐Ÿ› ๏ธ

๐Ÿ”ง ์ถ”์ฒœ ๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ

1. MongoDB Atlas (๊ณต์‹, ํด๋ผ์šฐ๋“œ)
MongoDB ๊ณต์‹ ํด๋ผ์šฐ๋“œ ์„œ๋น„์Šค. ๋ชจ๋‹ˆํ„ฐ๋ง, ๋ฐฑ์—…, ์•Œ๋ฆผ ๋ชจ๋‘ ํฌํ•จ!
๋ฌด๋ฃŒ ํ‹ฐ์–ด๋„ ์žˆ์–ด์„œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์ข‹์•„.

2. MongoDB Compass (๊ณต์‹, GUI)
์ฟผ๋ฆฌ ์„ฑ๋Šฅ ๋ถ„์„, ์ธ๋ฑ์Šค ๊ด€๋ฆฌ, ์Šคํ‚ค๋งˆ ์‹œ๊ฐํ™” ๋“ฑ
๊ฐœ๋ฐœํ•  ๋•Œ ์ •๋ง ์œ ์šฉํ•ด!

3. Percona Monitoring and Management (PMM)
์˜คํ”ˆ์†Œ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ. Grafana ๊ธฐ๋ฐ˜์œผ๋กœ ์˜ˆ์œ ๋Œ€์‹œ๋ณด๋“œ ์ œ๊ณต

4. mongostat / mongotop (CLI)
๊ฐ„๋‹จํ•œ ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง์— ์œ ์šฉ
mongostat --host localhost:27017
mongotop --host localhost:27017

๐ŸŽ“ ์‹ค์ „ ์‚ฌ๋ก€: ์žฌ๋Šฅ๋„ท ์Šคํ‚ค๋งˆ ์„ค๊ณ„

์ด๋ก ์€ ์ถฉ๋ถ„ํžˆ ๋ฐฐ์› ์œผ๋‹ˆ, ์ด์ œ ์‹ค์ œ ์‚ฌ๋ก€๋ฅผ ๋ณด์ž!
์žฌ๋Šฅ๋„ท ๊ฐ™์€ ์žฌ๋Šฅ ๊ณต์œ  ํ”Œ๋žซํผ์˜ ์Šคํ‚ค๋งˆ๋ฅผ ์–ด๋–ป๊ฒŒ ์„ค๊ณ„ํ• ์ง€ ์ƒ๊ฐํ•ด๋ณผ๊ฒŒ. ๐ŸŽจ

๐Ÿ“‹ ์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„

ํ•ต์‹ฌ ์—”ํ‹ฐํ‹ฐ

โ€ข ์‚ฌ์šฉ์ž (Users)
โ€ข ์žฌ๋Šฅ (Talents)
โ€ข ์นดํ…Œ๊ณ ๋ฆฌ (Categories)
โ€ข ์ฃผ๋ฌธ/๊ฑฐ๋ž˜ (Orders)
โ€ข ๋ฆฌ๋ทฐ (Reviews)
โ€ข ๋ฉ”์‹œ์ง€ (Messages)
์ฃผ์š” ์ฟผ๋ฆฌ ํŒจํ„ด

โ€ข ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์žฌ๋Šฅ ๋ชฉ๋ก ์กฐํšŒ (์ฝ๊ธฐ ๋งŽ์Œ)
โ€ข ์‚ฌ์šฉ์ž์˜ ์žฌ๋Šฅ ๋ชฉ๋ก ์กฐํšŒ
โ€ข ์ฃผ๋ฌธ ๋‚ด์—ญ ์กฐํšŒ (์‚ฌ์šฉ์ž๋ณ„, ํŒ๋งค์ž๋ณ„)
โ€ข ์žฌ๋Šฅ ์ƒ์„ธ + ๋ฆฌ๋ทฐ ์กฐํšŒ (ํ•จ๊ป˜ ์กฐํšŒ)
โ€ข ์‹ค์‹œ๊ฐ„ ๋ฉ”์‹œ์ง€ (์“ฐ๊ธฐ ๋งŽ์Œ)

๐Ÿ—๏ธ ์Šคํ‚ค๋งˆ ์„ค๊ณ„

// 1. Users ์ปฌ๋ ‰์…˜
{
  "_id": ObjectId("..."),
  "email": "dev@example.com",
  "name": "๊น€๊ฐœ๋ฐœ",
  "profile": {
    "bio": "ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค",
    "avatar": "https://...",
    "skills": ["JavaScript", "MongoDB", "React"]
  },
  "stats": {
    "total_sales": 1500000,
    "total_orders": 42,
    "rating": 4.8,
    "review_count": 38
  },
  "created_at": ISODate("2023-01-15"),
  "updated_at": ISODate("2024-01-20")
}

// ์ธ๋ฑ์Šค
db.users.createIndex({ email: 1 }, { unique: true })
db.users.createIndex({ "stats.rating": -1 })  // ์ธ๊ธฐ ํŒ๋งค์ž ์กฐํšŒ

์‚ฌ์šฉ์ž ํ†ต๊ณ„(stats)๋Š” ์ž„๋ฒ ๋””๋“œ๋กœ ์ €์žฅํ–ˆ์–ด.
ํ”„๋กœํ•„ ์กฐํšŒํ•  ๋•Œ ํ•ญ์ƒ ํ•จ๊ป˜ ๋ณด์—ฌ์ฃผ๋‹ˆ๊นŒ ํ•œ ๋ฒˆ์— ๊ฐ€์ ธ์˜ค๋Š” ๊ฒŒ ํšจ์œจ์ ์ด์ง€!

// 2. Talents ์ปฌ๋ ‰์…˜
{
  "_id": ObjectId("..."),
  "seller_id": ObjectId("..."),
  "seller_name": "๊น€๊ฐœ๋ฐœ",  // ์Šค๋ƒ…์ƒท (Extended Reference)
  "seller_avatar": "https://...",
  "title": "MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ์ปจ์„คํŒ…",
  "description": "...",
  "category": {
    "id": ObjectId("..."),
    "name": "IT/ํ”„๋กœ๊ทธ๋ž˜๋ฐ",
    "path": ["IT/ํ”„๋กœ๊ทธ๋ž˜๋ฐ", "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค", "MongoDB"]  // ๊ณ„์ธต ๊ตฌ์กฐ
  },
  "price": 50000,
  "delivery_days": 7,
  "tags": ["MongoDB", "์Šคํ‚ค๋งˆ์„ค๊ณ„", "DB์ตœ์ ํ™”"],
  "stats": {
    "views": 1234,
    "orders": 42,
    "rating": 4.8,
    "review_count": 38
  },
  "status": "active",  // active, paused, deleted
  "created_at": ISODate("2023-06-01"),
  "updated_at": ISODate("2024-01-15")
}

// ์ธ๋ฑ์Šค
db.talents.createIndex({ seller_id: 1, status: 1 })
db.talents.createIndex({ "category.id": 1, status: 1, "stats.rating": -1 })
db.talents.createIndex({ status: 1, created_at: -1 })  // ์ตœ์‹ ์ˆœ
db.talents.createIndex({ tags: 1 })  // ํƒœ๊ทธ ๊ฒ€์ƒ‰
db.talents.createIndex({ 
  title: "text", 
  description: "text", 
  tags: "text" 
})  // ์ „๋ฌธ ๊ฒ€์ƒ‰

์žฌ๋Šฅ ๋ฌธ์„œ์— ํŒ๋งค์ž ์ด๋ฆ„๊ณผ ์•„๋ฐ”ํƒ€๋ฅผ ์Šค๋ƒ…์ƒท์œผ๋กœ ์ €์žฅํ–ˆ์–ด.
๋ชฉ๋ก ์กฐํšŒํ•  ๋•Œ ํŒ๋งค์ž ์ •๋ณด๋ฅผ ๋ณ„๋„๋กœ ์กฐํšŒํ•˜์ง€ ์•Š์•„๋„ ๋˜๋‹ˆ๊นŒ ๋น ๋ฅด์ง€!
์นดํ…Œ๊ณ ๋ฆฌ๋„ ๊ฒฝ๋กœ๋ฅผ ์ €์žฅํ•ด์„œ "IT/ํ”„๋กœ๊ทธ๋ž˜๋ฐ" ํ•˜์œ„ ๋ชจ๋“  ์žฌ๋Šฅ์„ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์–ด.

// 3. Orders ์ปฌ๋ ‰์…˜
{
  "_id": ObjectId("..."),
  "order_number": "ORD-2024-001234",
  "buyer": {
    "id": ObjectId("..."),
    "name": "์ด๊ตฌ๋งค",
    "email": "buyer@example.com"
  },
  "seller": {
    "id": ObjectId("..."),
    "name": "๊น€๊ฐœ๋ฐœ",
    "email": "seller@example.com"
  },
  "talent": {
    "id": ObjectId("..."),
    "title": "MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„ ์ปจ์„คํŒ…",
    "price": 50000,
    "delivery_days": 7
  },
  "amount": 50000,
  "status": "completed",  // pending, in_progress, completed, cancelled
  "payment": {
    "method": "card",
    "paid_at": ISODate("2024-01-15T10:30:00Z"),
    "transaction_id": "TXN123456"
  },
  "delivery": {
    "started_at": ISODate("2024-01-15T11:00:00Z"),
    "completed_at": ISODate("2024-01-20T15:30:00Z"),
    "files": [
      { "name": "schema_design.pdf", "url": "https://..." }
    ]
  },
  "created_at": ISODate("2024-01-15T10:00:00Z"),
  "updated_at": ISODate("2024-01-20T15:30:00Z")
}

// ์ธ๋ฑ์Šค
db.orders.createIndex({ "buyer.id": 1, created_at: -1 })
db.orders.createIndex({ "seller.id": 1, created_at: -1 })
db.orders.createIndex({ status: 1, created_at: -1 })
db.orders.createIndex({ order_number: 1 }, { unique: true })

์ฃผ๋ฌธ ๋ฌธ์„œ๋Š” ์Šค๋ƒ…์ƒท ํŒจํ„ด์„ ์ ๊ทน ํ™œ์šฉํ–ˆ์–ด.
์ฃผ๋ฌธ ๋‹น์‹œ์˜ ์žฌ๋Šฅ ์ •๋ณด(๊ฐ€๊ฒฉ, ์ œ๋ชฉ ๋“ฑ)๋ฅผ ์ €์žฅํ•ด์„œ,
๋‚˜์ค‘์— ์žฌ๋Šฅ ์ •๋ณด๊ฐ€ ๋ฐ”๋€Œ์–ด๋„ ์ฃผ๋ฌธ ๋‚ด์—ญ์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋ผ. ๐Ÿ“ธ

// 4. Reviews ์ปฌ๋ ‰์…˜
{
  "_id": ObjectId("..."),
  "order_id": ObjectId("..."),
  "talent_id": ObjectId("..."),
  "buyer": {
    "id": ObjectId("..."),
    "name": "์ด๊ตฌ๋งค",
    "avatar": "https://..."
  },
  "seller_id": ObjectId("..."),
  "rating": 5,
  "comment": "์ •๋ง ๋„์›€์ด ๋งŽ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!",
  "images": [
    "https://...",
    "https://..."
  ],
  "reply": {  // ํŒ๋งค์ž ๋‹ต๋ณ€
    "comment": "๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!",
    "created_at": ISODate("2024-01-21T10:00:00Z")
  },
  "created_at": ISODate("2024-01-20T16:00:00Z")
}

// ์ธ๋ฑ์Šค
db.reviews.createIndex({ talent_id: 1, created_at: -1 })
db.reviews.createIndex({ "buyer.id": 1, created_at: -1 })
db.reviews.createIndex({ seller_id: 1, created_at: -1 })

๋ฆฌ๋ทฐ๋Š” ๋ณ„๋„ ์ปฌ๋ ‰์…˜์œผ๋กœ ๋ถ„๋ฆฌํ–ˆ์–ด.
์žฌ๋Šฅ ๋ฌธ์„œ์— ์ž„๋ฒ ๋””๋“œํ•˜๋ฉด ๋ฆฌ๋ทฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ๋ฌธ์„œ๊ฐ€ ๋„ˆ๋ฌด ์ปค์ง€๊ฑฐ๋“ !
๋Œ€์‹  ์žฌ๋Šฅ ๋ฌธ์„œ์—๋Š” ํ†ต๊ณ„(ํ‰๊ท  ํ‰์ , ๋ฆฌ๋ทฐ ์ˆ˜)๋งŒ ์ €์žฅํ•ด๋‘ฌ.

// 5. Messages ์ปฌ๋ ‰์…˜ (๋ฒ„ํ‚ท ํŒจํ„ด)
{
  "_id": ObjectId("..."),
  "conversation_id": "507f1f77bcf86cd799439011_507f191e810c19729de860ea",
  "participants": [
    ObjectId("507f1f77bcf86cd799439011"),
    ObjectId("507f191e810c19729de860ea")
  ],
  "start_time": ISODate("2024-01-15T10:00:00Z"),
  "end_time": ISODate("2024-01-15T11:00:00Z"),
  "messages": [
    {
      "sender_id": ObjectId("507f1f77bcf86cd799439011"),
      "text": "์•ˆ๋…•ํ•˜์„ธ์š”!",
      "timestamp": ISODate("2024-01-15T10:05:00Z"),
      "read": true
    },
    {
      "sender_id": ObjectId("507f191e810c19729de860ea"),
      "text": "๋„ค, ์•ˆ๋…•ํ•˜์„ธ์š”!",
      "timestamp": ISODate("2024-01-15T10:06:00Z"),
      "read": true
    }
    // ... ์ตœ๋Œ€ 100๊ฐœ ๋ฉ”์‹œ์ง€
  ],
  "message_count": 2
}

// ์ธ๋ฑ์Šค
db.messages.createIndex({ conversation_id: 1, start_time: -1 })
db.messages.createIndex({ participants: 1, start_time: -1 })

๋ฉ”์‹œ์ง€๋Š” ๋ฒ„ํ‚ท ํŒจํ„ด์„ ์‚ฌ์šฉํ–ˆ์–ด!
1์‹œ๊ฐ„ ๋˜๋Š” 100๊ฐœ ๋ฉ”์‹œ์ง€ ๋‹จ์œ„๋กœ ๋ฌถ์–ด์„œ ์ €์žฅํ•˜๋ฉด,
์ˆ˜๋ฐฑ๋งŒ ๊ฐœ์˜ ๋ฉ”์‹œ์ง€๋„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด. ๐Ÿ’ฌ

๐ŸŽฏ ์ฟผ๋ฆฌ ์˜ˆ์‹œ

// ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ธ๊ธฐ ์žฌ๋Šฅ ์กฐํšŒ
db.talents.find({
  "category.id": ObjectId("..."),
  status: "active"
}).sort({ "stats.rating": -1, "stats.orders": -1 }).limit(20)

// ์‚ฌ์šฉ์ž์˜ ์ฃผ๋ฌธ ๋‚ด์—ญ ์กฐํšŒ (๊ตฌ๋งค์ž)
db.orders.find({
  "buyer.id": ObjectId("...")
}).sort({ created_at: -1 })

// ์žฌ๋Šฅ ์ƒ์„ธ + ์ตœ๊ทผ ๋ฆฌ๋ทฐ ์กฐํšŒ
const talent = db.talents.findOne({ _id: ObjectId("...") })
const reviews = db.reviews.find({ 
  talent_id: ObjectId("...") 
}).sort({ created_at: -1 }).limit(10)

// ์ „๋ฌธ ๊ฒ€์ƒ‰ (์ œ๋ชฉ, ์„ค๋ช…, ํƒœ๊ทธ)
db.talents.find({
  $text: { $search: "MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„" },
  status: "active"
}).sort({ score: { $meta: "textScore" } })

// ๋Œ€ํ™” ๋‚ด์—ญ ์กฐํšŒ (์ตœ๊ทผ 10๊ฐœ ๋ฒ„ํ‚ท)
db.messages.find({
  conversation_id: "..."
}).sort({ start_time: -1 }).limit(10)
๐Ÿ’ก ์„ค๊ณ„ ํฌ์ธํŠธ ์ •๋ฆฌ

1. ์ฝ๊ธฐ ์ตœ์ ํ™”: ์ž์ฃผ ํ•จ๊ป˜ ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ์ž„๋ฒ ๋””๋“œ ๋˜๋Š” ์Šค๋ƒ…์ƒท
2. ํ™•์žฅ์„ฑ: ๋ฌดํ•œ์ • ์ปค์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ณ„๋„ ์ปฌ๋ ‰์…˜ ๋˜๋Š” ๋ฒ„ํ‚ท ํŒจํ„ด
3. ์ผ๊ด€์„ฑ: ์ฃผ๋ฌธ ๊ฐ™์€ ์ค‘์š” ๋ฐ์ดํ„ฐ๋Š” ์Šค๋ƒ…์ƒท์œผ๋กœ ๋‹น์‹œ ์ •๋ณด ๋ณด์กด
4. ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ: ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ํ•„ํ„ฐ์™€ ์ •๋ ฌ ์กฐ๊ฑด์— ๋ณตํ•ฉ ์ธ๋ฑ์Šค ์ƒ์„ฑ
5. ์œ ์—ฐ์„ฑ: ํ–ฅํ›„ ํ™•์žฅ์„ ๊ณ ๋ คํ•œ ๊ตฌ์กฐ (์˜ˆ: ์นดํ…Œ๊ณ ๋ฆฌ ๊ฒฝ๋กœ ๋ฐฐ์—ด)

๐ŸŽฌ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์™€, ์—ฌ๊ธฐ๊นŒ์ง€ ์ •๋ง ๊ธด ์—ฌ์ •์ด์—ˆ์–ด! ๐ŸŽ‰
MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„์™€ ์ปฌ๋ ‰์…˜ ์ตœ์ ํ™”์— ๋Œ€ํ•ด ๋งŽ์€ ๊ฑธ ๋ฐฐ์› ์ง€?

ํ•ต์‹ฌ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด๋ณด์ž๋ฉด:

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฝ๊ธฐ ํŒจํ„ด์„ ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„ํ•˜๋ผ
๊ด€๊ณ„ํ˜• DB์ฒ˜๋Ÿผ ์ •๊ทœํ™”์— ์ง‘์ฐฉํ•˜์ง€ ๋ง๊ณ , ํ•จ๊ป˜ ์กฐํšŒ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ํ•จ๊ป˜ ์ €์žฅํ•ด.

2. ์ž„๋ฒ ๋””๋“œ vs ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์„ ํƒํ•˜๋ผ
๋ฐ์ดํ„ฐ ํฌ๊ธฐ, ์กฐํšŒ ํŒจํ„ด, ์—…๋ฐ์ดํŠธ ๋นˆ๋„๋ฅผ ๊ณ ๋ คํ•ด์„œ ๊ฒฐ์ •ํ•ด.

3. ๊ฒ€์ฆ๋œ ํŒจํ„ด์„ ํ™œ์šฉํ•˜๋ผ
Tree, Bucket, Extended Reference ๋“ฑ ์ƒํ™ฉ์— ๋งž๋Š” ํŒจํ„ด์„ ์‚ฌ์šฉํ•ด.

4. ์ธ๋ฑ์Šค๋ฅผ ์ „๋žต์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋ผ
ESR ๊ทœ์น™์„ ๋”ฐ๋ฅด๊ณ , ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ธ๋ฑ์Šค๋Š” ๊ณผ๊ฐํžˆ ์ œ๊ฑฐํ•ด.

5. ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ๊ฐœ์„ ํ•˜๋ผ
๋А๋ฆฐ ์ฟผ๋ฆฌ๋ฅผ ์ฐพ์•„์„œ ์ตœ์ ํ™”ํ•˜๊ณ , ๋ฐ์ดํ„ฐ ํŒจํ„ด ๋ณ€ํ™”์— ๋Œ€์‘ํ•ด.

๐Ÿš€ ๋‹ค์Œ ๋‹จ๊ณ„

์ด์ œ ์ด๋ก ์€ ์ถฉ๋ถ„ํžˆ ๋ฐฐ์› ์œผ๋‹ˆ, ์ง์ ‘ ์‹ค์Šตํ•ด๋ณด๋Š” ๊ฒŒ ์ค‘์š”ํ•ด!

1. ์ž‘์€ ํ”„๋กœ์ ํŠธ๋กœ ์‹œ์ž‘: ๊ฐ„๋‹จํ•œ ๋ธ”๋กœ๊ทธ๋‚˜ TODO ์•ฑ์œผ๋กœ ์—ฐ์Šต
2. explain() ์Šต๊ด€ํ™”: ๋ชจ๋“  ์ฟผ๋ฆฌ์— explain()์„ ๋ถ™์—ฌ์„œ ์„ฑ๋Šฅ ํ™•์ธ
3. ์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ํ…Œ์ŠคํŠธ: ์ˆ˜๋งŒ~์ˆ˜์‹ญ๋งŒ ๊ฑด์˜ ๋ฐ์ดํ„ฐ๋กœ ์„ฑ๋Šฅ ์ธก์ •
4. ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ์šฉ: MongoDB ๊ณต์‹ ํฌ๋Ÿผ, Stack Overflow์—์„œ ์งˆ๋ฌธํ•˜๊ณ  ๋ฐฐ์šฐ๊ธฐ
5. ๊ณต์‹ ๋ฌธ์„œ ์ฝ๊ธฐ: MongoDB ๊ณต์‹ ๋ฌธ์„œ๋Š” ์ •๋ง ์ž˜ ๋˜์–ด ์žˆ์–ด!

์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์„ ๋งŒ๋“ค๋“ , ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋“ ,
MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ์ œ๋Œ€๋กœ ํ•˜๋Š” ๊ฒŒ ์ •๋ง ์ค‘์š”ํ•ด.
๋‚˜์ค‘์— ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋ ค๋ฉด ์—„์ฒญ๋‚œ ๊ณ ์ƒ์„ ํ•˜๊ฑฐ๋“ ! ๐Ÿ˜…

์ด ๊ธ€์ด MongoDB ์Šคํ‚ค๋งˆ ์„ค๊ณ„์— ๊ณ ๋ฏผํ•˜๋Š” ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋„์›€์ด ๋˜๊ธธ ๋ฐ”๋ผ!
๊ถ๊ธˆํ•œ ์ ์ด ์žˆ์œผ๋ฉด ์–ธ์ œ๋“  ์žฌ๋Šฅ๋„ท ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋ฌผ์–ด๋ด.
ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์ž! ๐Ÿ’ชโœจ

๐Ÿ“š ์ถ”์ฒœ ์ž๋ฃŒ

MongoDB ๊ณต์‹ ๋ฌธ์„œ: docs.mongodb.com
MongoDB University: learn.mongodb.com (๋ฌด๋ฃŒ ๊ฐ•์˜!)
MongoDB Blog: ์‹ค์ „ ์‚ฌ๋ก€์™€ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค
์žฌ๋Šฅ๋„ท ์ง€์‹์ธ์˜ ์ˆฒ: ๋” ๋งŽ์€ ๊ฐœ๋ฐœ ์ง€์‹ ๊ณต์œ !

Happy Coding! ๐ŸŽจ๐Ÿ’ป๐Ÿš€

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.