****πŸ‘¨β€πŸ’» 아킀텍쳐

μŠ€ν¬λ¦°μƒ· 2024-07-16 194718.png

πŸ›  μ‚¬μš© 기술

<aside> <img src="/icons/hammer_gray.svg" alt="/icons/hammer_gray.svg" width="40px" /> Java β€’ Spring β€’ Oracle β€’ Git β€’ MyBatis β€’ Apache Tomcat Server β€’ JSP β€’ HTML β€’ CSS β€’ Javascript β€’ Bootstrap β€’ JQuery β€’

</aside>

πŸ’£ νŠΈλŸ¬λΈ” μŠˆνŒ…

<aside> <img src="/icons/report_orange.svg" alt="/icons/report_orange.svg" width="40px" /> μ—¬λŸ¬ 개의 λ ˆμ‹œν”Ό κ³Όμ • 정보 등둝 λΆˆκ°€ ν•΄κ²°

</aside>

μ΄ˆκΈ°μ— Recipe(λ ˆμ‹œν”Ό κΈ°λ³Έ 정보 ν…Œμ΄λΈ”), Step(λ ˆμ‹œν”Ό κ³Όμ • ν…Œμ΄λΈ”), Ingredient(λ ˆμ‹œν”Ό 재료 ν…Œμ΄λΈ”) ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό ν•œ λ²ˆμ— μž…λ ₯λ°›κΈ° μœ„ν•΄ Array 방식을 μ‚¬μš©ν–ˆμœΌλ‚˜, λ ˆμ‹œν”Ό κ³Όμ •μ˜ νŠΉμ„±μƒ μ—¬λŸ¬ 개의 νŠœν”Œμ„ λ™μ‹œμ— μ²˜λ¦¬ν•  λ•Œ Array 크기 였λ₯˜λ‘œ μΈν•œ overflow λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ ModelAttribute 값을 Array λŒ€μ‹  ArrayList둜 μ €μž₯ν•˜λŠ” λ°©μ‹μœΌλ‘œ λ³€κ²½ν•˜μ—¬, μ—¬λŸ¬ 개의 λ ˆμ‹œν”Ό κ³Όμ •κ³Ό 사진 데이터가 μ •μƒμ μœΌλ‘œ 등둝될 수 μžˆλ„λ‘ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

λ˜ν•œ, λ ˆμ‹œν”Ό κ³Όμ • 정보가 μ—¬λŸ¬ 개일 경우 사진도 μ—¬λŸ¬ μž₯ 등둝해야 ν•˜λŠ” μƒν™©μ—μ„œ, κΈ°μ‘΄ VARCHAR νƒ€μž…μ΄ 4000ByteκΉŒμ§€λ§Œ μ €μž₯ κ°€λŠ₯ν•˜μ—¬ λŒ€μš©λŸ‰ 사진 데이터λ₯Ό μ €μž₯ν•˜λŠ” 데 ν•œκ³„κ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ Ingredient ν…Œμ΄λΈ”μ˜ 사진 데이터 νƒ€μž…μ„ VARCHARμ—μ„œ BLOB으둜 λ³€κ²½(4000Byte β†’ 4GB)ν•˜μ—¬, μ‚¬μš©μžκ°€ 사진 μš©λŸ‰μ„ 쀄이지 μ•Šκ³ λ„ λŒ€μš©λŸ‰ 이미지 νŒŒμΌμ„ μ—…λ‘œλ“œν•  수 μžˆλ„λ‘ κ°œμ„ ν–ˆμŠ΅λ‹ˆλ‹€.

μ„±κ³Ό: 데이터 μ €μž₯ ꡬ쑰λ₯Ό κ°œμ„ ν•˜μ—¬ λ‹€μˆ˜μ˜ λ ˆμ‹œν”Ό κ³Όμ • 정보와 사진 데이터λ₯Ό μ†μ‰½κ²Œ 등둝할 수 있게 λ˜μ—ˆκ³ , λŒ€μš©λŸ‰ 이미지 νŒŒμΌλ„ λ¬Έμ œμ—†μ΄ μ²˜λ¦¬ν•  수 μžˆμ–΄ μ‚¬μš©μž νŽΈμ˜μ„±μ΄ 크게 ν–₯μƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

