[TOY] DB 스키마 설계하기 1부 테이블 생성 및 관계도 설정

캡틴 노드랭크·2023년 1월 27일
0

Project

목록 보기
5/7
post-thumbnail

게시글 수정

  • 2023 02-03
    • 회원 테이블 빈약했던 부분 추가
    • 게시글 테이블 빈약했던 부분 추가
      • 테이블 분리
      • 무결성 확인

저는 개인 블로그를 제작하는 과정에 있어서 어떠한 유형의 데이터베이스를 사용할 지 고민했었습니다. 데이터베이스의 종류 두 가지가 있는데, RelationShip형 데이터베이스와, NoSQL형식의 데이터베이스가 있습니다.

관계형 데이터베이스의 차이점은 다음과 같습니다.

차이점

SQLNoSQL
DatabaseDatabase
TableCollection
ColumnField
RowDocument

DB 명세서 작성

다양한 블로그 플랫폼이 존재하며 이 블로그들을 참고삼아 가장 간단한 명세서부터 작성해봤습니다.

우선 명세서를 작성하기전 고려해야할 사항부터 알아봅시다. 이 곳에서 참조하였으며, 파워 오브 데이터베이스라는 책을 통해서도 학습중에 있습니다.

블로그 DB 명세서

가장 먼저 회원제도가 존재하고, 제 경우에는 게시글을 관리하는 관리자와 이용하는 회원이 있어야합니다. 그리고

  1. 블로그에는 회원(User)과 블로그 관리자 혹은 주인이(Admin) 존재한다.
  2. 블로그에는 관리자 혹은 주인만 게시글을 작성할 수 있다.
  3. 블로그에는 관리자 혹은 주인만 일부 게시글을 공지로 옮길 수 있다.
  4. 블로그에는 회원은 검색, 읽기, 좋아요, 댓글만 활용할 수 있다.
  5. 게시글은 마크다운 문법으로 글을 작성할 수 있어야한다.
  6. 게시글은 이미지와 첨부파일을 업로드 할 수 있어야한다.
  7. 게시글은 조회수 정보를 포함하여야한다.
  8. 게시글은 해시태그를 달 수 있었으면 좋겠다.
  9. 게시글은 대분류와 소분류의 카테고리로 나뉘어야한다.
  10. 댓글은 한 게시글에 0개 이상을 작성할 수 있다.
  11. 댓글 작성은 오직 로그인 한 회원만 가능하다.
  12. 댓글에 추가적인 답글을 작성할 수 있어야한다.
  13. 카테고리는 대분류와 소분류로 나눠 중첩된 형태로 이루어진다.
  14. 회원가입은 OAuth2.0을 활용한 간편한 가입이 되어야합니다.
  15. 회원은 서드파티사에서 제공하는 프로필 정보를 가지고있지만, 수정할 수 있습니다.
  16. 관리자는 회원관리를 할 수 있습니다.

테이블 설계

위에 제 스스로와 간단한 인터뷰를 통해 어떠한 테이블이 필요한지 정리할 차례입니다..

사용자, 카테고리, 게시글, 댓글, 태그 등이 필요할 것 같습니다. 또 찾아보니 게시글에 포함할 첨부파일 테이블도 있기에 추가해줍니다. 이제 각 테이블이 어떤 목록이 필요한지 정리하며 예비테이블을 만들어 나가겠습니다.

A. 유저

유저는 사용자와 관리자가 나뉘게 됩니다. 우선 회원제도는 따로 두지않고, SNS 로그인 가입만 받습니다. 블로그 활동은 로그인 한 회원만 가능했으면 좋겠습니다.

소셜 로그인을 통해 어떠한 정보가 넘어오는지 google로 예를 들어보겠습니다.

//구글에 요청하면 이렇게 옵니다.
 {
 "id": "사용자일련번호",
 "email": "이메일,
 "verified_email": true,
 "name": "a b c",
 "given_name": "s",
 "family_name": "d",
 "link": "https://plus.google.com/115625613876653534063",
 "picture": "https://lh6.googleusercontent.com/-Pq0jb6y0rmw/AAAAAAAAAAI/AAAAAAAAERI/0K0OhMiZUqY/photo.jpg",
 "gender": "male",
 "locale": "en"
} 

토큰을 발급받고 요청하게되면, 회원 정보가 이런식으로 넘어오게됩니다. email,name,picture 등만 추출하면 될 것 같습니다.

추가적으로 고려사항은 다음과 같습니다

  • 관리자는 회원 권한을 줄 수 있는가?
  • 관리자는 광고성 유저, 악성 댓글(패드립, 심한욕설)유저를 재제할 수 있나?

정도가 될 것 같습니다. 그래서 필요한 테이블은 다음과 습니다.

B. 카테고리

카테고리는, 카테고리 명 그리고 계층형으로 구분짓기 위해 카테고리의 메인 키를 참조할 만한 별도의 무언가가 있어야합니다.

이렇게 테이블을 나눌수 있습니다. 하지만 데이터 넣기도 복잡해지고, 괜히 일만 키워버립니다. 관계형 데이터베이스에는 Recursive Relationship 이라는 자기 참조 관계 기법이 존재합니다. 주로 조직도를 구현할 때 사용합니다. 그래서 자기참조가 될만한 리스트로 다음과 같은 이름을 붙였습니다. 부모 카테고리 번호, 테이블은 다음과 같습니다.

카테고리를 생성한 날짜도 넣기도 그러는데... 굳이 언제 생성했는지 수정하고 삭제했는지 불필요할것 같아 리스트에선 뺐습니다.

C. 게시글

