์ค๋ณต๊ณผ ๊ณต๋ฐฑ์ ํผํ๋ ๋์์ฑ ์์ ์ฒญ๊ตฌ์ ๋ฒํธ ์ง์
์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ์ฒญ๊ตฌ์๋ ํฐ์ผ์ ์์ฑํด๋ ์ค๋ณต์ด๋ ์๊ธฐ์น ์์ ๊ณต๋ฐฑ ์์ด ๋์ํ๋ ์ค์ฉ์ ์ธ ํจํด์ ์์๋ณด์ธ์.

๋ ์ฌ๋์ด ๋์์ ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด ์ด๋ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊น
๋ฐ์ ์ฌ๋ฌด์ค์์ ์คํ 4์ 55๋ถ์ ์์ํด๋ณด์ธ์. ๋ ์ฌ๋์ด ๊ฑฐ์ ๊ฐ์ ์๊ฐ์ ์ฒญ๊ตฌ์๋ฅผ ๋ง์น๊ณ ์ ์ฅ์ ๋๋ฆ ๋๋ค. ๋ ํ๋ฉด ๋ชจ๋ ์ ๊น "์ฒญ๊ตฌ์ #1042"๋ฅผ ๋ณด์ฌ์ค๋๋ค. ํ ๋ ์ฝ๋๋ ์ ์ฅ๋๊ณ , ๋ค๋ฅธ ํ๋๋ ์คํจํ๊ฑฐ๋, ๋ ๋์๊ฒ๋ ๋ ๋ค ๊ฐ์ ๋ฒํธ๋ก ์ ์ฅ๋ ์ ์์ต๋๋ค. ์ด๋ ์ค์ ํ๊ฒฝ์์ ๊ฐ์ฅ ํํ ๋ณด์ด๋ ์ฆ์์ ๋๋ค: ๋ถํ๊ฐ ๊ฑธ๋ฆด ๋๋ง ๋ํ๋๋ ์ค๋ณต ๋ฒํธ.
ํฐ์ผ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ๋ ์๋ด์ฌ๊ฐ ๋์์ ๊ฐ์ ๊ณ ๊ฐ์ ์ ํฐ์ผ์ ์์ฑํ๊ณ ์์คํ ์ด ๊ฐ์ฅ ์ต์ ๋ ์ฝ๋๋ฅผ ๋ณด๊ณ "๋ค์ ๋ฒํธ"๋ฅผ ์ ํํ๋ ค ํ๋ฉด, ๋ ๋ค ๊ฐ์ ์ต์ ๊ฐ์ ์ฝ๊ณ ๊ฐ์ ๋ค์ ๋ฒํธ๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
๋ ๋ฒ์งธ ์ฆ์์ ๋ ๋ฏธ๋ฌํฉ๋๋ค: ๋ฒํธ๊ฐ ๊ฑด๋๋ฐ์ด ๋ณด์ด๋ ๊ฒฝ์ฐ์ ๋๋ค. ์๋ฅผ ๋ค์ด #1042 ๋ค์์ #1044๊ฐ ์๊ณ #1043์ด ๋น ์ ธ ์๋ ์์ ๋๋ค. ์ด๋ ์ค๋ฅ๋ ์ฌ์๋ ํ์ ์ข ์ข ๋ฐ์ํฉ๋๋ค. ํ ์์ฒญ์ด ๋ฒํธ๋ฅผ ์์ฝํ์ง๋ง ์ ์ฅ์ด ๊ฒ์ฆ ์ค๋ฅ, ํ์์์, ๋๋ ์ฌ์ฉ์๊ฐ ํญ์ ๋ซ์์ ์คํจํ ์ ์์ต๋๋ค. ๋๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ด ๋คํธ์ํฌ ๋ฌธ์ ๋ก ์ฌ์๋ํ๋ฉด์ ์ฒซ ๋ฒ์งธ ์๋๊ฐ ์ด๋ฏธ ๋ฒํธ๋ฅผ ์๋นํ์์๋ ์ ๋ฒํธ๋ฅผ ๊ฐ์ ธ๊ฐ ์ ์์ต๋๋ค.
์ฒญ๊ตฌ์์ ๊ฒฝ์ฐ ๋ฒํธ ์ง์ ์ ๊ฐ์ฌ ์ถ์ ์ ์ผ๋ถ๋ผ ์ค์ํฉ๋๋ค. ํ๊ณ๋ด๋น์๋ ๊ฐ ์ฒญ๊ตฌ์๊ฐ ๊ณ ์ ํ๊ฒ ์๋ณ๋๊ธธ ๊ธฐ๋ํ๊ณ , ๊ณ ๊ฐ์ ๊ฒฐ์ ๋ ๋ฌธ์์์ ์ฒญ๊ตฌ์ ๋ฒํธ๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค. ํฐ์ผ์์๋ ๋ฒํธ๊ฐ ๋ํ, ๋ณด๊ณ ์, ๋ด๋ณด๋ด๊ธฐ ๋ฑ์์ ๋ชจ๋ ์ฌ๋์ด ์ฌ์ฉํ๋ ์๋ณ์์ ๋๋ค. ์ค๋ณต์ ํผ๋์ ๋ง๋ค๊ณ , ๋๋ฝ๋ ๋ฒํธ๋ ๋ถ์ ํ์๊ฐ ์์ด๋ ๊ฒํ ์ ์๋ฌธ์ ๋ถ๋ฌ์ผ์ผํฌ ์ ์์ต๋๋ค.
์ด๊ธฐ์ ๋ถ๋ช ํ ํด๋ ํต์ฌ ๊ธฐ๋์น๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: ๋ชจ๋ ๋ฒํธ ์ง์ ๋ฐฉ๋ฒ์ด ๋์์ฑ ์์ ์ฑ๊ณผ ๊ณต๋ฐฑ ์์(gapless)์ ๋์์ ๋ง์กฑ์ํฌ ์๋ ์์ต๋๋ค. ๋์์ฑ ์์ ํ ๋ฒํธ ์ง์ (๋ง์ ์ฌ์ฉ์๊ฐ ์์ด๋ ์ค๋ณต์ด ๋ฐ์ํ์ง ์์)์ ๋ฌ์ฑ ๊ฐ๋ฅํ๋ฉฐ ํ์์ ์ ๋๋ค. ๊ณต๋ฐฑ ์๋ ๋ฒํธ๋ ๊ฐ๋ฅํ์ง๋ง ์ถ๊ฐ ๊ท์น์ด ํ์ํ๊ณ ์ด์, ์คํจ, ์ทจ์๋ฅผ ๋ค๋ฃจ๋ ๋ฐฉ์์ ๋ฐ๊พธ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
๋ฌธ์ ๋ฅผ ์ ์ํ๋ ์ข์ ๋ฐฉ๋ฒ์ ๋ฒํธ๊ฐ ์ด๋ค ๋ณด์ฅ์ ํด์ผ ํ๋์ง ๋ฌป๋ ๊ฒ์ ๋๋ค:
- ์ ๋ ๋ฐ๋ณต๋๋ฉด ์ ๋๋ค(ํญ์ ๊ณ ์ )
- ๋๋ถ๋ถ ์ฆ๊ฐํ๋ฉด ์ข๋ค(์์ผ๋ฉด ์ข์)
- ์ ๋ ๊ฑด๋๋ฐ๋ฉด ์ ๋๋ค(์ค๊ณํ ๊ฒฝ์ฐ์๋ง)
๋ฃฐ์ ์ ํ๋ฉด ๊ธฐ์ ์ ์๋ฃจ์ ์ ํ์ด ํจ์ฌ ์ฌ์์ง๋๋ค.
์ค๋ณต๊ณผ ๊ณต๋ฐฑ์ด ๋ฐ์ํ๋ ์ด์
๋๋ถ๋ถ์ ์ฑ์ ๊ฐ๋จํ ํจํด์ ๋ฐ๋ฆ ๋๋ค: ์ฌ์ฉ์๊ฐ ์ ์ฅ์ ๋๋ฅด๋ฉด ์ฑ์ด ๋ค์ ์ฒญ๊ตฌ์๋ ํฐ์ผ ๋ฒํธ๋ฅผ ์์ฒญํ๊ณ , ๊ทธ ๋ฒํธ๋ก ์ ๋ ์ฝ๋๋ฅผ ์ฝ์ ํฉ๋๋ค. ํ ์ฌ๋๋ง ์์ ํ ๋๋ ์๋ฒฝํ๊ฒ ์๋ํ๋ฏ๋ก ์์ ํด ๋ณด์ ๋๋ค.
๋ฌธ์ ๋ ๋ ๊ฐ์ ์ ์ฅ์ด ๊ฑฐ์ ๋์์ ๋ฐ์ํ ๋ ์์๋ฉ๋๋ค. ๋ ์์ฒญ์ด ์ด๋ ํ๋๋ ์ฝ์ ์ ๋ง์น๊ธฐ ์ ์ "๋ค์ ๋ฒํธ ๊ฐ์ ธ์ค๊ธฐ" ๋จ๊ณ์ ๋๋ฌํ ์ ์์ต๋๋ค. ๋ ๋ค ๊ฐ์ "๋ค์" ๊ฐ์ ๋ณด๋ฉด ๊ฐ์ ๋ฒํธ๋ฅผ ์ฐ๋ ค๊ณ ํฉ๋๋ค. ์ด๊ฒ์ด ๊ฒฝ์ ์ํ(race condition)์ ๋๋ค: ๊ฒฐ๊ณผ๊ฐ ๋ก์ง์ด ์๋๋ผ ํ์ด๋ฐ์ ๋ฌ๋ ค ์์ต๋๋ค.
์ ํ์ ์ธ ํ์๋ผ์ธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์์ฒญ A๊ฐ ๋ค์ ๋ฒํธ๋ฅผ ์ฝ์: 1042
- ์์ฒญ B๊ฐ ๋ค์ ๋ฒํธ๋ฅผ ์ฝ์: 1042
- ์์ฒญ A๊ฐ ์ฒญ๊ตฌ์ 1042 ์ฝ์
- ์์ฒญ B๊ฐ ์ฒญ๊ตฌ์ 1042 ์ฝ์ (๋๋ ๊ณ ์ ์ ์ฝ์ด ๋ง์ ์คํจ)
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ ๋ฒ์งธ ์ฝ์ ์ ๋ง๋ ์ฅ์น๊ฐ ์์ผ๋ฉด ์ค๋ณต์ด ๋ฐ์ํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์์ "์ด ๋ฒํธ๊ฐ ์ฌ์ฉ๋๋?"๋ฅผ ๊ฒ์ฌ๋ง ํด๋, ๊ฒ์ฌ์ ์ฝ์ ์ฌ์ด์ ๊ฒฝ์์์ ์ง ์ ์์ต๋๋ค.
๊ณต๋ฐฑ์ ๋ค๋ฅธ ๋ฌธ์ ์ ๋๋ค. ์์คํ ์ด ๋ฒํธ๋ฅผ "์์ฝ"ํ์ง๋ง ๋ ์ฝ๋๊ฐ ์ค์ ๋ก ์ปค๋ฐ๋์ง ์์ ๋ ๋ฐ์ํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ์์ธ์ ๊ฒฐ์ ์คํจ, ๋์ค์ ๋ฐ๊ฒฌ๋ ๊ฒ์ฆ ์ค๋ฅ, ํ์์์, ๋๋ ์ฌ์ฉ์๊ฐ ๋ฒํธ๊ฐ ํ ๋น๋ ๋ค ํญ์ ๋ซ๋ ๊ฒฝ์ฐ์ ๋๋ค. ์ฝ์ ์ด ์คํจํด์ ์๋ฌด ๊ฒ๋ ์ ์ฅ๋์ง ์์๋ ๊ทธ ๋ฒํธ๋ ์ด๋ฏธ ์๋น๋์ ์ ์์ต๋๋ค.
๋ณด์ด์ง ์๋ ๋์์ฑ์ ์ด๋ฅผ ๋ ์ ํ์ํต๋๋ค. ๋ฌธ์ ๋ ๋จ์ํ "๋ ์ฌ๋์ด ์ ์ฅ ๋ฒํผ์ ๋๋ฆ"์ด ์๋๋๋ค. ๋ํ ๋ค์๊ณผ ๊ฐ์ ์ผ์ด ์์ ์ ์์ต๋๋ค:
- ๋ณ๋ ฌ๋ก ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ API ํด๋ผ์ด์ธํธ
- ๋ฐฐ์น๋ก ์คํ๋๋ ์ํฌํธ
- ์ผ๊ฐ์ ์ฒญ๊ตฌ์๋ฅผ ์์ฑํ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
- ์ฐ๊ฒฐ์ด ๋ถ์์ ํ ๋ชจ๋ฐ์ผ ์ฑ์ ์ฌ์๋
๋ฐ๋ผ์ ๊ทผ๋ณธ ์์ธ์: (1) ์ฌ๋ฌ ์์ฒญ์ด ๊ฐ์ ์นด์ดํฐ ๊ฐ์ ์ฝ์ ๋์ ํ์ด๋ฐ ์ถฉ๋, ๊ทธ๋ฆฌ๊ณ (2) ํธ๋์ญ์ ์ด ์ฑ๊ณตํ ์ง ํ์คํ๊ธฐ ์ ์ ๋ฒํธ๋ฅผ ํ ๋นํ๋ ๊ฒ์ ๋๋ค. ๋์์ฑ ์์ ํ ๋ฒํธ ์ง์ ๊ณํ์ ์ด๋ค ๊ฒฐ๊ณผ๋ฅผ ํ์ฉํ ์ง(์ค๋ณต ์์, ๊ณต๋ฐฑ ์์, ๋๋ ๋ ๋ค) ๊ทธ๋ฆฌ๊ณ ์ด๋ค ์ด๋ฒคํธ(์ด์, ์ฌ์๋, ์ทจ์)์ ๋ํด ํ์ฉํ ์ง ๊ฒฐ์ ํด์ผ ํฉ๋๋ค.
์๋ฃจ์ ์ ๊ณ ๋ฅด๊ธฐ ์ ์ ๋ฒํธ ๊ท์น์ ์ ํ์ธ์
๋์์ฑ ์์ ๋ฒํธ ์ง์ ์ ์ค๊ณํ๊ธฐ ์ ์, ๋ฒํธ๊ฐ ๋น์ฆ๋์ค์ ์ผ๋ก ์ด๋ค ์๋ฏธ์ธ์ง ํ ๋ฌธ์ฅ์ผ๋ก ์ ์ด๋์ธ์. ๊ฐ์ฅ ํํ ์ค์๋ ๊ธฐ์ ์ ๋ฐฉ๋ฒ์ ๋จผ์ ์ ํํ๊ณ ๋์ค์ ํ๊ณ๋ ๋ฒ์ ๊ท์น์ด ๋ค๋ฅธ ๊ธฐ๋๋ฅผ ๊ฐ์ง๊ณ ์์์ ๋ฐ๊ฒฌํ๋ ๊ฒ์ ๋๋ค.
๋ณดํต ํผ๋๋๋ ๋ ๋ชฉํ๋ฅผ ๋ถ๋ฆฌํด์ ์์ํ์ธ์:
- ๊ณ ์ (Unique): ๋ ์ฒญ๊ตฌ์๋ ํฐ์ผ์ด ๋์ผํ ๋ฒํธ๋ฅผ ์ ๋ ๊ณต์ ํ์ง ์์
- ๊ณต๋ฐฑ ์์(Gapless): ๊ณ ์ ํ๊ณ ๋ํ ์๊ฒฉํ ์ฐ์์ (๋๋ฝ ์์)
๋ง์ ์์คํ ์ ๊ณ ์ ์ฑ๋ง์ ๋ชฉํ๋ก ํ๊ณ ๊ณต๋ฐฑ์ ํ์ฉํฉ๋๋ค. ๊ณต๋ฐฑ์ ์ ์์ ์ธ ์ด์ ๋ก ๋ฐ์ํ ์ ์์ต๋๋ค: ์ฌ์ฉ์๊ฐ ์ด์์ ์ด๊ณ ๋ฒ๋ฆผ, ๊ฒฐ์ ์คํจ๋ก ์์ฝ๋ ๋ฒํธ ์๋ชจ, ๋๋ ๋ ์ฝ๋ ์์ฑ ํ ๋ฌดํจ ์ฒ๋ฆฌ ๋ฑ. ํฌํ๋ฐ์คํฌ ํฐ์ผ์ ๊ฒฝ์ฐ ๊ณต๋ฐฑ์ ๋ณดํต ๋ฌธ์ ๋์ง ์์ต๋๋ค. ์ฒญ๊ตฌ์์ ๊ฒฝ์ฐ๋ ๊ฐ์ฌ ์ถ์ ์ผ๋ก ์ค๋ช ํ ์ ์๋ค๋ฉด ๊ณต๋ฐฑ์ ํ์ฉํ๋ ํ์ด ๋ง์ต๋๋ค. ๊ณต๋ฐฑ ์๋ ๋ฒํธ๋ฅผ ์ํ๋ฉด ์ถ๊ฐ ๊ท์น์ด ํ์ํ๊ณ ์ข ์ข ๋ง์ฐฐ์ด ์๊น๋๋ค.
๋ค์์ผ๋ก ์นด์ดํฐ์ ๋ฒ์๋ฅผ ๊ฒฐ์ ํ์ธ์. ์์ ๋ฌธ๊ตฌ ์ฐจ์ด๊ฐ ์ค๊ณ๋ฅผ ๋ง์ด ๋ฐ๊ฟ๋๋ค:
- ๋ชจ๋ ๊ฒ์ ๋ํด ํ๋์ ๊ธ๋ก๋ฒ ์ํ์ค์ธ๊ฐ, ์๋๋ฉด ํ์ฌ/ํ ๋ํธ๋ณ๋ก ๋ถ๋ฆฌํ ๊ฒ์ธ๊ฐ?
- ๋งค๋ ๋ฆฌ์ ํ ๊ฒ์ธ๊ฐ(์: 2026-000123), ์๋๋ฉด ์ ๋ ๋ฆฌ์ ํ์ง ์์ ๊ฒ์ธ๊ฐ?
- ์ฒญ๊ตฌ์ vs ์ ์ฉ์ ํ vs ํฐ์ผ ๋ฑ ๋ฌธ์ ์ข ๋ฅ๋ณ๋ก ๋ค๋ฅธ ์๋ฆฌ์ฆ๊ฐ ํ์ํ๊ฐ?
- ์ฌ๋์ด ์ฝ๊ธฐ ์ฌ์ด ํ์(์ ๋์ฌ, ๊ตฌ๋ถ์)์ด ํ์ํ๊ฐ, ์๋๋ฉด ๋ด๋ถ์ฉ ์ซ์๋ง์ผ๋ก ์ถฉ๋ถํ๊ฐ?
๊ตฌ์ฒด์ ์: ๋ค์ ๊ณ ๊ฐ ํ์ฌ๋ฅผ ๊ฐ์ง SaaS ์ ํ์ ํ์ฌ๋ณ๋ก ๊ณ ์ ํ๊ณ ์ฐ๋๋ณ๋ก ๋ฆฌ์ ๋๋ ์ฒญ๊ตฌ์ ๋ฒํธ๋ฅผ ์๊ตฌํ ์ ์์ผ๋ฉฐ, ํฐ์ผ์ ์ ์ญ์์ ๊ณ ์ ํ๊ณ ์ ๋ ๋ฆฌ์ ํ์ง ์์ ์ ์์ต๋๋ค. UI๋ ๋น์ทํด ๋ณด์ฌ๋ ์๋ก ๋ค๋ฅธ ๊ท์น์ ๊ฐ์ง ๋ ์นด์ดํฐ๊ฐ ํ์ํฉ๋๋ค.
์ ๋ง ๊ณต๋ฐฑ ์์์ ์ํ๋ค๋ฉด ๋ฒํธ๊ฐ ํ ๋น๋ ๋ค ์ด๋ค ์ด๋ฒคํธ๋ฅผ ํ์ฉํ ์ง ๋ช ํํ ํ์ธ์. ์๋ฅผ ๋ค์ด ์ฒญ๊ตฌ์๋ฅผ ์ญ์ ํ ์ ์๋๊ฐ, ์๋๋ฉด ์ทจ์๋ง ๊ฐ๋ฅํ๊ฐ? ์ฌ์ฉ์๊ฐ ์ด์์ ์ ์ฅํ ๋ ๋ฒํธ๋ฅผ ๋ถ์ฌํ ์ ์๋๊ฐ, ์๋๋ฉด ์ต์ข ์น์ธ ์์๋ง ๋ฒํธ๋ฅผ ๋ถ์ฌํ๋๊ฐ? ์ด๋ฌํ ์ ํ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ธฐ์ ๋ณด๋ค ๋ ์ค์ํ ๋๊ฐ ๋ง์ต๋๋ค.
๊ตฌํ ์ ์ ๊ฐ๋จํ ๊ท๊ฒฉ์ ํ ์ค๋ก ์ ์ด๋์ธ์:
- ์ด๋ค ๋ ์ฝ๋ ์ ํ์ด ์ํ์ค๋ฅผ ์ฌ์ฉํ๋๊ฐ?
- ๋ฒํธ๊ฐ '์ฌ์ฉ๋จ'์ผ๋ก ๊ฐ์ฃผ๋๋ ์์ ์ ์ธ์ ์ธ๊ฐ(์ด์, ๋ฐํ, ๊ฒฐ์ ๋ฑ)?
- ๋ฒ์๋ ์ด๋ป๊ฒ ๋๋๊ฐ(๊ธ๋ก๋ฒ, ํ์ฌ๋ณ, ์ฐ๋๋ณ, ์๋ฆฌ์ฆ๋ณ)?
- ๋ฌดํจ ์ฒ๋ฆฌ์ ์์ ์ ์ด๋ป๊ฒ ๋ค๋ฃจ๋๊ฐ?
AppMaster์ฒ๋ผ ๋ ธ์ฝ๋ ๋๊ตฌ์์๋ ์ด๋ฐ ๊ท์น์ ๋ฐ์ดํฐ ๋ชจ๋ธ๊ณผ ๋น์ฆ๋์ค ํ๋ก์ธ์ค ์์ ๋์ด ํ ์ ์ฒด๊ฐ(์น UI, API, ๋ชจ๋ฐ์ผ) ๋์ผํ ๋์์ ๊ตฌํํ๋๋ก ํ์ธ์.
ํํ ์ ๊ทผ๋ฒ๊ณผ ๊ฐ ๋ฐฉ์์ ๋ณด์ฅ ์ฌํญ
์ฌ๋๋ค์ด "์ฒญ๊ตฌ์ ๋ฒํธ ์ง์ "์ ๋งํ ๋ ๋ณดํต ๋ ๊ฐ์ง ๋ชฉํ๋ฅผ ๋ค์์ต๋๋ค: (1) ๊ฐ์ ๋ฒํธ๋ฅผ ๋ ๋ฒ ์์ฑํ์ง ์๊ธฐ, (2) ๋ฒํธ๊ฐ ๊ฑด๋๋ฐ์ง ์๊ธฐ. ๋๋ถ๋ถ์ ์์คํ ์ ์ฒซ ๋ฒ์งธ๋ ์ฝ๊ฒ ๋ณด์ฅํ ์ ์๊ณ ๋ ๋ฒ์งธ๋ ํจ์ฌ ์ด๋ ต์ต๋๋ค. ํธ๋์ญ์ ์คํจ, ์ด์ ํฌ๊ธฐ, ๋ ์ฝ๋ ๋ฌดํจ ์ฒ๋ฆฌ ๋ฑ์ด ์ธ์ ๋ ์ง ๊ณต๋ฐฑ์ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ ๊ทผ๋ฒ 1: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํ์ค (๋น ๋ฅธ ๊ณ ์ ์ฑ)
PostgreSQL ์ํ์ค๋ ๋ถํ๊ฐ ๊ฑธ๋ฆด ๋๋ ๊ณ ์ ํ๊ณ ์ฆ๊ฐํ๋ ๊ฐ์ ์ ๊ณตํ๋ ๊ฐ์ฅ ๋จ์ํ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ง์ ๋์ ์์ฑ ์์ฒญ์ ๋ํด ์ํ์ค ๊ฐ์ ๋น ๋ฅด๊ฒ ๋ฐ๊ธํ๋๋ก ์ค๊ณ๋์ด ์์ต๋๋ค.
์ป๋ ๊ฒ: ๊ณ ์ ์ฑ ๋ฐ ๋๋ถ๋ถ ์ฆ๊ฐํ๋ ์์์ฑ. ์ป์ง ๋ชปํ๋ ๊ฒ: ๊ณต๋ฐฑ ์์. ์ฝ์ ์ด ์คํจํ ํ ์ํ์ค ๊ฐ์ ์๋ชจ๋๋ฏ๋ก ๊ณต๋ฐฑ์ด ์๊น๋๋ค.
์ ๊ทผ๋ฒ 2: ๊ณ ์ ์ ์ฝ + ์ฌ์๋ (๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋งก๊ธฐ๊ธฐ)
์ฑ ๋ก์ง์์ ํ๋ณด ๋ฒํธ๋ฅผ ์์ฑํ๊ณ ์ ์ฅํ ๋ค, UNIQUE ์ ์ฝ์ผ๋ก ์ค๋ณต์ ๊ฑฐ๋ถํ๋ฉด ์ถฉ๋ ์ ์ฌ์๋ํ๋ ๋ฐฉ์์ ๋๋ค.
์๋์ ํ์ง๋ง, ๋์ ๋์์ฑ์์๋ ์์์ด ์ปค์ง ์ ์์ต๋๋ค. ์ฌ์๋๊ฐ ๋ง์์ง๊ณ ์คํจ ํธ๋์ญ์ ์ด ๋์ด๋๋ฉฐ ๋๋ฒ๊น ์ด ์ด๋ ค์์ง ์ ์์ต๋๋ค. ๋ํ ์๊ฒฉํ ์์ฝ ๊ท์น๊ณผ ๊ฒฐํฉํ์ง ์์ผ๋ฉด ๊ณต๋ฐฑ์ ๋ณด์ฅํ์ง ๋ชปํฉ๋๋ค.
์ ๊ทผ๋ฒ 3: ์ ๊ธ ์๋ ์นด์ดํฐ ํ(๊ณต๋ฐฑ ๋ชฉํ)
์ ๋ง ๊ณต๋ฐฑ ์๋ ๋ฒํธ๊ฐ ํ์ํ๋ฉด ์ ์ฉ ์นด์ดํฐ ํ ์ด๋ธ(๋ฒ์๋ณ๋ก ํ ํ)์ ์ฌ์ฉํด ๊ทธ ํ์ ํธ๋์ญ์ ๋ด์์ ์ ๊ทธ๊ณ ์ฆ๊ฐ์ํค๋ ํจํด์ ์ฌ์ฉํฉ๋๋ค.
์ด๋ ์ผ๋ฐ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ์์ ๊ณต๋ฐฑ์ ๊ฐ์ฅ ๊ทผ์ ํ ๋ฐฉ๋ฒ์ด์ง๋ง ๋น์ฉ์ด ์์ต๋๋ค: ๋ชจ๋ ์์ฑ์๊ฐ ๋๊ธฐํด์ผ ํ๋ ๋จ์ผ "ํซ์คํ"์ ๋ง๋ค๊ณ , ๊ธด ํธ๋์ญ์ , ํ์์์, ๋ฐ๋๋ฝ์ ์ทจ์ฝํด์ง๋๋ค.
์ ๊ทผ๋ฒ 4: ๋ณ๋์ ์์ฝ ์๋น์ค(ํน์ํ ๊ฒฝ์ฐ์๋ง)
๋ ๋ฆฝ์ ์ธ "๋ฒํธ ๋ฐ๊ธ ์๋น์ค"๋ฅผ ๋๋ฉด ์ฌ๋ฌ ์ฑ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๊ฑธ์น ๊ท์น์ ์ค์ํํ ์ ์์ต๋๋ค. ์ฌ๋ฌ ์์คํ ์์ ๋ฒํธ๋ฅผ ๋ฐ๊ธํด์ผ ํ๊ฑฐ๋ ์ฐ๊ธฐ๋ฅผ ํตํฉํ ์ ์์ ๋๋ง ๋๊ฐ ๊ฐ์น๊ฐ ์์ต๋๋ค.
๋๊ฐ๋ก ์ด์ ๋ฆฌ์คํฌ๊ฐ ๋์ด๋ฉ๋๋ค: ์ถ๊ฐ ์๋น์ค๊ฐ ์ ํํ๊ณ ๊ณ ๊ฐ์ฉ์ฑ, ์ผ๊ด์ฑ์ ์ ์งํด์ผ ํฉ๋๋ค.
์์ฝํด์ ์๊ฐํ๊ธฐ ์ข์ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ํ์ค: ๊ณ ์ , ๋น ๋ฆ, ๊ณต๋ฐฑ ํ์ฉ
- ๊ณ ์ + ์ฌ์๋: ๊ณ ์ , ๋ฎ์ ๋ถํ์์ ๋จ์, ๋์ ๋ถํ์์ ๋ฌธ์ ๋ฐ์ ๊ฐ๋ฅ
- ์ ๊ธ ์นด์ดํฐ ํ: ๊ณต๋ฐฑ ๊ฐ๋ฅ, ๊ณ ๋์์ฑ์์ ๋๋ฆผ
- ๋ณ๋ ์๋น์ค: ์์คํ ๊ฐ ์ ์ฐ์ฑ, ๋ณต์ก๋์ ์คํจ ๋ชจ๋ ์ฆ๊ฐ
AppMaster ๊ฐ์ ๋ ธ์ฝ๋ ๋๊ตฌ์์๋ ์ ํ์ง๋ ๋์ผํฉ๋๋ค: ์ต์ข ๋ณด์ฅ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ด์ผ ํฉ๋๋ค. ์ฑ ๋ก์ง์ ์ฌ์๋์ ๋ช ํํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋์ง๋ง, ์ต์ข ๋ณด์ฆ์ ์ ์ฝ๊ณผ ํธ๋์ญ์ ์์ ๋์์ผ ํฉ๋๋ค.
๋จ๊ณ๋ณ: ์ํ์ค์ ๊ณ ์ ์ ์ฝ์ผ๋ก ์ค๋ณต ๋ฐฉ์งํ๊ธฐ
์ฃผ ๋ชฉํ๊ฐ ์ค๋ณต ๋ฐฉ์ง(๊ณต๋ฐฑ ๋ณด์ฅ์ ์๋)๋ผ๋ฉด ๊ฐ์ฅ ๋จ์ํ๋ฉด์ ์ ๋ขฐํ ์ ์๋ ํจํด์: ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋ด๋ถ ID๋ฅผ ์์ฑํ๊ฒ ํ๊ณ , ์ฌ์ฉ์์๊ฒ ๋ณด์ด๋ ๋ฒํธ๋ ๋ณ๋ ์ด์ ๊ณ ์ ์ ์ฝ์ ๋๋ ๊ฒ์ ๋๋ค.
๋ ๊ฐ๋ ์ ๋ถ๋ฆฌํ์ธ์. ์กฐ์ธ, ์์ , ๋ด๋ณด๋ด๊ธฐ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฑ ๋ด๋ถ ๊ฐ(identity/sequence)์ ๊ธฐ๋ณธ ํค๋ก ์ฌ์ฉํ๊ณ , invoice_no๋ ticket_no๋ ์ฌ๋์๊ฒ ๋ณด์ฌ์ฃผ๋ ๋ณ๋ ์ด๋ก ๋ก๋๋ค.
PostgreSQL์์์ ์ค์ฉ์ ์ค์
๋ค์์ ๋์์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ๋๋ ์ผ๋ฐ์ ์ธ PostgreSQL ์ ๊ทผ์ ๋๋ค. ์ฝ๋ ๋ธ๋ก์ ๋ณ๊ฒฝํ์ง ๋ง์ธ์.
-- Internal, never-shown primary key
create table invoices (
id bigint generated always as identity primary key,
invoice_no text not null,
created_at timestamptz not null default now()
);
-- Business-facing uniqueness guarantee
create unique index invoices_invoice_no_uniq on invoices (invoice_no);
-- Sequence for the visible number
create sequence invoice_no_seq;
์ด์ ํ์ ๋ฒํธ๋ INSERT ์์ ์ ์์ฑํ์ธ์(์ ๋๋ก select max(invoice_no) + 1์ฒ๋ผ ํ์ง ๋ง์ธ์). ํ ๊ฐ์ง ๊ฐ๋จํ ํจํด์ INSERT ์์์ ์ํ์ค ๊ฐ์ ํฌ๋งทํ๋ ๊ฒ์
๋๋ค:
insert into invoices (invoice_no)
values (
'INV-' || lpad(nextval('invoice_no_seq')::text, 8, '0')
)
returning id, invoice_no;
50๋ช ์ ์ฌ์ฉ์๊ฐ ๋์์ "์ฒญ๊ตฌ์ ์์ฑ"์ ํด๋ฆญํด๋ ๊ฐ INSERT๋ ๋ค๋ฅธ ์ํ์ค ๊ฐ์ ๋ฐ๊ณ , ๊ณ ์ ์ธ๋ฑ์ค๊ฐ ์ฐ์ฐํ ์ค๋ณต์ ๋ง์์ค๋๋ค.
์ถฉ๋์ด ๋ฐ์ํ๋ฉด ์ด๋ป๊ฒ ํ ๊น
์ผ๋ฐ ์ํ์ค์์๋ ์ถฉ๋์ด ๋๋ญ ๋๋ค. ์ฐ๋๋ณ ๋ฆฌ์ , ํ ๋ํธ๋ณ, ์ฌ์ฉ์ ํธ์ง ๊ฐ๋ฅํ ๋ฒํธ ๋ฑ ์ถ๊ฐ ๊ท์น์ ๋์ ํ๋ฉด ์ถฉ๋์ด ์๊ธธ ์ ์์ผ๋ฏ๋ก ๊ณ ์ ์ ์ฝ์ ์ฌ์ ํ ์ค์ํฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์์๋ ๊ณ ์ ์ ์ฝ ์๋ฐ ์ ์์ ์ฌ์๋ ๋ฃจํ๋ฅผ ๊ตฌํํ์ธ์. ๋จ์ํ๊ณ ์ ํ์ ์ผ๋ก ์ ์งํฉ๋๋ค:
- ์ฝ์ ์๋
- invoice_no์ ๋ํ ๊ณ ์ ์ ์ฝ ์๋ฐ ์ค๋ฅ๊ฐ ๋๋ฉด ์ฌ์๋
- ์๋ ํ์ ์ ํ ํ ๋ช ํํ ์ค๋ฅ ํ์
์ด ๋ฐฉ๋ฒ์ ์ฌ์๋๊ฐ ๋น์ ์์ ์ํฉ(์: ํฌ๋งท ์ถฉ๋)์์๋ง ๋ฐ์ํ๋ฏ๋ก ์ ๋์ํฉ๋๋ค.
๊ฒฝ์ ์ฐฝ(race window)์ ์ค์ด์ธ์
๋ฒํธ๋ฅผ UI์์ ๊ณ์ฐํ์ง ๋ง๊ณ , ์ฝ๊ณ ๋์ ์ฝ์ ํ๋ ๋ฐฉ์์ผ๋ก ์์ฝํ์ง ๋ง์ธ์. ์ฝ์ ๊ณผ ๊ฐ๋ฅํ ํ ๊ฐ๊น๊ฒ ๋ฒํธ๋ฅผ ์์ฑํ์ธ์.
AppMaster์ PostgreSQL์ ํจ๊ป ์ฌ์ฉํ๋ค๋ฉด, Data Designer์์ id๋ฅผ identity PK๋ก ๋ชจ๋ธ๋งํ๊ณ invoice_no์ ๊ณ ์ ์ ์ฝ์ ์ถ๊ฐํ ๋ค ์์ฑ ํ๋ฆ์์ invoice_no๋ฅผ ์์ฑํ์ฌ ์ฝ์ ๊ณผ ํจ๊ป ์คํ๋๊ฒ ํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด PostgreSQL์ด ์ง์ค์ ๊ทผ์์ด ๋๊ณ ๋์์ฑ ๋ฌธ์ ๋ PostgreSQL์ด ๊ฐ์ฅ ์ ์ฒ๋ฆฌํ๋๋ก ๋๊ฒ ๋ฉ๋๋ค.
๋จ๊ณ๋ณ: ํ ์ ๊ธ์ผ๋ก ๊ณต๋ฐฑ ์๋ ์นด์ดํฐ ๋ง๋ค๊ธฐ
์ ๋ง๋ก ๊ณต๋ฐฑ ์๋ ๋ฒํธ(๋ฒํธ ๋๋ฝ ์์)๊ฐ ํ์ํ๋ฉด ํธ๋์ญ์ ์นด์ดํฐ ํ ์ด๋ธ๊ณผ ํ ์ ๊ธ์ ์ฌ์ฉํ์ธ์. ์์ด๋์ด๋ ๋จ์ํฉ๋๋ค: ์ฃผ์ด์ง ๋ฒ์์์ ๋ค์ ๋ฒํธ๋ฅผ ๊ฐ์ ธ์ค๋ ๋์ ํ ํธ๋์ญ์ ๋ง ํ์ฉํ๋ฉด ๋ฒํธ๋ ์์๋๋ก ๋ฐฐ๋ถ๋ฉ๋๋ค.
๋จผ์ ๋ฒ์๋ฅผ ๊ฒฐ์ ํ์ธ์. ๋ง์ ํ์ด ํ์ฌ๋ณ, ์ฐ๋๋ณ, ๋๋ ์๋ฆฌ์ฆ๋ณ๋ก ๋ถ๋ฆฌ๋ ์ํ์ค๋ฅผ ํ์๋ก ํฉ๋๋ค. ์นด์ดํฐ ํ ์ด๋ธ์ ๊ฐ ๋ฒ์์ ๋ง์ง๋ง ์ฌ์ฉ ๋ฒํธ๋ฅผ ์ ์ฅํฉ๋๋ค.
PostgreSQL ํ ์ ๊ธ์ ์ฌ์ฉํ๋ ์ค์ฉ์ ํจํด์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
number_counters๊ฐ์ ํ ์ด๋ธ์ ๋ง๋ค๊ณcompany_id,year,series,last_number๊ฐ์ ์ด๊ณผ(company_id, year, series)์ ๋ํ ๊ณ ์ ํค๋ฅผ ๋ก๋๋ค.- ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ์ ์์ํฉ๋๋ค.
SELECT last_number FROM number_counters WHERE ... FOR UPDATE๋ก ํด๋น ๋ฒ์์ ์นด์ดํฐ ํ์ ์ ๊ธ๋๋ค.next_number = last_number + 1์ ๊ณ์ฐํ๊ณ ์นด์ดํฐ ํ์last_number = next_number๋ก ์ ๋ฐ์ดํธํฉ๋๋ค.next_number๋ฅผ ์ฌ์ฉํด ์ธ๋ณด์ด์ค๋ ํฐ์ผ ํ์ ์ฝ์ ํ ๋ค ์ปค๋ฐํฉ๋๋ค.
ํต์ฌ์ FOR UPDATE์
๋๋ค. ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๋ฉด ์ค๋ณต์ด ๋ฐ์ํ์ง ์์ต๋๋ค. ๋ํ ๋ ์ฌ์ฉ์๊ฐ ๊ฐ์ ๋ฒํธ๋ฅผ ์ป๋ ์ผ๋ก ์ธํ ๊ณต๋ฐฑ๋ ๋ฐ์ํ์ง ์์ต๋๋ค. ๋ ๋ฒ์งธ ํธ๋์ญ์
์ ์ฒซ ๋ฒ์งธ๊ฐ ์ปค๋ฐํ๊ฑฐ๋ ๋กค๋ฐฑํ ๋๊น์ง ํด๋น ์นด์ดํฐ ํ์ ์ฝ๊ณ ์ฆ๊ฐ์ํค์ง ๋ชปํ๊ณ ์ ์ ๊ธฐ๋ค๋ฆฝ๋๋ค. ๊ทธ ๊ธฐ๋ค๋ฆผ์ด ๊ณต๋ฐฑ ์์์ ๋๊ฐ์
๋๋ค.
์๋ก์ด ๋ฒ์ ์ด๊ธฐํ
์ ํ์ฌ๋ ์ ์ฐ๋, ์ ์๋ฆฌ์ฆ๊ฐ ์๊ธธ ๋ ์ด๊ธฐํ ๊ณํ์ด ํ์ํฉ๋๋ค. ํํ ๋ ์ต์ ์:
- ๋ฏธ๋ฆฌ ์นด์ดํฐ ํ์ ์์ฑํด๋๊ธฐ(์: 12์์ ๋ค์ ์ฐ๋ ํ ์์ฑ)
- ์จ๋๋งจ๋๋ก ์์ฑ:
last_number = 0์ผ๋ก ์นด์ดํฐ ํ ์ฝ์ ์ ์๋ํ๊ณ ์ด๋ฏธ ์กด์ฌํ๋ฉด ์ ์์ ์ธ ์ ๊ธ-์ฆ๊ฐ ํ๋ฆ์ผ๋ก ๋์ฒด
๋ ธ์ฝ๋ ๋๊ตฌ์์ ๋ง๋ค๋ฉด "์ ๊ธ, ์ฆ๊ฐ, ์ฝ์ " ์์๋ฅผ ํ๋์ ํธ๋์ญ์ ์์ ๋์ด ๋ชจ๋ ์คํ๋๊ฑฐ๋ ์ ํ ์คํ๋์ง ์๊ฒ ํ์ธ์.
์์ธ ์ํฉ: ์ด์, ์คํจํ ์ ์ฅ, ์ทจ์, ์์
๋๋ถ๋ถ์ ๋ฒํธ ๋ฌธ์ ๋ ์ง์ ๋ถํ ๋ถ๋ถ์์ ๋ํ๋ฉ๋๋ค: ๊ฒ์๋์ง ์์ ์ด์, ์ ์ฅ ์คํจ, ์ฒญ๊ตฌ์ ๋ฌดํจ ์ฒ๋ฆฌ, ๋๊ตฐ๊ฐ ๋ฒํธ๋ฅผ ๋ณธ ๋ค ํํด์ง ์์ ๋ฑ์ ๋๋ค. ๋์์ฑ ์์ ํ ๋ฒํธ๋ฅผ ์ํ๋ค๋ฉด ๋ฒํธ๊ฐ ์ธ์ "์ค์ "๊ฐ ๋๋์ง์ ๋ํ ๋ช ํํ ๊ท์น์ด ํ์ํฉ๋๋ค.
๊ฐ์ฅ ํฐ ๊ฒฐ์ ์ ํ์ด๋ฐ์ ๋๋ค. ์ฌ์ฉ์๊ฐ "์ ์ฒญ๊ตฌ์"๋ฅผ ํด๋ฆญํ๋ ์๊ฐ ๋ฒํธ๋ฅผ ํ ๋นํ๋ฉด ๋ฒ๋ ค์ง ์ด์ ๋๋ฌธ์ ๊ณต๋ฐฑ์ด ์๊น๋๋ค. ์ฒญ๊ตฌ์๋ฅผ ์ต์ข ํ(post/issue)ํ ๋๋ง ํ ๋นํ๋ฉด ๋ฒํธ๊ฐ ๋ ์ด์ดํด์ง๊ณ ์ค๋ช ํ๊ธฐ ์ฌ์์ง๋๋ค.
์คํจํ ์ ์ฅ๊ณผ ๋กค๋ฐฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋์๊ณผ ๊ธฐ๋์น๊ฐ ์ถฉ๋ํ๋ ๊ณณ์ ๋๋ค. ์ผ๋ฐ ์ํ์ค์์๋ ํ ๋ฒ ๋ฒํธ๊ฐ ์๋น๋๋ฉด ํธ๋์ญ์ ์ด ๋์ค์ ์คํจํ๋๋ผ๋ ๊ทธ ๋ฒํธ๋ ์๋ชจ๋ฉ๋๋ค. ์ด๊ฒ์ ์ ์์ ์ด๊ณ ์์ ํ์ง๋ง ๊ณต๋ฐฑ์ ๋ง๋ญ๋๋ค. ๊ณต๋ฐฑ ์๋ ์ ์ฑ ์ ์ํ๋ฉด ๋ฒํธ๋ ์ต์ข ๋จ๊ณ์์๋ง, ๊ทธ๋ฆฌ๊ณ ํธ๋์ญ์ ์ด ์ปค๋ฐ๋ ๋๋ง ํ ๋นํด์ผ ํฉ๋๋ค. ๋ณดํต ๋จ์ผ ์นด์ดํฐ ํ์ ์ ๊ทธ๊ณ ์ต์ข ๋ฒํธ๋ฅผ ์ฐ๊ณ ์ปค๋ฐํ๋ ๋ฐฉ์์ด ํ์ํฉ๋๋ค. ์ด๋ค ๋จ๊ณ๊ฐ ์คํจํ๋ฉด ์๋ฌด ๊ฒ๋ ํ ๋น๋์ง ์์ต๋๋ค.
์ทจ์์ ๋ฌดํจ ์ฒ๋ฆฌ๋ ๋ฒํธ๋ฅผ ์ฌ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ๊ฑฐ์ ๋ถ๋ณ์ ์์น์ ๋๋ค. ํ์คํ ๋ฆฌ๋ ์ผ๊ด์ฑ์ ์ ์งํด์ผ ํ๋ฏ๋ก ๋ฒํธ๋ ๋จ๊ฒจ๋๊ณ ์ํ์ ์ด์ ๋ฅผ ๊ธฐ๋กํ์ธ์.
์์ ์ ๋ ๊ฐ๋จํฉ๋๋ค: ๋ฒํธ๊ฐ ์ธ๋ถ์ ๋ ธ์ถ๋ ๋ค์๋ ์๊ตฌ์ ์ด๋ผ๊ณ ์ทจ๊ธํ์ธ์. ๊ณต์ ๋๊ฑฐ๋ ๋ด๋ณด๋ด์ง๊ฑฐ๋ ์ธ์๋ ๋ฒํธ๋ฅผ ๋ค์ ๋งค๊ธฐ์ง ๋ง์ธ์. ์์ ์ด ํ์ํ๋ฉด ์ ๋ฌธ์๋ฅผ ๋ง๋ค๊ณ ์ด์ ๊ฒ์ ์ฐธ์กฐ(์: ์ ์ฉ ์ ํ ๋๋ ๊ต์ฒด ๋ฌธ์)ํ์ธ์.
๋ง์ ํ์ด ์ฑํํ๋ ์ค์ฉ์ ๊ท์น:
- ์ด์์๋ ์ต์ข ๋ฒํธ ์์(๋ด๋ถ ID ๋๋ "DRAFT" ์ฌ์ฉ)
- "๊ฒ์/๋ฐํ" ์์๋ง ๋ฒํธ๋ฅผ ํ ๋น, ์ํ ๋ณ๊ฒฝ๊ณผ ๊ฐ์ ํธ๋์ญ์ ์์์ ์ํ
- ๋ฌดํจ ์ฒ๋ฆฌ/์ทจ์๋ ๋ฒํธ๋ฅผ ์ ์งํ๋ ๋ช ํํ ์ํ์ ์ด์ ๋ฅผ ๋ถ์ฌ
- ์ธ์/์ด๋ฉ์ผ๋ก ์ ๋ฌ๋ ๋ฒํธ๋ ๋ณ๊ฒฝํ์ง ์์
- ์ํฌํธ๋ ์๋ณธ ๋ฒํธ ๋ณด์กด ํ ์นด์ดํฐ๋ฅผ ์ต๋๊ฐ ์ดํ๋ก ์ค์
๋ง์ด๊ทธ๋ ์ด์ ๊ณผ ์ํฌํธ๋ ์ฃผ์๊ฐ ํ์ํฉ๋๋ค. ๋ค๋ฅธ ์์คํ ์์ ์ฎ๊ธด๋ค๋ฉด ๊ธฐ์กด ๋ฒํธ๋ฅผ ๊ทธ๋๋ก ๋ค์ฌ์ค๊ณ ์นด์ดํฐ๋ ์ต๋ ๊ฐ์ ธ์จ ๊ฐ ์ดํ๋ถํฐ ์์ํ์ธ์. ์ฌ๋ฌ ํฌ๋งท(์ฐ๋๋ณ ์ ๋์ฌ ๋ฑ)์ด ํผ์ฌํ๋ฉด ํ์ ๋ฒํธ(display number)๋ ์๋ณธ ๊ทธ๋๋ก ๋ณด๊ดํ๊ณ ๋ณ๋์ ๋ด๋ถ PK๋ฅผ ์ ์งํ๋ ํธ์ด ๋ซ์ต๋๋ค.
์: ํฌํ๋ฐ์คํฌ๋ ํฐ์ผ์ ๋น ๋ฅด๊ฒ ์์ฑํ์ง๋ง ์ด์์ด ๋ง์ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์๋ด์ฌ๊ฐ "๊ณ ๊ฐ์๊ฒ ์ ์ก"์ ํด๋ฆญํ ๋๋ง ํฐ์ผ ๋ฒํธ๋ฅผ ํ ๋นํ๋ฉด ๋ฒ๋ ค์ง ์ด์ ๋๋ฌธ์ ๋ฒํธ๋ฅผ ๋ญ๋นํ์ง ์์ต๋๋ค. ๋ ธ์ฝ๋ ๋๊ตฌ์์๋ ๋์ผํ ์์ด๋์ด๋ฅผ ์ ์ฉํ์ธ์: ์ด์์ ๊ณต๊ฐ ๋ฒํธ ์์ด ๋ ์ฝ๋๋ก ์ ์งํ๊ณ , ์ต์ข ์ ์ถ ๋จ๊ณ์์ ํธ๋์ญ์ ์์ ์ต์ข ๋ฒํธ๋ฅผ ์์ฑํ์ธ์.
์ค๋ณต์ด๋ ๋ป๋ฐ์ ๊ณต๋ฐฑ์ ์ผ์ผํค๋ ํํ ์ค์
๋๋ถ๋ถ์ ๋ฒํธ ๋ฌธ์ ๋ ๋ฒํธ๋ฅผ ํ์๊ฐ(display value)์ฒ๋ผ ์ทจ๊ธํ๊ณ ๊ณต์ ์ํ(shared state)๋ก ๋ณด์ง ์๋ ๋ฐ์ ์ต๋๋ค. ์ฌ๋ฌ ์ฌ๋์ด ๋์์ ์ ์ฅํ๋ฉด ๋ค์ ๋ฒํธ๋ฅผ ๊ฒฐ์ ํ ํ ๊ณณ, ์คํจ ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง์ ๋ํ ํ ๊ท์น์ด ํ์ํฉ๋๋ค.
๊ณ ์ ์ ์ค์๋ ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋์์ SELECT MAX(number) + 1์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ๋จ์ผ ์ฌ์ฉ์ ํ
์คํธ์์๋ ๊ด์ฐฎ์ ๋ณด์ด์ง๋ง ๋ ์์ฒญ์ด ์ด๋ ํ๋๋ ์ปค๋ฐํ๊ธฐ ์ ์ ๊ฐ์ MAX๋ฅผ ์ฝ์ ์ ์์ต๋๋ค. ๋ ๋ค ๊ฐ์ ๋ค์ ๊ฐ์ ์์ฑํ๊ณ ์ค๋ณต์ด ์๊น๋๋ค. "ํ์ธ ํ ์ฌ์๋"๋ฅผ ์ถ๊ฐํด๋ ํผํฌ ํธ๋ํฝ์์๋ ๋ถํ์ ์ด์ํ ์คํ์ดํฌ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
๋ ๋ค๋ฅธ ์ค๋ณต ์์ธ์ ํด๋ผ์ด์ธํธ ์ธก(๋ธ๋ผ์ฐ์ ๋ ๋ชจ๋ฐ์ผ)์์ ๋ฒํธ๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋๋ค. ํด๋ผ์ด์ธํธ๋ ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ๋ฌด์์ ํ๊ณ ์๋์ง ์ ์ ์๊ณ , ์ ์ฅ์ ์คํจํ ๊ฒฝ์ฐ ์์ ํ๊ฒ ๋ฒํธ๋ฅผ ์์ฝํ ์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ ์์ฑ ๋ฒํธ๋ "์์ ๋ผ๋ฒจ(์: Draft 12)"์๋ ๊ด์ฐฎ์ง๋ง ๊ณต์ ์ฒญ๊ตฌ์๋ ํฐ์ผ ID์๋ ์ ํฉํ์ง ์์ต๋๋ค.
๊ณต๋ฐฑ์ ์ํ์ค๊ฐ ๊ณต๋ฐฑ ์๋ค๊ณ ๊ฐ์ ํ๋ ํ์ ๋๋ผ๊ฒ ํฉ๋๋ค. PostgreSQL ์ํ์ค๋ ๊ณ ์ ์ฑ์ ์ํด ์ค๊ณ๋์๊ณ ์๋ฒฝํ ์ฐ์์ฑ์ ๋ณด์ฅํ์ง ์์ต๋๋ค. ํธ๋์ญ์ ๋กค๋ฐฑ, ID ์ ํ ๋น(prefetch), ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์์ ๋ฑ์ผ๋ก ๋ฒํธ๊ฐ ๊ฑด๋๋ธ ์ ์์ต๋๋ค. ๋ง์ฝ ์ง์ง ์๊ตฌ์ฌํญ์ด "์ค๋ณต ์์"์ด๋ผ๋ฉด ์ํ์ค์ ๊ณ ์ ์ ์ฝ์ ์กฐํฉ์ด ๋ณดํต ์ฌ๋ฐ๋ฅธ ๋ต์ ๋๋ค. ์ง์ง๋ก "๊ณต๋ฐฑ ์์"์ด ํ์ํ๋ฉด ๋ค๋ฅธ ํจํด(๋ณดํต ํ ์ ๊ธ)์ด ํ์ํ๊ณ ์ฒ๋ฆฌ๋์ ๋ํ ํธ๋ ์ด๋์คํ๋ฅผ ๋ฐ์๋ค์ฌ์ผ ํฉ๋๋ค.
์ ๊ธ๋ ๋๋ฌด ๊ด๋ฒ์ํ๊ฒ ํ๋ฉด ์ญํจ๊ณผ๊ฐ ๋ ์ ์์ต๋๋ค. ๋ชจ๋ ๊ฒ์ ๋ํด ๋จ์ผ ๊ธ๋ก๋ฒ ๋ฝ์ ๊ฑธ๋ฉด ๋ชจ๋ ์์ฑ ์์ ์ด ์ง๋ ฌํ๋์ด ํ์ฌ, ์์น, ๋ฌธ์ ์ ํ๋ณ๋ก ๋ถ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ๋ ๋๊ธฐํ๊ฒ ๋ฉ๋๋ค. ์ด๋ก ์ธํด ์ ์ฅ์ด "์์๋ก" ์ง์ฒด๋๋ค๊ณ ๋๋ ์ ์์ต๋๋ค.
๊ตฌํ ์ ์ ๊ฒํ ์ค์ ๋ชฉ๋ก:
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ค ๊ณ ์ ์ ์ฝ ์์ด
MAX + 1์ฌ์ฉ - ์ต์ข ๋ฒํธ๋ฅผ ํด๋ผ์ด์ธํธ์์ ์์ฑํ๊ณ ๋์ค์ ์ถฉ๋์ "์์ "ํ๋ ค ํจ
- PostgreSQL ์ํ์ค๋ฅผ ๊ณต๋ฐฑ ์์์ผ๋ก ๊ธฐ๋ํ๊ณ ๊ณต๋ฐฑ์ ์ค๋ฅ๋ก ์ทจ๊ธ
- ๋ชจ๋ ๊ฒ์ ๋ํด ํ๋์ ๊ณต์ ์นด์ดํฐ๋ฅผ ์ ๊ธ ๋์ ํ์์ ๋ฐ๋ผ ๋ถํ ํ์ง ์์
- ํ ์ฌ์ฉ์ ํ๊ฒฝ์์๋ง ํ ์คํธํ์ฌ ๊ฒฝ์ ์ํ๊ฐ ์ถ์ ํ์์ผ ๋๋ฌ๋จ
์ค์ฉ์ ํ ์คํธ ํ: 100~1,000๊ฐ์ ๋ ์ฝ๋๋ฅผ ๋ณ๋ ฌ๋ก ์์ฑํ๋ ๊ฐ๋จํ ๋์์ฑ ํ ์คํธ๋ฅผ ์คํํด ์ค๋ณต๊ณผ ์๊ธฐ์น ์์ ๊ณต๋ฐฑ์ ํ์ธํ์ธ์. ๋ ธ์ฝ๋ ๋๊ตฌ์์๋ ๊ฐ์ ๊ท์น์ด ์ ์ฉ๋ฉ๋๋ค: ์ต์ข ๋ฒํธ๋ UI๊ฐ ์๋ ์๋ฒ ์ธก ๋จ์ผ ํธ๋์ญ์ ์์ ํ ๋นํ์ธ์.
์ถ์ ์ ๋น ๋ฅธ ์ ๊ฒ ๋ชฉ๋ก
์ถ์ ์ ์ ์์ฃผ ์คํจํ๋ ๋ถ๋ถ์ ๋น ๋ฅด๊ฒ ์ ๊ฒํ์ธ์. ๋ชฉํ๋ ๊ฐ๋จํฉ๋๋ค: ๊ฐ ๋ ์ฝ๋๊ฐ ์ ํํ ํ๋์ ๋น์ฆ๋์ค ๋ฒํธ๋ฅผ ๋ฐ๊ณ , 50๋ช ์ด ๋์์ "์์ฑ"์ ๋๋ฌ๋ ๊ท์น์ด ์ ์ง๋๋์ง ํ์ธํ๋ ๊ฒ์ ๋๋ค.
์ฌ์ ์ ๊ฒ ์ฒดํฌ๋ฆฌ์คํธ:
- ๋น์ฆ๋์ค ๋ฒํธ ํ๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ค์ ๊ณ ์ ์ ์ฝ์ด ์๋์ง ํ์ธํ์ธ์(๋จ์ UI ๊ฒ์ฌ๋ง์ผ๋ก๋ ๋ถ์กฑ). ์ถฉ๋ ์ ์ด๊ฒ์ด ๋ง์ง๋ง ๋ฐฉ์ด์ ์ ๋๋ค.
- ๋ฒํธ ํ ๋น์ด ๋ ์ฝ๋๋ฅผ ์ ์ฅํ๋ ๋์ผํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ์์์ ์ด๋ฃจ์ด์ง๋์ง ํ์ธํ์ธ์. ๋ฒํธ ํ ๋น๊ณผ ์ ์ฅ์ด ์์ฒญ ๊ฐ์ ๋ถ๋ฆฌ๋๋ฉด ๊ฒฐ๊ตญ ์ค๋ณต์ด ๋ฐ์ํฉ๋๋ค.
- ๊ณต๋ฐฑ ์๋ ๋ฒํธ๋ฅผ ์๊ตฌํ๋ฉด ๋ ์ฝ๋๋ฅผ ์ต์ข ํํ ๋๋ง ๋ฒํธ๋ฅผ ํ ๋นํ์ธ์(์: ์ด์ ์์ฑ ์๊ฐ ์๋). ์ด์, ๋ฒ๋ ค์ง ํผ, ์คํจํ ๊ฒฐ์ ๊ฐ ๊ณต๋ฐฑ์ ๊ฐ์ฅ ํํ ์์ธ์ ๋๋ค.
- ํฌ๊ทํ ์ถฉ๋์ ๋๋นํ ์ฌ์๋ ์ ๋ต์ ์ถ๊ฐํ์ธ์. ํ ์ ๊ธ์ด๋ ์ํ์ค์์๋ ์ง๋ ฌํ ์ค๋ฅ, ๋ฐ๋๋ฝ, ๊ณ ์ ์๋ฐ์ด ๋ ์ ์์ต๋๋ค. ์งง์ ๋ฐฑ์คํ๋ฅผ ๋ ๊ฐ๋จํ ์ฌ์๋๊ฐ ์ถฉ๋ถํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
- UI, ๊ณต๊ฐ API, ๋๋ ์ํฌํธ ๋ฑ ๋ชจ๋ ์ง์ ์ ์์ 20~100๊ฐ์ ๋์ ์์ฑ์ ์คํธ๋ ์ค ํ ์คํธํ์ธ์. ํญ๋ฐ์ ์์ฒญ, ๋๋ฆฐ ๋คํธ์ํฌ, ์ด์ค ์ ์ถ ๊ฐ์ ํ์ค์ ํผํฉ์ ์ํํ์ธ์.
๊ฒ์ฆ ๋ฐฉ๋ฒ: ๋ฐ์ ํฌํ๋ฐ์คํฌ ์ํฉ์ ์๋ฎฌ๋ ์ด์ ํ์ธ์. ๋ ์๋ด์ฌ๊ฐ "์ ํฐ์ผ" ํผ์ ์ด๊ณ ํ ๋ช ์ด ์น์์ ์ ์ถํ๋ ๋์ ์ํฌํธ ์์ ์ด ์ด๋ฉ์ผ ์ธ๋ฐ์ค์์ ํฐ์ผ์ ์ฝ์ ํฉ๋๋ค. ์คํ ํ ๋ชจ๋ ๋ฒํธ๊ฐ ๊ณ ์ ํ๊ณ ํ์์ด ์ฌ๋ฐ๋ฅด๋ฉฐ ์คํจ๊ฐ ๋ฐ๋ง ์ ์ฅ๋ ๋ ์ฝ๋๋ฅผ ๋จ๊ธฐ์ง ์๋์ง ํ์ธํ์ธ์.
AppMaster๋ก ์ํฌํ๋ก๋ฅผ ๊ตฌ์ถํ๋ค๋ฉด ๊ฐ์ ์์น์ ๋ฐ๋ฅด์ธ์: ๋ฒํธ ํ ๋น์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ๋ด์ ๋๊ณ PostgreSQL ์ ์ฝ์ ์ ๋ขฐํ๋ฉฐ UI์ API ์์ชฝ์ ํ ์คํธํ์ธ์. ๋ง์ ํ์ด ์๋ ํ ์คํธ์์๋ ์์ ํ๋ค๊ณ ๋๋ผ์ง๋ง ์ค์ ์ฌ์ฉ์๊ฐ ๋ชฐ๋ฆฌ๋ ์ฒซ๋ ์ ๋๋ผ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
์: ๋ถ์ฃผํ ํฌํ๋ฐ์คํฌ ํฐ์ผ๊ณผ ๋ค์ ๋จ๊ณ
์น ์ฑ์์ ์๋ด์ฌ๊ฐ ํฐ์ผ์ ์์ฑํ๊ณ , ํตํฉ์ ์ฑํ ๋๊ตฌ๋ ์ด๋ฉ์ผ์์ ํฐ์ผ์ ์์ฑํ๋ ํ๊ฒฝ์ ์์ํ์ธ์. ๋ชจ๋ T-2026-000123 ๊ฐ์ ํฐ์ผ ๋ฒํธ๋ฅผ ๊ธฐ๋ํ๊ณ , ๊ฐ ๋ฒํธ๊ฐ ์ ํํ ํ๋์ ํฐ์ผ์ ๊ฐ๋ฆฌํค๊ธธ ๋ฐ๋๋๋ค.
์์งํ ์ ๊ทผ์ "๋ง์ง๋ง ํฐ์ผ ๋ฒํธ๋ฅผ ์ฝ๊ณ +1์ ํด์ ์ ํฐ์ผ ์ ์ฅ"์ ๋๋ค. ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๋ฉด ๋ ์์ฒญ์ด ์ด๋ ํ๋๋ ์ ์ฅํ๊ธฐ ์ ์ ๊ฐ์ "๋ง์ง๋ง ๋ฒํธ"๋ฅผ ์ฝ์ ์ ์์ต๋๋ค. ๋ ๋ค ๊ฐ์ ๋ค์ ๋ฒํธ๋ฅผ ๊ณ์ฐํ๊ณ ์ค๋ณต์ด ๋ฐ์ํฉ๋๋ค. ์คํจ ํ ์ฌ์๋๋ก ์ด๋ฅผ ๊ณ ์น๋ ค ํด๋ ์๋ฏธ ์๋ ๊ณต๋ฐฑ์ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ฑ ์ฝ๋๊ฐ ๋ฏธ์ํด๋ ์ค๋ณต์ ๋ง์์ค ์ ์์ต๋๋ค. ticket_number ์ด์ ๊ณ ์ ์ ์ฝ์ ์ถ๊ฐํ์ธ์. ๊ทธ๋ฐ ๋ค์ ๋ ์์ฒญ์ด ๊ฐ์ ๋ฒํธ๋ฅผ ์๋ํ๋ฉด ํ๋์ ์ฝ์ ์ด ์คํจํ๊ณ ์ฌ์๋ ๋ก์ง์ผ๋ก ๊น๋ํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ๋์์ฑ ์์ ํ ๋ฒํธ ์ง์ ์ ํต์ฌ์ ๋๋ค: ๊ณ ์ ์ฑ์ UI๊ฐ ์๋๋ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋งก๊ธฐ์ธ์.
๊ณต๋ฐฑ ์๋ ๋ฒํธ๋ ์ํฌํ๋ก๋ฅผ ๋ฐ๊ฟ๋๋ค. ๊ณต๋ฐฑ ์๋ ๋ฒํธ๊ฐ ํ์ํ๋ฉด ํฐ์ผ์ด ์ฒ์ ์์ฑ๋ ๋(์ด์) ์ต์ข ๋ฒํธ๋ฅผ ๋ถ์ฌํ ์ ์์ต๋๋ค. ๋์ ์ํ๋ฅผ Draft๋ก ๋๊ณ ticket_number๋ NULL๋ก ๋ก๋๋ค. ๋ฒํธ๋ ํฐ์ผ์ ์ต์ข ํํ ๋๋ง ํ ๋นํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด ์คํจ๋ ๋ฒ๋ฆผ์ผ๋ก ๋ฒํธ๊ฐ ๋ญ๋น๋์ง ์์ต๋๋ค.
๊ฐ๋จํ ํ ์ด๋ธ ์ค๊ณ ์:
- tickets: id, created_at, status (Draft, Open, Closed), ticket_number (nullable), finalized_at
- ticket_counters: key (์: "tickets_2026"), next_number
AppMaster์์๋ ์ด๋ฅผ Data Designer์ PostgreSQL ํ์ ์ผ๋ก ๋ชจ๋ธ๋งํ ๋ค Business Process Editor์์ ๋ก์ง์ ๊ตฌ์ถํ ์ ์์ต๋๋ค:
- Create Ticket: status=Draft๋ก ํฐ์ผ ์ฝ์ (ticket_number ์์)
- Finalize Ticket: ํธ๋์ญ์ ์์, ์นด์ดํฐ ํ ์ ๊ธ, ticket_number ์ค์ , next_number ์ฆ๊ฐ, ์ปค๋ฐ
- ํ ์คํธ: ๋์์ ๋ ๊ฐ์ "Finalize"๋ฅผ ์คํํด ์ค๋ณต์ด ๋ฐ์ํ์ง ์๋์ง ํ์ธ
๋ค์ ๋จ๊ณ: ๊ท์น(๊ณ ์ ๋ง ํ์ฉ vs ์ง์ง ๊ณต๋ฐฑ ์์)์ ์ ํ์ธ์. ๊ณต๋ฐฑ์ ํ์ฉํ ์ ์๋ค๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํ์ค์ ๊ณ ์ ์ ์ฝ์ ์กฐํฉ์ด ๋ณดํต ์ถฉ๋ถํ๊ณ ํ๋ฆ์ด ๋จ์ํฉ๋๋ค. ๊ณต๋ฐฑ์ด ๋ฐ๋์ ์์ด์ผ ํ๋ค๋ฉด ๋ฒํธ ํ ๋น์ ์ต์ข ํ ๋จ๊ณ๋ก ์ฎ๊ธฐ๊ณ "์ด์"์ 1์ฐจ ์ํ๋ก ์ทจ๊ธํ์ธ์. ๊ทธ๋ฐ ๋ค์ ์ฌ๋ฌ ์๋ด์ฌ๊ฐ ๋์์ ํด๋ฆญํ๊ฑฐ๋ API ํตํฉ์ด ๋ฒ์คํธ๋ฅผ ์ผ์ผํฌ ๋ ๋ก๋ ํ ์คํธ๋ฅผ ์คํํด ์ค์ ์ฌ์ฉ์ ์ ์ ๋์์ ํ์ธํ์ธ์.


