ERD - 100-hours-a-week/20-real-wiki GitHub Wiki

ERD

ERD Cloud ๋งํฌ

ํ…Œ์ด๋ธ” ์ •์˜ ๊ณตํ†ต ์„ค๋ช…

  • BIGINT๋Š” 8๋ฐ”์ดํŠธ INT๋Š” 4๋ฐ”์ดํŠธ๋กœ ์ •ํ™•ํžˆ ๋‘ ๋ฐฐ ์ฐจ์ด๋‚˜๋Š”๊ฑธ๋กœ ์•Œ๊ณ ์žˆ์Šต๋‹ˆ๋‹ค. BIGINT๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ…Œ์ด๋ธ”์ด ๋งŽ์•„์ง€๊ณ , ์„œ๋น„์Šค ์ด์šฉ์ž๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก INT์— ๋น„ํ•ด ๋””์Šคํฌ์™€ RAM์— ์ฐจ์ง€ํ•˜๋Š” ๋น„์ค‘์ด ์ปค์ง‘๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์„œ๋น„์Šค์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง„๋‹ค๋ฉด ๊ทธ ๋•Œ BIGINT๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ˜„์žฌ๋กœ์„œ๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋ผ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
  • ์นดํ…Œ๋ถ€ ๋‚ด๋ถ€ ์„œ๋น„์Šค๋‹ค๋ณด๋‹ˆ UTC๋ฅผ ์ž๋™๋ณ€ํ™˜ํ•ด์ฃผ๋Š” TIMESTAMP๋ณด๋‹ค DATETIME์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ 2038๋…„ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” TIMESTAMP๋ณด๋‹ค๋Š” ์•ˆ์ •์„ฑ ์žˆ๊ฒŒ DATETIME์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
  • soft delete๋ฅผ ์œ„ํ•ด deleted_at์ด ํ•„์š”ํ•œ ๋Œ€๋ถ€๋ถ„์˜ ํ…Œ์ด๋ธ”์—์„œ "์‚ญ์ œ๋˜์ง€ ์•Š์€ ํ…Œ์ด๋ธ” ์ค‘ ์ตœ์‹ ์ˆœ"์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. INDEX(deleted_at, created_at DESC)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ๋ฑ์‹ฑ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ํ…Œ์ด๋ธ”์—์„œ deleted_at์ด null์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ๋…์œผ๋กœ ์ธ๋ฑ์‹ฑ ํ•˜๋Š” ๊ฒƒ์€ ์œ ์˜๋ฏธํ•œ ์„ฑ๋Šฅ ๊ฐœ์„ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— created_at๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ด๋ธ” ์ •์˜์„œ

