loading
본문 바로가기
I Learned/- Projects

#DB final / 디비에 대한 고찰

by pikiforyou 2021. 2. 27.

 

최종 디비완성

 

최종디비의 모습이다. SQL로 옮겨서 구현하면 오늘의 할일 끝 :)

 

디비설계는 항상 처음이 아니라, 생각하면 생각할수록 더욱 좋은 디비의 모양이 나오게 되는 것 같다. 몇일후에 관계를 찬찬히 다시 살펴보면, 개선할 수 있는 방법과 구현할 수 있는 다른 방법이 생각나게 된다. 코린이기때문에 최종디비가 완벽한 디비다! 라고 확신할 수는 없겠지만, 구현할때마다 테이블 명명규칙/스키마설계/지양/지향점을 찾아보고, 좀 더 편하고 활용성이 좋은 테이블의 구조는 무엇일까 생각하는것이 즐겁다.

구현되야할 기능에 대해서 최대한 많은 변수를 생각해보고 디비를 설계해야하기때문에, 디비구축은 언제나 좋은 경험인 것 같다

 

 

 


 

수정한 내역

  • 모든 컬럼에 MySQL 데이터타입 추가
    • 모든 member_id값 binary(16) 설정 = UUID
    • 모든 id값 auto increment 값 설정 (int(11))
  • hidden관련한 1:1대응 관계 변경
    • admin_interview/admin_category는 사용자가 건들수없는 디폴트소스값이기때문에 hidden테이블을 따로 두었다
    • my_interview/my_interview_category는 테이블내에 use_yn컬럼을 새롭게 추가했다.
  • to_do state값은 status로 변수명변경
    • 상태부분 completed/expired 로 세분화 변경
  • todo 1:1 대응 관계로 만들어주는 작업
    • company_label테이블 삭제후, status컬럼으로 company테이블내에 추가
    • todo_label -> label 로 테이블 변경
    • todo_and_label로 테이블 추가(1:1대응관계 테이블)
    • company_id(FK)는 Nullable로 변경
  • 기타 추가한 컬럼내역
    • 이메일 인증컬럼추가 → verify 컬럼추가
    • company 테이블에서 url링크를 달수있게 link컬럼 추가
    • my_interview에 use_yn으로 컬럼추가

 


 

디비 설계를 마치고 

 

이번에 많이 알아본 내역은 PK값은 어떻게 설정하면 좋은지에 대해서였다.

여러가지를 검색하며 생각해봤을 때,

PK는 유일하고, 예상가능하며, 성능저하가 일어나지 않아야하고, 인덱싱이 되며, 보안상의 이슈도 없어야 했다. 

기존 팀프로젝트때는 Oracle을 사용했기때문에 시퀀스를 만들고, .nextval 대신에 Trigger를 걸어사용했었다. MySQL에서는 Auto increment 라는것이 그 기능을 대신하고있었다.  

 

이 편리한 기능을 이용해서 PK를 저장하는것보다, 거의 유일성이 보장되는 UUID로 지정해야하는게 아닐까 생각이 들었었다. 

마치 React에서 key값으로 index를 관용적으로 주면 해결은 되지만, 프로그램이 커질때나 다른 상황을 고려하면 유일한 값을 보장해줘야한다고 찾아봤던것과 같은 맥락이었다. 

 

하지만 막상 찾아봤을 때는 상충되는 내용들이 있었다.

일단, UUID는 난수이기는 하지만 동일한 수를 만날 확률이 거의 없다고 봐도 무방했기에 유일성 문제는 괜찮았다. 하지만 인덱싱으로 사용하기에는 크기 자체가 크기때문에 PK에 바로 집어넣으면 성능저하가 우려되기때문에 PK로는 Auto increment를 사용한다는 글이었다. 또한 바로 사용하기에는 '-' 같은 글자가 걸리기때문에 가공해서 집어넣어야 했다.

물론 Auto increment도 만능은 아니었다. 일부DB에서는 소실되는 일이 있고, 마지막 값을 찾는데에 문제가 있을수도 있었다 (이는 실제로 팀프에서 동일 세션내에서 INSERT가 진행되지않으면 시퀀스의 .currval을 확인조차 할수 없었던 점으로 겪긴 했었다).

즉, 값이 발생되기전에는 알 수 없으므로 예상가능하지 않다는 점이었다. 또한 숫자증가 방식이라 그대로 웹상에 노출될경우 보안상 예상가능한 문제도 있다. 

 

 

데이터명명규칙도 그렇고 왜 정답을 쉽게 주지않는거야..!!!

 

 

언제나 독학은 정답, 또는 더 옳거나 나은 방법에 대한 답에 대해 목마르다 (...)

 

결국 내리게 된 결론은, 유저가 접근할 수 없는 DB(BACKEND)단에서는 auto increment를 사용하는 것이고, 이에 대해 url로 오가면서 보이게 되는 FRONTEND단에서는 UUID로 난수화시켜주면 되지 않을까였다.

다만 정확히 어떤 식으로 줘야하는지 모르겠기에 일단 이번 프로젝트에서는 가능한선에서 사용해보기로 했는데, member_id 값에는 UUID를 넣어서 식별을 하고 나머지 테이블들의 PKAuto incrementint(11) 데이터 타입으로 주었다. 

 

이 때 UUID는 인덱싱을 보장받을수있는 방식으로 가공하여 binary(16) 타입으로 저장시킬 것이고,
다른 PK들은 unsigned를 선언한 int(11) 타입으로 최대한 낭비없이 사용할것이다!

 

 

유일한 값을 줘야하는 PK의 더 나은 방식에 대한 고민은 앞으로도 계속될것같다. 

그래도 항상 더 나은 방식을 생각하고, 그에 대한 정답을 알아내는건 너무 즐거운 일이다. :P

 

 

 


추가로 더 작성한 글

2021/03/01 - [BACK-END/SQL] - Auto Increment vs UUID ?

 

댓글