<aside> <img src="/icons/report_orange.svg" alt="/icons/report_orange.svg" width="40px" /> 같은 상세 νŽ˜μ΄μ§€μ— λ™μ‹œμ— μ ‘κ·Όν–ˆμ„λ•Œ μ‘°νšŒμˆ˜κ°€ μ¦κ°€λ˜μ§€ μ•ŠλŠ” 문제 ν•΄κ²°

</aside>

λ ˆμ‹œν”Ό 상세 νŽ˜μ΄μ§€μ—μ„œ 2개 μ΄μƒμ˜ 계정이 λ™μ‹œμ— 같은 νŽ˜μ΄μ§€μ— μ ‘κ·Όν–ˆμ„ λ•Œ, μ‘°νšŒμˆ˜κ°€ μ¦κ°€ν•˜μ§€ μ•ŠλŠ” λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. 이 λ¬Έμ œλŠ” μ—¬λŸ¬ μ‚¬μš©μž μš”μ²­μ΄ λ™μ‹œμ— λ°œμƒν•˜λ©΄μ„œ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ 쑰회수(visitcnt)κ°€ μ œλŒ€λ‘œ μ¦κ°€λ˜μ§€ μ•ŠλŠ” 것이 μ›μΈμ΄μ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ @Transactional을 μ‚¬μš©ν•˜μ—¬ recipe_tbl에 λŒ€ν•œ λ™μ‹œ 접근을 순차적으둜 μ²˜λ¦¬ν•˜λ„λ‘ ν•˜μ˜€κ³ , κ·Έ 결과둜 μ‘°νšŒμˆ˜κ°€ μ •ν™•ν•˜κ²Œ 1μ”© μ¦κ°€ν•˜λ„λ‘ 문제λ₯Ό ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

μ„±κ³Ό: λ™μ‹œμ„± 문제λ₯Ό ν•΄κ²°ν•˜μ—¬ μ—¬λŸ¬ μ‚¬μš©μžκ°€ λ™μ‹œμ— λ ˆμ‹œν”Ό 상세 νŽ˜μ΄μ§€μ— 접근해도 μ‘°νšŒμˆ˜κ°€ μ •ν™•νžˆ μ¦κ°€ν•˜λ„λ‘ ν•˜μ˜€μœΌλ©°, 이λ₯Ό 톡해 데이터 무결성을 μœ μ§€ν•˜κ³  μ‚¬μš©μž 행동을 μ •ν™•ν•˜κ²Œ λ°˜μ˜ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

πŸŽ† κ²°κ³Ό / μ„±κ³Ό

<aside> <img src="/icons/cursor-click_gray.svg" alt="/icons/cursor-click_gray.svg" width="40px" /> ν…Œμ΄λΈ” 컬럼 μžλ£Œν˜•μ— λ”°λ₯Έ λ ˆμ‹œν”Ό 등둝 κΈ°λŠ₯

</aside>

κΈ°μ‘΄ CSV 파일의 데이터 νƒ€μž… μ œμ•½μ„ λ°”νƒ•μœΌλ‘œ, λ ˆμ‹œν”Ό 등둝 μ‹œ 잘λͺ»λœ 데이터가 μž…λ ₯λ˜μ§€ μ•Šλ„λ‘ μ˜ˆμ™Έ μΌ€μ΄μŠ€λ₯Ό μ²˜λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λͺ‡ 인뢄과 같은 λ ˆμ‹œν”Ό μ •λ³΄λŠ” λ°˜λ“œμ‹œ INT νƒ€μž…μœΌλ‘œλ§Œ μž…λ ₯λ˜λ„λ‘ ν–ˆμœΌλ©°, 이λ₯Ό UIμ—μ„œ λ²„νŠΌ λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•˜μ—¬ μ‚¬μš©μžκ°€ 잘λͺ»λœ 데이터λ₯Ό μž…λ ₯ν•  κ°€λŠ₯성을 μ›μ²œ μ°¨λ‹¨ν–ˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, 재료의 μ–‘κ³Ό 같은 μ •λ³΄λŠ” 숫자둜만 μž…λ ₯λ˜λ„λ‘ μ„€μ •ν•˜μ˜€μœΌλ©°, 이λ₯Ό NumberFormatException을 ν†΅ν•œ Try-Catch 처리둜 κ΄€λ¦¬ν•˜μ—¬, 잘λͺ»λœ 데이터가 μž…λ ₯될 경우 μ‚¬μš©μžμ—κ²Œ μž¬μž…λ ₯을 μš”μ²­ν•˜λŠ” λ°©μ‹μœΌλ‘œ 였λ₯˜λ₯Ό λ°©μ§€ν–ˆμŠ΅λ‹ˆλ‹€.