게시글은 가져야할 리스트가 좀 많을것 같습니다. 보통 "글쓰기" 클릭하게되면, 페이지로 이동하면서 브라우저는 글쓰기 페이지를 그려줍니다. 게시판 글쓰기를 보면 정말 여러가지 기능들이 존재합니다. 어떠한 기능들이 있는지 대략적으로 리스트를 작성해봤습니다.

  • 제목
  • 부가 설명
  • 작성자
  • 본문
  • 슬러그: [slug는 SEO를 위해 추가해주었습니다. 게시물 번호대신 제목을 URL로 노출하고 싶기때문입니다.]
  • 이미지 명
  • 이미지 경로 : [이미지 명과 경로는 카테고리를 클릭했을때 화면에 그려주는 게시물 썸네일입니다.]
  • 첨부파일 명
  • 첨부파일 경로
  • 첨부파일 확장자
  • 조회수
  • 추천수
  • 해시 태그
  • 공개 여부
  • 검색엔진최적화(SEO)
  • 생성일
  • 수정일
  • 삭제일

이렇게 리스트를 완성하고, 테이블을 뽑아야합니다. 하지만 하나의 테이블로는 일관성을 해치기때문에 문제가 발생할 확률이 높습니다. 리스트 중에서 구분지어 테이블을 생성해보도록 하겠습니다.

첨부파일 : 첨부파일은 게시글에 속해있지만, 파일의 경로, 확장자, 크기 등의 정보를 필요합니다. 즉 게시글에 포함될 부가적인 요소이기 때문에 분리했습니다.
추천수 : "좋아요" 기능입니다. 따로 분리해줘야 하는 이유는 하나로 합치면 좋아요를 누르는 회원을 기록할때 조금 난감해집니다. 무결성을 위해선 빼는게 더 낫습니다.
조회수 : 중복 조회 방지를 위해 별도로 빼서 관리해 줄 수 있습니다. 하지만 Redis로 ip를 수집하던가 cookie를 통해 검증할 방법이 있기때문에 단순히 카운팅용도로 게시글 테이블에 포함시키겠습니다.
검색엔진최적화: SEO용으로 별도의 정보를

C - 1. 좋아요(추천수)

좋아요를 따로 분리한 테이블을 빼줍니다.

왜? 게시글과 분리를 해야할까요.

  • 좋아요 테이블을 분리 함으로서 어떤 사용자가 눌렀는지 확인할 수 있습니다.
  • 좋아요 테이블의 중복 횟수를 없에 비교적 정확한 수치를 제공할 수 있습니다.

그렇기 때문에 좋아요 테이블을 따로 분리해주는게 낫습니다. 그리고 좋아요를 얼마나 눌렀는지 확인해야 하기 때문에 p_like_cnt을 게시글 테이블에 추가해줍니다.

테이블은 다음과 같습니다.

C - 2. 해시태그

대부분 블로그에는 별도의 해시태그가 달려있기 때문에, 제 블로그에도 이 기능이 들어가야 되겠다 생각했습니다. 카테고리처럼 계층형으로 이루어지지 않지만, 하나의 게시글에는 여러개의 해시태그를 달 수 있습니다.

그렇다는건, 게시글의 메인키를 참조해야하고, 해쉬 태그 명만 필요할것 같습니다.

해시 태그와 게시글의 관계는 N:M 일것입니다.

하나의 해시태그에는 다양한 게시글이 존재하고
하나의 개시글에는 여러개의 해시 태그를 포함합니다.
해시태그는 모든글에 중복될 수 있습니다.

이런 게시판과 해시태그 관계에서는 3개의 테이블을 생성하는 솔루션을 적합한 방법으로 이용되고 있습니다.

테이블은 다음과 같습니다.

C - 3. 첨부파일

첨부 파일은 하나의 게시글에 다양한 확장자들로 이루어진 파일이 올라 올 수 있습니다. 그리고 첨부파일에 대한 정보를 필요하다 싶어 추가해줬습니다.

테이블은 다음과 같습니다.

C - 4. 게시글 메타

검색엔진 최적화(SEO)를 위한 postmeta 테이블입니다. 작성글의 정보를 구글같은 곳에 노출하기위해 데이터를 저장할 테이블입니다.

F. 댓글

댓글은 ,사용자,내용,생성일,수정일 등이 있습니다. 여기서 고려해봐야할건 다음과 같습니다.

  1. 댓글에는 답변글(대댓글)을 달 수 있다.
  2. 대댓글은 어떤 댓글에 달렸는지 알 필요가 있다.
  3. 댓글과 대댓글의 구분이 필요하다.

이 정보로 추가적인 컬럼이 필요할거라 생각됩니다.

이 부분에서 깊이와 그룹이 추가되었습니다.

  • 댓글 부모(c_p_id): 부모 댓글의 키를 담고있습니다. 어떤 댓글에 속했는지 알기위한 그룹화입니다.
  • 댓글 깊이(c_depth): 댓글의 깊이로 대댓글을 구분하기 위한 컬럼입니다.(0: 댓글, 1: 대댓글)

최종정리

완성되면 올리겠습니다.

관계설정

[ 1 : N ]관계

  • 사용자 - 게시글
  • 사용자 - 댓글
  • 카테고리 - 게시글
  • 게시글 - 해시태그
  • 게시글 - 업로드 파일
  • 게시글 - 댓글

[ N : M ] 관계

  • 게시글 - 해쉬태그
  • 게시글 - 좋아요
  • 사용자 - 좋아요

자기 참조 관계

  • 댓글 - 대댓글
  • 카테고리 - 보조 카테고리

ref: 태그, 조회수

profile
다시 처음부터 천천히... 급할필요가 없다.

0개의 댓글