Home > Backend Development > πŸ“š[Backend Development] μ΅œλŒ€ 2 Depth λŒ“κΈ€ μ •λ ¬ ꡬ쑰의 'λ¬΄ν•œ 슀크둀 방식'μ΄λž€ λ¬΄μ—‡μΌκΉŒμš”?

πŸ“š[Backend Development] μ΅œλŒ€ 2 Depth λŒ“κΈ€ μ •λ ¬ ꡬ쑰의 'λ¬΄ν•œ 슀크둀 방식'μ΄λž€ λ¬΄μ—‡μΌκΉŒμš”?
Backend Ddevelopment

β€œπŸ“š[Backend Development] μ΅œλŒ€ 2 Depth λŒ“κΈ€ μ •λ ¬ ꡬ쑰의 β€˜λ¬΄ν•œ 슀크둀 λ°©μ‹β€™μ΄λž€ λ¬΄μ—‡μΌκΉŒμš”?”

βœ… μ΅œλŒ€ 2 Depth λŒ“κΈ€ μ •λ ¬ ꡬ쑰의 β€œλ¬΄ν•œ 슀크둀 방식” μ„€λͺ….

  • λ¬΄ν•œ 슀크둀 방식은 νŽ˜μ΄μ§€ 번호 방식(LIMIT ?, OFFSET ?)을 μ‚¬μš©ν•˜μ§€ μ•Šκ³ , λ§ˆμ§€λ§‰μœΌλ‘œ 뢈러온 λŒ“κΈ€μ˜ IDλ₯Ό κΈ°μ€€μœΌλ‘œ λ‹€μŒ λŒ“κΈ€μ„ λΆˆλŸ¬μ˜€λŠ” 방식(Keyset Pagination)μž…λ‹ˆλ‹€.
  • 이 방식은 νŽ˜μ΄μ§€ 번호 방식보닀 μ„±λŠ₯이 μš°μˆ˜ν•˜μ—¬, λŒ€λŸ‰μ˜ 데이터λ₯Ό λΉ λ₯΄κ²Œ λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ—οΈ1️⃣ λ¬΄ν•œ 슀크둀 λ°©μ‹μ΄λž€?

  • λ¬΄ν•œ 슀크둀 방식은 λ§ˆμ§€λ§‰μœΌλ‘œ 뢈러온 λŒ“κΈ€(lastCommentId)을 κΈ°μ€€μœΌλ‘œ κ·Έ 이후 데이터λ₯Ό κ°€μ Έμ˜€λŠ” λ°©μ‹μž…λ‹ˆλ‹€.
SELECT * FROM comment
WHERE article_id = ?
AND comment_id > ?
ORDER BY parent_comment_id ASC, comment_id ASC
LIMIT ?;
SQL ν‚€μ›Œλ“œ μ„€λͺ…
WHERE comment_id > ? λ§ˆμ§€λ§‰ λŒ“κΈ€ ID 이후 λ°μ΄ν„°λ§Œ κ°€μ Έμ˜΄
ORDER BY parent_comment_id ASC, comment_id ASC λΆ€λͺ¨-μžμ‹ 관계λ₯Ό μœ μ§€ν•˜λ©΄μ„œ μ •λ ¬
LIMIT ? ν•œ λ²ˆμ— κ°€μ Έμ˜¬ μ΅œλŒ€ 개수 지정
  • πŸ“Œ 이 방식을 μ‚¬μš©ν•˜λ©΄ OFFSET을 μ‚¬μš©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ„±λŠ₯이 훨씬 μš°μˆ˜ν•©λ‹ˆλ‹€.

πŸ—οΈ2️⃣ SQL 예제 (λ¬΄ν•œ 슀크둀 방식)

  • 예λ₯Ό λ“€μ–΄, ν•œ λ²ˆμ— 3개의 λŒ“κΈ€μ„ λΆˆλŸ¬μ˜€λ„λ‘ μ„€μ •ν•˜κ³ , λ§ˆμ§€λ§‰μœΌλ‘œ 뢈러온 λŒ“κΈ€μ˜ ID(lastCommentId)κ°€ 3이라고 κ°€μ •ν•©λ‹ˆλ‹€.
SELECT * FROM comment
WHERE article_id = ?
AND comment_id > 3
ORDER BY parent_comment_id ASC, comment_id ASC
LIMIT 3;

πŸ—οΈ3️⃣ μ •λ ¬ 방식

πŸ“Œ μ •λ ¬ κΈ°μ€€.

ORDER BY parent_comment_id ASC, comment_id ASC
    1. μ΅œμƒμœ„ λŒ“κΈ€μ„ λ¨Όμ € μ •λ ¬ ➞ parent_comment_id IS NULL μˆœμ„œλŒ€λ‘œ μ •λ ¬
    1. λŒ€λŒ“κΈ€μ€ 같은 λΆ€λͺ¨ μ•„λž˜μ—μ„œ μ •λ ¬ ➞ comment_id ASC μˆœμ„œλ‘œ μ •λ ¬
    1. νŽ˜μ΄μ§• 없이 WHERE comment_id > lastCommentId λ°©μ‹μœΌλ‘œ 쑰회