μ„±κ³Ό: 이λ₯Ό 톡해 μ‚¬μš©μžκ°€ λ ˆμ‹œν”Όλ₯Ό 등둝할 λ•Œ λ°œμƒν•  수 μžˆλŠ” 데이터 νƒ€μž… 였λ₯˜λ₯Ό 사전에 μ°¨λ‹¨ν•˜μ—¬, λ°μ΄ν„°λ² μ΄μŠ€μ— μž…λ ₯λ˜λŠ” μ •λ³΄μ˜ μ •ν™•μ„±κ³Ό 신뒰성을 보μž₯ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. ꢁ극적으둜 데이터 정합성을 높이고 μ‚¬μš©μž κ²½ν—˜μ„ κ°œμ„ ν•˜λŠ” κ²°κ³Όλ₯Ό μ–»μ—ˆμŠ΅λ‹ˆλ‹€.

<aside> <img src="/icons/cursor-click_gray.svg" alt="/icons/cursor-click_gray.svg" width="40px" /> 쑰회 μˆ˜μ™€ λŒ“κΈ€ 수λ₯Ό 기반으둜 ν•œ λ ˆμ‹œν”Ό TOP 10 κΈ°λŠ₯

</aside>

쑰회 μˆ˜μ™€ λŒ“κΈ€ 수λ₯Ό κΈ°μ€€μœΌλ‘œ μƒμœ„ 10개의 λ ˆμ‹œν”Όλ₯Ό 메인 νŽ˜μ΄μ§€ 상단 λ°°λ„ˆμ— λ…ΈμΆœν•˜λŠ” κΈ°λŠ₯을 κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€. μ²˜μŒμ—λŠ” XML νŒŒμΌμ—μ„œ 쿼리λ₯Ό ORDER BY DESC둜 μ •λ ¬ν•œ ν›„ JSPμ—μ„œ <c:if>둜 μƒμœ„ 10개만 ν•„ν„°λ§ν–ˆμ§€λ§Œ, λͺ¨λ“  데이터λ₯Ό κ°€μ Έμ˜€λŠ” 방식이 λΉ„νš¨μœ¨μ μ΄λΌ νŒλ‹¨ν–ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό κ°œμ„ ν•˜κΈ° μœ„ν•΄ λ°μ΄ν„°λ² μ΄μŠ€ μΏΌλ¦¬μ—μ„œ ROWNUM <= 10 쑰건과 ORDER BY DESCλ₯Ό μ‚¬μš©ν•΄ 쑰회 μˆ˜μ™€ λŒ“κΈ€ μˆ˜κ°€ λ§Žμ€ λ ˆμ‹œν”Όλ₯Ό μš°μ„  μΆ”μΆœν•˜λ„λ‘ λ³€κ²½ν–ˆμŠ΅λ‹ˆλ‹€.

μ„±κ³Ό: 이둜 인해 μ‚¬μš©μžλ“€μ€ κ°€μž₯ 인기 μžˆλŠ” λ ˆμ‹œν”Όλ₯Ό μ‹ μ†ν•˜κ²Œ 확인할 수 있게 λ˜μ—ˆμœΌλ©°, 쑰회 속도λ₯Ό 354msμ—μ„œ 11ms둜 μ•½ 31λ°° κ°œμ„ ν–ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 μ‚¬μ΄νŠΈ μ„±λŠ₯이 ν–₯μƒλ˜μ—ˆκ³ , μ‚¬μš©μž λ§Œμ‘±λ„μ™€ μ‚¬μ΄νŠΈ λ‚΄ ν™œλ™μ„±μ΄ 크게 μ¦κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

<aside> <img src="/icons/cursor-click_gray.svg" alt="/icons/cursor-click_gray.svg" width="40px" /> λ‹€μ–‘ν•œ ν‚€μ›Œλ“œλ‘œ λ ˆμ‹œν”Όλ₯Ό 검색 ν•  수 있게 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

</aside>