ํ…Œ์ด๋ธ”๋ช… ์ปฌ๋Ÿผ ๋ชฉ๋ก(PK/FK, ๋ฐ์ดํ„ฐ ํƒ€์ž…, ์ œ์•ฝ์กฐ๊ฑด) ๊ธฐ๋Šฅ์  ์—ญํ•  ๋ฐ ์ธ๋ฑ์Šค ์„ค๋ช…
์‚ฌ์šฉ์ž id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)email (VARCHAR 255, UNIQUE, NOT NULL)password (VARCHAR 100, NULL)login_type (VARCHAR(10), NOT NULL)role (VARCHAR 10, NOT NULL)nickname (VARCHAR 50, NOT NULL)profile_url (VARCHAR 512, NOT NULL) state(VARCHAR(10), NOTNULL) last_login_at(DATETIME, NOTNULL)signup_at (DATETIME, NOT NULL)withdraw_at (DATETIME, NULL) ์‚ฌ์šฉ์ž ์ •๋ณด ๊ด€๋ฆฌ Indexes- INDEX (state, role, nickname)  : ํœด๋ฉด/์ •์ง€/์ •์ƒ ํ•„ํ„ฐ๋ง ์ค‘ ๋‹‰๋„ค์ž„ ์ •๋ ฌ - ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค.- ์นดํ…Œ๋ถ€ ๊ด€๋ จ์ž๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•œ ์šฉ๋„๋กœ ์ด๋ฉ”์ผ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฉ”์ผ์ด ์ค‘๋ณต๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.- RFC ํ‘œ์ค€์ƒ ์ด๋ฉ”์ผ ์ „์ฒด ๊ธธ์ด๋Š” ์ตœ๋Œ€ 320์ž๊นŒ์ง€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋ก  255์ž๋ฅผ ๋„˜๊ธฐ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ธธ์ด ์ œํ•œ์„ 255๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.- ํ˜„์žฌ ๊ธฐ๋Šฅ์ •์˜์ƒ์—๋Š” ์ž์ฒด ๋กœ๊ทธ์ธ์ด ์—†์ง€๋งŒ ์ถ”ํ›„ ํ™•์žฅ ๊ฐ€๋Šฅ์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ์ž์ฒด ๋กœ๊ทธ์ธ์„ ์œ„ํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๊ตฌ๊ธ€์—์„  ์ตœ๋Œ€ 100์ž, ์œˆ๋„์šฐ์—์„œ๋Š” ์ตœ๋Œ€ 127์ž, ๊ทธ ์™ธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ 64์ž๋ฅผ ์ œํ•œํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์—ฌ 100์ž๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.- ์—ญํ• ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์นดํ…Œ๋ถ€ ์šด์˜์ง„์ธ์ง€, ๊ต์œก์ƒ์ธ์ง€, ์™ธ๋ถ€์ธ์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.- ๋‹‰๋„ค์ž„์€ โ€˜์˜๋ฌธ์ด๋ฆ„(ํ•œ๊ธ€์ด๋ฆ„)/๊ณผ์ •โ€™์˜ ํฌ๋งท์œผ๋กœ ์ €์žฅ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธธ์ด ์ œํ•œ์„ 50์œผ๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. - ์‚ฌ์šฉ์ž์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด state ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ‰์†Œ์—๋Š” ์ •์ƒ์ด๊ณ , ํƒˆํ‡ด๋ฅผ ํ–ˆ๋‹ค๋ฉด ํƒˆํ‡ด ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ์™ธ์—๋„ ํœด๋ฉด์ƒํƒœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. - ํ•œ ์‚ฌ์šฉ์ž๋Š” ๋‰ด์Šคยท๊ณต์ง€์— ์—ฌ๋Ÿฌ ๋Œ“๊ธ€์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด์„œ news_comment, notice_comment ํ…Œ์ด๋ธ”๊ณผ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.- ํ•œ ์‚ฌ์šฉ์ž๋Š” ์—ฌ๋Ÿฌ ๋‰ด์Šคยท๊ณต์ง€์— ๋Œ€ํ•œ ์ข‹์•„์š”๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด์„œ news_like, notice_like์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.- ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ์ง€ ์•Š์€ ๊ณต์ง€๋ฅผ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด ๊ธ€์„ ์ฝ์—ˆ๋Š”์ง€์— ๋Œ€ํ•œ ํ…Œ์ด๋ธ”์ธ user_notice_read์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.- ์‚ญ์ œ๋œ ๋‚ ์งœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ 30์ผ ๋’ค์— ์™„์ „ ์‚ญ์ œ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด deleted_at ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.- refresh token์€ Redis๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.- Redis์—์„œ๋Š” TTL์„ ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ๋งŒ๋ฃŒ์ผ์„ ๊ด€๋ฆฌํ•˜๊ณ , ์ž์ฃผ ๊ฐฑ์‹ ๋˜๋Š” access token์„ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๋†’์ผ ๊ณ„ํš์ž…๋‹ˆ๋‹ค.- ํ† ํฐ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ ๊ด€๋ฆฌ ์ธก๋ฉด์—์„œ๋„ Redis์˜ ์ด์ ์„ ๊ธฐ๋Œ€ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
OAuth id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)user_id (FK, INT UNSIGNED, NOT NULL)provider_id (VARCHAR (255), NOT NULL)provider (VARCHAR (20), NOT NULL) OAuth ์ •๋ณด ๊ด€๋ฆฌ - OAuth๋กœ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋“ค์˜ OAuth ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ํ…Œ์ด๋ธ”์ž…๋‹ˆ๋‹ค.- ํ˜„์žฌ๋Š” ์นด์นด์˜ค ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ด์ง€๋งŒ ์ถ”ํ›„ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ user_id๋ฅผ FK๋กœ ์ฐธ์กฐํ•˜๋Š” ํ˜•์‹์œผ๋กœ ์„ค๊ณ„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.- ์ž์ฒด ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ๊นŒ์ง€ ๊ณ ๋ คํ•˜์—ฌ ์‚ฌ์šฉ์ž ํ…Œ์ด๋ธ”๊ณผ ๋ถ„๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค. - ํ•˜๋‚˜์˜ OAuth๊ฐ€ ์žˆ๋Š”๋ฐ ๋‹ค๋ฅธ OAuth๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋”ฐ๋กœ ์‚ฌ์šฉ์ž ์„ค์ •ํƒญ์—์„œ OAuth๋ฅผ ์ถ”๊ฐ€ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด๋ฏธ ๊ฐ€์ž…์ด ๋˜์–ด ์žˆ๋Š” ์ด๋ฉ”์ผ๋กœ ์ƒˆ OAuth ํšŒ์›๊ฐ€์ž…์„ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ด๋ฉ”์ผ์ด๋‹ˆ ๋กœ๊ทธ์ธํ•ด์„œ ์ถ”๊ฐ€ํ•ด๋‹ฌ๋ผ๋Š” ์•ˆ๋‚ด๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ merge collision์„ ๋ฐฉ์ง€ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. - ๋กœ๊ทธ์ธ ์ดํ›„ ์นด์นด์˜ค ๊ด€๋ จ ์ •๋ณด๋ฅผ ๋ณ„๋„๋กœ ์š”์ฒญํ•˜์ง€ ์•Š๊ณ , ํšŒ์›๊ฐ€์ž… ๋•Œ ๋ฐ›์€ ์ •๋ณด๋ฅผ ์„œ๋น„์Šค DB์— ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— access_token์„ ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ณต์ง€ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT) user_id(FK, INT UNSIGNED, NOTNULL, AUTO_INCREMENT)title (VARCHAR 26, NOT NULL)content (TEXT, NOT NULL) tag(VARCHAR(10), NOTNULL)total_view_count (INT UNSIGNED, NOT NULL)like_count (INT UNSIGNED, NOT NULL)comment_count(INT UNSIGNED, NOT NULL)original_url (VARCHAR 512, NOT NULL)summary (VARCHAR 255, NULL)created_at (DATETIME, NOT NULL)updated_at (DATETIME, NOT NULL)deleted_at (DATETIME, NULL) ๊ณต์ง€ ๊ด€๋ฆฌ Indexes- INDEX (deleted_at, created_at DESC)  : ์‚ญ์ œ๋˜์ง€ ์•Š์€ ์ตœ์‹ ์ˆœ ์กฐํšŒ - ์นดํ…Œ๋ถ€ ์šด์˜์ง„์ด ์ž‘์„ฑํ•œ ๊ณต์ง€ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ์ œ๋ชฉ์€ ์ตœ๋Œ€ 26์ž๊นŒ์ง€๋งŒ ๋ฐ›์Šต๋‹ˆ๋‹ค.- content์˜ ๊ฒฝ์šฐ๋Š” ๋…ธ์…˜๊ณต์ง€, ๋””์Šค์ฝ”๋“œ ๊ณต์ง€๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ๋ณด์—ฌ์ฃผ๋Š”๋ฐ ๋…ธ์…˜ ๊ณต์ง€์—์„œ ๊ธด ๊ณต์ง€์˜ UTF-8 ์ธ์ฝ”๋”ฉ ๊ธฐ์ค€ ๋ฐ”์ดํŠธ์ˆ˜๊ฐ€ 10.7KB ๋‚˜์™”์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์˜ ๋‹ค๋ฅธ ์ปฌ๋Ÿผ์—์„œ VARCHAR๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ด๋ธ”์˜ ์ตœ๋Œ€๊ณต๊ฐ„์„ ๋„˜๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด TEXT๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€์Šต๋‹ˆ๋‹ค. - ์‚ญ์ œ๋œ ๋‚ ์งœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ 30์ผ ๋’ค์— ์™„์ „ ์‚ญ์ œ๋ฅผ ์œ„ํ•ด deleted_at์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.- ์กฐํšŒ์ˆ˜ยท์ข‹์•„์š” ์ˆ˜๋Š” ์งง์€ ์‹œ๊ฐ„์— ๋งŽ์€ SELECT๊ฐ€ ์˜ˆ์ƒ๋˜๋ฏ€๋กœ Redis๋กœ ์˜คํ”„๋กœ๋“œํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.- ์›๋ณธ URL ๊ธธ์ด๋ฅผ ๊ฐ์•ˆํ•˜์—ฌ 512์ž๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.- ๊ณต์ง€ ์š”์•ฝ์€ MVP ๋‹จ๊ณ„์—์„œ๋Š” ์—†์œผ๋ฏ€๋กœ NULL ํ—ˆ์šฉ์œผ๋กœ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.
๊ณต์ง€ ๋Œ“๊ธ€ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)user_id (FK, INT UNSIGNED, NOT NULL)notice_id (FK, INT UNSIGNED, NOT NULL)content (VARCHAR 500, NOT NULL)created_at (DATETIME, NOT NULL)deleted_at (DATETIME, NULL) ๊ณต์ง€์— ๋Œ€ํ•œ ๋Œ“๊ธ€ ๊ด€๋ฆฌ INDEXES - INDEX(deleted_at, created_at DESC) : ์‚ญ์ œ๋˜์ง€ ์•Š์€ ์ตœ์‹ ์ˆœ ์กฐํšŒ - ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต์ง€์— ๋‚จ๊ธฐ๋Š” ๋Œ“๊ธ€์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ๋Œ“๊ธ€ ์ž‘์„ฑ์ž๋Š” ๋ฐ˜๋“œ์‹œ ์กด์žฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ user_id FK๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.- ๋Œ“๊ธ€์ด ๋‹ฌ๋ฆด ๊ณต์ง€๊ฐ€ ๋ฐ˜๋“œ์‹œ ์กด์žฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ notice_id FK๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.- ๋Œ“๊ธ€ ๋‚ด์šฉ์€ ์ตœ๋Œ€ 500์ž๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.- ์‚ญ์ œ ํ›„ 30์ผ ๋’ค ์™„์ „ ์‚ญ์ œ๋ฅผ ์œ„ํ•ด deleted_at์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๊ณต์ง€ ์ฝ์Œ ์—ฌ๋ถ€ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)user_id (FK, INT UNSIGNED, NOT NULL,  UNIQUE (user_id, notice_id))notice_id (FK, INT UNSIGNED, NOT NULL,  UNIQUE (user_id, notice_id)) ์‚ฌ์šฉ์ž ์ฝ์Œ ์ฒดํฌ - ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต์ง€๋ฅผ ์ฝ์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ๋ณตํ•ฉํ‚ค ๋Œ€์‹  ๊ฐœ๋ณ„ PK + UNIQUE(user_id, notice_id)๋กœ ์œ ์ผ์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.- ์ถ”ํ›„ ์„ฑ๋Šฅ ์ด์Šˆ ์‹œ Redis ์บ์‹ฑ์„ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค.- ํƒˆํ‡ด ์ „์—๋Š” ์‚ญ์ œ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ soft delete๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ณต์ง€ ์ข‹์•„์š” id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)user_id (FK, INT UNSIGNED, NOT NULL,  UNIQUE (user_id, notice_id))notice_id (FK, INT UNSIGNED, NOT NULL,  UNIQUE (user_id, notice_id)) is_activated(BOOLEAN NOTNULL DEFAULT TRUE) ๊ณต์ง€๊ธ€ ์ข‹์•„์š” ์ฒ˜๋ฆฌ - ์‚ฌ์šฉ์ž์™€ ๊ณต์ง€์˜ ์ข‹์•„์š” ๊ด€๊ณ„๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.- UNIQUE(user_id, notice_id)๋กœ ํ•œ ๋ฒˆ๋งŒ ์ข‹์•„์š” ๊ฐ€๋Šฅํ•˜๋„๋ก ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.- ์ข‹์•„์š”/์ทจ์†Œ๋ฅผ is_activated๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. true๋ผ๋ฉด ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์ด๊ณ , false๋ผ๋ฉด ์ข‹์•„์š”๋ฅผ ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
๊ณต์ง€ ํŒŒ์ผ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)notice_id (FK, INT UNSIGNED, NOT NULL)file_url (VARCHAR 512, NOT NULL)type (VARCHAR 10, NOT NULL)name (VARCHAR 255, NOT NULL)file_seq_no (TINYINT UNSIGNED, NOT NULL) ๊ณต์ง€ ๊ด€๋ จ ํŒŒ์ผ ์ •๋ณด - ๊ณต์ง€์— ์ฒจ๋ถ€๋œ ์ด๋ฏธ์ง€ยทํŒŒ์ผ ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ์‹ค์ œ ํŒŒ์ผ์€ S3์— ์ €์žฅํ•˜๊ณ  URL๋งŒ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.- ํ™•์žฅ์ž ๊ธธ์ด๋ฅผ ๊ณ ๋ คํ•ด type์€ 10์ž๋กœ ์ œํ•œํ–ˆ์Šต๋‹ˆ๋‹ค.- ํŒŒ์ผ ์ด๋ฆ„์€ OS ํ•œ๊ณ„(255์ž)์— ๋งž์ถฐ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.- ํŒŒ์ผ ์ˆœ์„œ๋ฅผ file_seq_no๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค(์ตœ๋Œ€ 20).
๋‰ด์Šค id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)title (VARCHAR 26, NOT NULL)content (VARCHAR(1024), NOT NULL)total_view_count (INT UNSIGNED, NOT NULL)today_view_count (INT UNSIGNED, NOT NULL)like_count (INT UNSIGNED, NOT NULL)comment_count(INT UNSIGNED, NOT NULL)image_url (VARCHAR 512, NULL)created_at (DATETIME, NOT NULL)updated_at (DATETIME, NOT NULL)deleted_at (DATETIME, NULL) ๋‰ด์Šค ๊ด€๋ฆฌ INDEXES - INDEX(deleted_at, created_at DESC) : ์‚ญ์ œ๋˜์ง€ ์•Š์€ ์ตœ์‹ ์ˆœ ์กฐํšŒ - ์นดํ…Œ๋ถ€ ์†Œ์‹์„ ์ „๋‹ฌํ•˜๋Š” ๊ธ€์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ์ œ๋ชฉ ๊ธธ์ด๋Š” ์ตœ๋Œ€ 26์ž์ž…๋‹ˆ๋‹ค.- ๋‚ด์šฉ์€ ์ตœ๋Œ€ 1024์ž(VARCHAR)์ž…๋‹ˆ๋‹ค. AI ๊ฐœ๋ฐœ์ž๋ถ„๋“ค๊ณผ ์ƒ์˜ํ•œ ๊ฒฐ๊ณผ ๊ฐ€์žฅ ์ตœ์ ์˜ ์‘๋‹ต ํ† ํฐ ์ˆ˜๊ฐ€ 1024์˜€์Šต๋‹ˆ๋‹ค. - ์˜ค๋Š˜ ์กฐํšŒ์ˆ˜(today_view_count)๋Š” 00:00โ€“23:59 ๊ธฐ์ค€ ์ƒ๋‹จ ๋…ธ์ถœ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.- ์กฐํšŒ์ˆ˜ยท์ข‹์•„์š” ์ˆ˜๋Š” Redis ์บ์‹ฑ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.- ์ด๋ฏธ์ง€๊ฐ€ 1์žฅ๋งŒ ํ•„์š”ํ•˜๋ฏ€๋กœ image_url๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.- ์‚ญ์ œ ํ›„ 30์ผ ๋’ค ์™„์ „ ์‚ญ์ œ๋ฅผ ์œ„ํ•ด deleted_at์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๋‰ด์Šค ๋Œ“๊ธ€ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)user_id (FK, INT UNSIGNED, NOT NULL)news_id (FK, INT UNSIGNED, NOT NULL)content (VARCHAR 500, NOT NULL)created_at (DATETIME, NOT NULL)deleted_at (DATETIME, NULL) ๋‰ด์Šค์— ๋Œ€ํ•œ ๋Œ“๊ธ€ ๊ด€๋ฆฌ INDEXES - INDEX(deleted_at, created_at DESC) : ์‚ญ์ œ๋˜์ง€ ์•Š์€ ์ตœ์‹ ์ˆœ ์กฐํšŒ - ์‚ฌ์šฉ์ž๊ฐ€ ๋‰ด์Šค์— ๋‚จ๊ธฐ๋Š” ๋Œ“๊ธ€์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ์ž‘์„ฑ์ž๋Š” user_id, ๋Œ€์ƒ ๋‰ด์Šค๋Š” news_id๋ฅผ FK๋กœ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.- ๋Œ“๊ธ€ ๋‚ด์šฉ์€ ์ตœ๋Œ€ 500์ž๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.- ์‚ญ์ œ ํ›„ 30์ผ ๋’ค ์™„์ „ ์‚ญ์ œ๋ฅผ ์œ„ํ•ด deleted_at์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๋‰ด์Šค ์ข‹์•„์š” id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)user_id (FK, INT UNSIGNED, NOT NULL,  UNIQUE (user_id, news_id))news_id (FK, INT UNSIGNED, NOT NULL,  UNIQUE (user_id, news_id)) is_activated(BOOLEAN NOTNULL DEFAULT TRUE) ๋‰ด์Šค ์ข‹์•„์š” ์ฒ˜๋ฆฌ - ์‚ฌ์šฉ์ž์™€ ๋‰ด์Šค์˜ ์ข‹์•„์š” ๊ด€๊ณ„๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.- UNIQUE(user_id, news_id)๋กœ ์œ ์ผ์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.- ์ข‹์•„์š”/์ทจ์†Œ๋ฅผ is_activated๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. true๋ผ๋ฉด ์ข‹์•„์š”๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์ด๊ณ , false๋ผ๋ฉด ์ข‹์•„์š”๋ฅผ ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
์œ„ํ‚ค id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)title (VARCHAR 26, NOT NULL, UNIQUE)content (MEDIUMTEXT, NOT NULL)editor_name (VARCHAR 50, NOT NULL)created_at (DATETIME, NOT NULL)updated_at (DATETIME, NOT NULL)deleted_at (DATETIME, NULL) ์œ„ํ‚ค ๋ฌธ์„œ ๊ด€๋ฆฌ INDEXES -INDEX(title) - ์นดํ…Œ๋ถ€ ์ด์šฉ์ž๊ฐ€ ํŽธ์ง‘ยท๊ด€๋ฆฌํ•˜๋Š” ๋ฌธ์„œ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ์ œ๋ชฉ์€ ์ตœ๋Œ€ 26์ž์ด๋ฉฐ ์ค‘๋ณต ์ƒ์„ฑ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด UNIQUE๋ฅผ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.- content์˜ ๊ฒฝ์šฐ์—๋Š” ๋งˆํฌ๋‹ค์šด ํ˜•์‹์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ˆ˜๋ฌธ์ž๋„ ๋“ค์–ด๊ฐ€๊ณ , ์ด๋ฏธ์ง€๋„ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งŽ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด๊ฐˆ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์œ„ํ‚ค๋Š” ๋ชจ๋“  ๊ต์œก์ƒ์ด ์ˆ˜์ •, ๋‚ด์šฉ์ถ”๊ฐ€, ํŽธ์ง‘ ๋“ฑ์„ ํ•  ์ˆ˜ ์žˆ์–ด์„œ ํ•˜๋‚˜์˜ ์œ„ํ‚ค ๋ฌธ์„œ ๋‚ด์šฉ์ด ๊ธธ์–ด์งˆ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์˜๋„์ ์œผ๋กœ TEXT๋ณด๋‹ค ํฐ MEDIUMTEXT๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.- ์ตœ๊ทผ ํŽธ์ง‘์ž์˜ ์ด๋ฆ„์„ editor_name์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ์‚ญ์ œ ํ›„ 30์ผ ๋’ค ์™„์ „ ์‚ญ์ œ๋ฅผ ์œ„ํ•ด deleted_at์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. - ์œ„ํ‚ค ๋ฌธ์„œ์˜ ์ œ๋ชฉ์€ ์ค‘๋ณต๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์‹ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
ํ€ด์ฆˆ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)wiki_id (FK, INT UNSIGNED, NOT NULL)content (VARCHAR 255, NOT NULL)answer (VARCHAR(50), NOT NULL)created_at (DATETIME, NOT NULL) ํ€ด์ฆˆ ์ •๋ณด ๊ด€๋ฆฌ INDEXES - INDEX(created_at) LIMIT 1 - AI๊ฐ€ ์ƒ์„ฑํ•œ ํ€ด์ฆˆ ๋ฌธ์ œยท์ •๋‹ต ์ •๋ณด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ํ€ด์ฆˆ ๋‚ด์šฉ์€ 255์ž ์ดํ•˜๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.- ์ƒ์„ฑ ์‹œ๊ฐ์„ ์ €์žฅํ•˜์—ฌ โ€˜์˜ค๋Š˜์˜ ํ€ด์ฆˆโ€™๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. - ํ€ด์ฆˆ๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํ€ด์ฆˆ, ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ƒ์„ฑ๋œ ํ€ด์ฆˆ๋งŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
์ •๋‹ต id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)quiz_id (FK, INT UNSIGNED, NOT NULL)content (VARCHAR 50, NOT NULL) ํ€ด์ฆˆ ์ •๋‹ต ์ •๋ณด ๊ด€๋ฆฌ - ์œ ์‚ฌํ•œ ๋‹ต๋ณ€๋„ ์ •๋‹ต ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ •๋‹ต์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ๊ฐ€์žฅ ๊ธด ๋‹จ์–ด ๊ธธ์ด๋ฅผ ๊ณ ๋ คํ•˜์—ฌ 50์ž๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ œ์ถœ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)user_id (FK, INT UNSIGNED, NOT NULL, UNIQUE(user_id, quiz_id))quiz_id (FK, INT UNSIGNED, NOT NULL, UNIQUE(user_id, quiz_id))is_correct (BOOLEAN, NOT NULL)is_first_winner (BOOLEAN, NOT NULL) ์‚ฌ์šฉ์ž ํ€ด์ฆˆ ์ œ์ถœ ๊ด€๋ฆฌ - ์‚ฌ์šฉ์ž์™€ ํ€ด์ฆˆ์˜ ์ œ์ถœ ์ •๋ณด๋ฅผ ๋‹ด์Šต๋‹ˆ๋‹ค.- ํ•œ ์‚ฌ์šฉ์ž๋Š” ํ€ด์ฆˆ๋‹น ํ•œ ๋ฒˆ๋งŒ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ UNIQUE(user_id, quiz_id)๋ฅผ ์ถ”๊ฐ€๋กœ ๊ฑธ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.- ์‚ฌ์šฉ์ž๊ฐ€ ์ œ์ถœํ•œ ๋‹ต์ด ์˜ค๋‹ต์ด๋ฉด is_correct์— FALSE๋ฅผ, ์ •๋‹ต์ด๋ฉด TRUE๋ฅผ ์ €์žฅํ•œ๋‹ค.- ์‚ฌ์šฉ์ž๊ฐ€ ์˜ค๋Š˜์˜ ํ€ด์ฆˆ ์ตœ์ดˆ ์ •๋‹ต์ž๋ผ๋ฉด is_first_winner์— TRUE๋ฅผ ์ €์žฅํ•˜๊ณ , ์•„๋‹ˆ๋ผ๋ฉด FALSE๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
์šด์˜์ง„ ์•Œ๋ฆผ id (PK, INT UNSIGNED, NOT NULL, AUTO_INCREMENT)receiver_id (FK, INT UNSIGNED, NOT NULL)sender_id (FK, INT UNSIGNED, NOT NULL)content (VARCHAR 500, NOT NULL)is_read(BOOLEAN, NOTNULL)created_at (DATETIME, NOT NULL)deleted_at (DATETIME, NULL) ์•Œ๋ฆผ ์ •๋ณด ๊ด€๋ฆฌ - ์šด์˜์ง„์ด ๊ต์œก์ƒ์—๊ฒŒ ๋ณด๋‚ด๋Š” ์•Œ๋ฆผ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.- ์•Œ๋ฆผ ๋‚ด์šฉ์€ ์ตœ๋Œ€ 500์ž๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.- ์‚ญ์ œ ํ›„ 30์ผ ๋’ค ์™„์ „ ์‚ญ์ œ๋ฅผ ์œ„ํ•ด deleted_at์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.