πŸ—οΈ4️⃣ 데이터 μ˜ˆμ‹œ.

πŸ“Œ λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯된 λŒ“κΈ€ 데이터

comment_id parent_comment_id λ‚΄μš©
1 NULL λŒ“κΈ€1 (μ΅œμƒμœ„ λŒ“κΈ€)
2 1 λŒ“κΈ€2 (λŒ“κΈ€1의 λŒ€λŒ“κΈ€)
3 NULL λŒ“κΈ€3 (μ΅œμƒμœ„ λŒ“κΈ€)
4 1 λŒ“κΈ€4 (λŒ“κΈ€1의 λŒ€λŒ“κΈ€)
5 3 λŒ“κΈ€5 (λŒ“κΈ€3의 λŒ€λŒ“κΈ€)
6 NULL λŒ“κΈ€6 (μ΅œμƒμœ„ λŒ“κΈ€)

πŸ“Œ λ¬΄ν•œ 슀크둀 λ°©μ‹μœΌλ‘œ 데이터 쑰회.

βœ… 첫 번째 μš”μ²­(lastCommentId = 0)

SELECT * FROM comment
WHERE article_id = ?
AND comment_id > 0
ORDER BY parent_comment_id ASC, comment_id ASC
LIMIT 3;

πŸ“Œ κ²°κ³Ό

comment_id parent_comment_id λ‚΄μš©
1 NULL λŒ“κΈ€1 (μ΅œμƒμœ„ λŒ“κΈ€)
2 1 λŒ“κΈ€2 (λŒ“κΈ€1의 λŒ€λŒ“κΈ€)
4 1 λŒ“κΈ€4 (λŒ“κΈ€1의 λŒ€λŒ“κΈ€)
  • πŸ“Œ λ§ˆμ§€λ§‰ λŒ“κΈ€ ID = 4

βœ… 두 번째 μš”μ²­(lastCommentId = 4)

SELECT * FROM comment
WHERE article_id = ?
AND comment_id > 4
ORDER BY parent_comment_id ASC, comment_id ASC
LIMIT 3;

πŸ“Œ κ²°κ³Ό

comment_id parent_comment_id λ‚΄μš©
3 NULL λŒ“κΈ€3 (μ΅œμƒμœ„ λŒ“κΈ€)
5 3 λŒ“κΈ€5 (λŒ“κΈ€3의 λŒ€λŒ“κΈ€)
6 NULL λŒ“κΈ€6 (μ΅œμƒμœ„ λŒ“κΈ€)
  • πŸ“Œ λ§ˆμ§€λ§‰ λŒ“κΈ€ ID = 6

πŸ—οΈ5️⃣ μž₯점과 단점.

μž₯점 단점
OFFSET 없이 λΉ λ₯Έ 쑰회 κ°€λŠ₯ (μ„±λŠ₯ μ΅œμ ν™”) lastCommentIdλ₯Ό ν΄λΌμ΄μ–ΈνŠΈκ°€ μœ μ§€ν•΄μ•Ό 함
λŒ€λŸ‰μ˜ λŒ“κΈ€μ΄ μžˆλŠ” 경우 효율적 λŒ“κΈ€μ΄ μ‚­μ œλ  경우 정렬이 흐트러질 κ°€λŠ₯성이 있음
νŽ˜μ΄μ§€ 번호 방식보닀 ν™•μž₯성이 μ’‹μŒ μ •λ ¬ μˆœμ„œκ°€ μœ μ§€λ˜λ„λ‘ 쑰심해야 함

πŸš€6️⃣ 정리.

  • βœ… λ¬΄ν•œ 슀크둀 방식은 WHERE comment_id > lastCommentIdλ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터 쑰회
  • βœ… ORDER BY parent_comment_id ASC, comment_id ASCλ₯Ό μ‚¬μš©ν•΄ 계측 ꡬ쑰 μœ μ§€
  • βœ… νŽ˜μ΄μ§€ 번호 방식(LIMIT ?, OFFSET ?)보닀 μ„±λŠ₯이 μš°μˆ˜ν•˜λ©° λŒ€λŸ‰ 데이터 μ²˜λ¦¬μ— 적합
  • βœ… λ§ˆμ§€λ§‰ λŒ“κΈ€ ID(lastCommentId)λ₯Ό μœ μ§€ν•΄μ•Ό 함
  • πŸ“Œ μ΅œλŒ€ 2 Depth λŒ“κΈ€ κ΅¬μ‘°μ—μ„œλŠ” λ¬΄ν•œ 슀크둀 방식이 μ„±λŠ₯ μ΅œμ ν™”μ— μœ λ¦¬ν•˜λ©°, λΉ λ₯΄κ²Œ λŒ“κΈ€μ„ 뢈러올 수 μžˆμŠ΅λ‹ˆλ‹€.