-
Notifications
You must be signed in to change notification settings - Fork 1
๐ DB ์๋ณ์ ๊ฐ์ผ๋ก UUID v7 ์ฌ์ฉํ๊ธฐ
์ฟผ๋ฆฌ๊ฐ ์๋ํ ๋๋ก ๋์ํ์ง ์์ต๋๋ค. ์ธ๋ฑ์ค ์ค์บ์ด ๋์ง ์์ต๋๋ค.
select max(basechat2_.chat_id)
from chat basechat2_
where basechat2_.room_id = roomuser0_.room_id
order by basechat2_.create_at desc,
basechat2_.chat_id desc
์ ์ฒด ์ฟผ๋ฆฌ๋ก ํ๋ฉด ๊ธธ์ด์ง๊ธฐ ๋๋ฌธ์ ์ ์ฒด ์ฟผ๋ฆฌ ์ค ๋ฌธ์ ์ ์๋ธ์ฟผ๋ฆฌ๋ง ์์ฑํ์์ต๋๋ค.
create_at
๋ ์๊ฐ ์์ด๋ฉฐ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
chat_id
๋ ์๊ฐ ์์ผ๋ก ์์ฐจ์ ์ผ๋ก ์ถ๊ฐ๋๋ฉฐ ๋ณ๊ฒฝํ์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ MySQL์์๋ A, B ๋ ์ฝ๋๊ฐ ์์ ๋, A๊ฐ B๋ณด๋ค create_at
์ด ํฌ๋ฉด chat_id
๋ ํฌ๋ค๋ ๊ฑธ ๋ชจ๋ฆ
๋๋ค(์ดํ๋ฆฌ์ผ์ด์
๋จ์์ ์ ํ ๊ท์น์ด๋ฏ๋ก).
ํ์ฌ ์ธ๋ฑ์ค๊ฐ basechat_idx(room_id, create_at, chat_id)
์ธ๋ฐ, room_id
๊น์ง๋ง ์ ํจํ๊ณ ์ค๊ฐ์ create_at
๊ฐ ์์ด์ ์ฒ๋ฆฌ๊ฐ ๋์ง์์ต๋๋ค.
๊ทธ๋์ room์ ๋ชจ๋ chat์ index full scanํ๊ฒ ๋ฉ๋๋ค.
- user 100๋ช
- room 200
- roomuser 100 ๊ฐ
- chat 100000 ๊ฐ = ํ ๋ฐฉ๋น 500๊ฐ
index full scan = ํ ์ด๋ธ ๋ฐ์ดํฐ๊ฐ ๋์ด๋ ์๋ก ์ฝ๋ ๋์ด ์ฆ๊ฐ -> ์ฑ๋ฅ ๊ฐ์
์ธ๋ฑ์ค ์กฐ๊ฑด์ผ๋ก ์ธํ ๋ฌธ์ ์ด์ง๋ง, ๋ ๊ทผ๋ณธ์ ์ผ๋ก๋ id์ create_at์ผ๋ก ์๊ฐ ์ ์ ๋ ฌ 2๊ฐ์ง ๊ฐ์ ๋ชจ๋ ์ฌ์ฉํ๋ ค๊ณ ํด์ ์๊ธด ๋ฌธ์ ์ ๋๋ค.
- ์ธ๋ฑ์ค ์ถ๊ฐ/์กฐ๊ฑด ์์
- ์ฑ๋ฅ ๊ฐ์ or ์ ์ฐํ ์ฟผ๋ฆฌ(ํน์ ์๊ฐ ์ ๊ฒ์ ๋ฑ) ์ค์ ํ๋๋ ํฌ๊ธฐ๋ฅผ ํด์ผ ํฉ๋๋ค.
- ์๊ฐ ์ ๋ณด๊ฐ ํฌํจ๋ ID๋ฅผ ์ฌ์ฉํ๊ธฐ
- ๊ทผ๋ณธ์ ์ธ ์์ธ ํด๊ฒฐ
- Native SQL์ ์ฌ์ฉํ๊ธฐ
- JPA์ ํ๊ณ๋ก from ์ ์๋ธ์ฟผ๋ฆฌ ๋ฐ ์๋ธ์ฟผ๋ฆฌ limit์ด ๋ถ๊ฐ๋ฅ, ํ์ง๋ง ์ง์ SQL๋ฌธ์ ์์ฑํ๋ค๋ฉด ๊ธฐ์กด ๊ตฌ์กฐ๋ก๋ ์ ํจํ ์ค๊ณ๋ฅผ ๊ฐ์ ธ๊ฐ ์ ์์ต๋๋ค.
2๋ฒ ๋ฐฉ๋ฒ ์ฑํ ์ด์ : ์ค๊ณ ๋จ๊ณ์ด๋ฏ๋ก, ๊ธฐ์กด ๋ฐ์ดํฐ์์ ํธํ์ฑ์ ๊ฑฑ์ ํ์ง ์์๋ ๋ฉ๋๋ค. long, localdate์ byte ํฌ๊ธฐ๋ฅผ ํฉ์น๋ฉด uuid์ ๋์ผํ์ฌ ์ ์ฅ๊ณต๊ฐ ๋ฌธ์ ๋ ์ ์ต๋๋ค.
- ObjectID: MongoDB์์ ์ฌ์ฉํจ, ์๊ฐ ์ ์ ๋ ฌ, 96bit(12-bytes)
- UUID: 128bit(16byte), ํ์ค์ผ๋ก ๋๋ฆฌ ์ฐ์. v1๊ณผ v7๋ง ์๊ฐ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋๋ฉฐ, ์๊ฐ ์ ์ ๋ ฌ์ด ๊ฐ๋ฅํฉ๋๋ค.
- ULID: UUID์ ํธํ๋จ, ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ์ปค์คํ UUID ํ์
- Snowflake ID: ํธ์ํฐ์์ ๋ง๋ PK, ์คํ์์ค ํ๋ ๊ฑธ๋ก ์๋๋ฐ ์ง๊ธ์ ์๋๋๋ค.
- ULID์ ๋ฌ๋ฆฌ ํ์ค์ ๋๋ค.
- v1์ฒ๋ผ ํ์ํ์ง ์์ MAC address(๋ณด์ ์ ๋ฌธ์ ๊ฐ ์๊ธธ ์๋ ์๋ค๊ณ ํจ)๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.
- ์๊ฐ ์ ์ธํ๊ณ ๋๋จธ์ง ์์๋ ์ ๋ถ ์์ฐจ์ ์ธ ๋๋ค ๋ฐ์ดํฐ์ ๋๋ค (๊ตฌํ์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์๋ค๊ณ ํจ)
- ์คํ๊ฐ ๊ฝค ๋ง์ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์กด์ฌํจ (ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋น)
- ๊ทธ๋ฆฌ๊ณ JPA์ ํธํ์ ์ํด ULID ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ULID ํ์ ์ ์ฌ์ฉํ๋๋ผ๋ ์ ์ฅ์ UUID๋ก ํ๊ณ ULID์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํด์ ํ๋ณํ์ ํด์ผ ํ๋๋ฐ, ์ด๋ฌํ ๋ณํ ๊ณผ์ ์ด ๋ฒ๊ฑฐ๋ก์ธ ์ ์์ต๋๋ค.
์ค์ ์๋น์ค์์ ์๋ณ์๋ก ์ฌ์ฉํ๊ธฐ๋ ํฉ๋๋ค. CICD ํด์ ์ ๊ณตํ๋ Buildkite
์๋น์ค์์ ์๋ณ์๋ก UUIDv7์ ์ฑํํ๊ธฐ๋ ํ์ต๋๋ค.
์คํ ์๊ฐ ๋ ๋ง์ 1 ์ ํ
https://buildkite.com/blog/goodbye-integers-hello-uuids << ์ฐธ๊ณ
0x018B5642A68F7892AD50248BAC01E76C
<< Chat ID ์ผ๋,
0x018B5642A68F
๋ฅผ Hex to Decimal ํ๋ฉด 1697959290511
๊ฐ ๋์ต๋๋ค. ์ด ๊ฐ์ด ์๊ฐ ์ ๋ณด(epoch time)์
๋๋ค.
์ฝํ๋ฆฐ ์ฝ๋๋ก UUID๋ฅผ ์๊ฐ ์ ๋ณด๋ฅผ ํฌํจํ๋ long ํ์ ์ผ๋ก ๋ณํํ๋ ค๋ฉด ์๋์ฒ๋ผ ๊ตฌํ ๊ฐ๋ฅํฉ๋๋ค.
fun getTime(uuid: UUID): Long { return uuid.mostSignificantBits ushr 16 }
msb๊ฐ 64๋นํธ๋๊น ์ค๋ฅธ์ชฝ์ผ๋ก 16๋นํธ ์ํํธ ํด์ 48๋นํธ๋ง ๊ตฌํด์ ์๊ฐ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
๋ ์ง ๊ธฐ์ค์ผ๋ก ์ฟผ๋ฆฌ ์ฌ์ฉ ์์๋
select *
from chat
where chat_id <= 1697959290511
๋ก ๊ฒ์ํ ์ ์์ต๋๋ค. (16์ง์๋ 10์ง์๋ ํธํ๋๋ ๋ฏ)
์๋๋ฉด 0x018B5B123FAA72E2BE5953AAF2A0741B
์ฒ๋ผ ๊ฑ 16์ง์ ์จ๋ ์คํ ๊ฐ๋ฅ
๋์ UUIDv7 ํน์ง ์ ์์๋ฆฌ๊ฐ ์๊ฐ์ด๊ณ ๋๋จธ์ง๋ ๋๋ค์ด๋ผ ์ ํํ ๊ทธ ์๊ฐ๋๋๋ผ๋ <=
์กฐ๊ฑด์ผ๋ก ๊ฒ์ํด์ผ ํฉ๋๋ค(์ด์ฐจํผ ==
์กฐ๊ฑด ์ฐ๋ฉด ์๋ฌ).
๋ง์ฝ ํน์ ์๊ฐ๋ ์ดํ(>=
) ์กฐ๊ฑด์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด?
select *
from chat
where chat_id > 1697959290511 + 1 # ์๊ฐ๋์ 1 ๋ฐ๋ฆฌ์ด๋ฅผ ์ถ๊ฐํ๊ณ ๋ฏธ๋ง ์กฐ๊ฑด์ผ๋ก ๊ฒ์ํ๋ ๊ฒ
์ฒ๋ผ ์ฌ์ฉํฉ๋๋ค.
JDK์๋ 64๋นํธ ๊ฐ์ ์์งํ ๋น๊ต๋ฅผ ์ฌ์ฉํ๋
java.util.UUID
์ ๊ตฌํ์ ๊ฒฐํจ์ด ์์ต๋๋ค.
compareTo()
๊ธฐ๋ณธ ์ฝํ ์ธ ๊ฐ ๋ชจ๋ ๋ชฉ์ ์ ๋ํด ์๋ช ๋์ง ์์ ๊ฒฝ์ฐ ์ด๋ ์์๋๋ก ์๋ํ์ง ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ๋ ๊ฐ์ UUID๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
7f905a0b-bb6e-11e3-9e8f-000000000000
8028f08c-bb6e-11e3-9e8f-000000000000
๋ถํธ ํ์ฅ์ผ๋ก ์ธํด ๋ ๋ฒ์งธ ๊ฐ๋ถํฐ ๋จผ์ ์ฃผ๋ฌธ๋ฉ๋๋ค(๋ ๋ฒ์งธ ๊ฐ์ ์์๋ก ๊ฐ์ฃผ๋๋ฏ๋ก "๋ ์์").
์ด ๋๋ฌธ์ ํญ์
com.fasterxml.uuid.UUIDComparator
๊ฐ๋จํ ๋ถํธ ์๋ ์ ๋ ฌ์ธ ์์ ์ ๋ ฌ ์์๋ฅผ ๊ตฌํํ๋ ์ ๊ฐ์ ์ธ๋ถ ๋น๊ต๊ธฐ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์ด๋ UUID์ ์ฌ์ ์(์ํ๋ฒณ) ์ ๋ ฌ(๊ท ์ผํ ๋๋ฌธ์ ์ฌ์ฉ์ ๊ฐ์ ํ ๋)๊ณผ ๋์ผํฉ๋๋ค.
์ ๊ธ์ java-uuid-generator์์ ์ฐธ๊ณ
LocalDateTime์ Long์ผ๋ก ๋ณํ or ๋ฐ๋ ๋ก์ง์ ์ํํ๋ ๊ฒฝ์ฐ์์
LocalDateTime.MAX
๋ฅผ ์ฌ์ฉํ๋ฉด Long ๋ณํ ๊ณผ์ ์์ overflow ๋ฐ์
-> LocalDateTime.MAX
๋์ 5000 ๋
๋ ์๊ฐ์ผ๋ก ๋ณ๊ฒฝํ๊ณ Util ํด๋์ค์์ ๊ณต์ ํด์ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝ
id
์ ์๊ฐ ์ ๋ณด๊ฐ ํฌํจ๋๊ธฐ ๋๋ฌธ์ create_at
์ ์ญ์ ,
์ธ๋ฑ์ค ๊ตฌ์กฐ๋ฅผ chat_idx_1(room_id ASC, chat_id DESC),
๋ก ๋ณ๊ฒฝ
SELECT MAX(chat.chat_id) FROM chat WHERE chat.room_id = 11
์คํ ๊ณํ
-> Zero input rows (No matching min/max row), aggregated into one output row (cost=0..0 rows=1) (actual time=0.00954..0.00963 rows=1 loops=1)
room_id=11
์๋ 500๊ฐ์ ์ฑํ
์ด ์์ง๋ง ํ๋์ ๋ ์ฝ๋๋ง ์ฝ๊ณ ์ฟผ๋ฆฌ๋ฅผ ์ข
๋ฃํฉ๋๋ค.
SELECT count(chat.chat_id) FROM chat WHERE chat.room_id = 11
-> Aggregate: count(chat.chat_id) (cost=101 rows=1) (actual time=0.257..0.257 rows=1 loops=1)
-> Covering index lookup on chat using chat_idx_1 (room_id=11) (cost=50.9 rows=500) (actual time=0.0692..0.223 rows=500 loops=1)
์๊ฐ ์ ์ ๋ ฌ๊ณผ ์๊ฐ ๋ฐ์ดํฐ๊น์ง ํ๋๋ก ์ฒ๋ฆฌํจ์ผ๋ก์จ ์ธ๋ฑ์ค๋ฅผ ๋์ฑ ํจ๊ณผ์ ์ผ๋ก ์ค๊ณํ ์ ์์์ต๋๋ค.
๋์ค์ ์ํฐํฐ ๊ตฌ์กฐ ์์ฒด๊ฐ ๋ณ๊ฒฝ๋์ด์ ํด๋น ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง๋ ์๊ฒ ๋์์ต๋๋ค.
ํ์ง๋ง UUID๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ํจ์จ์ ์ธ ์ธ๋ฑ์ค ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ก๊ณ , ์ดํ ์๋กญ๊ฒ ๊ตฌํํ๋ ๊ตฌ์กฐ์์๋ ์ฌ์ฉ๋์์ต๋๋ค.