라이징캠프에서 DB 설계 과제를 하게 되었다.
이 과정에서 조건이 존재했다
1. 모든 테이블에는 createAt,updateAt, status 속성을 갖도록 한다.
2. 한 방 쿼리 라는 것을 작성하는데, 여기서 한 방 쿼리 라는 이름이 붙은 이유 : 하나의 화면에 대한 것을 출력 시키기 위한 쿼리를 작성한다 . 이 때, 최대한 "하나의 쿼리만" 날리도록 작성한다.
나는 여기서, "status" column을 왜 가져야할까 에 대해 고민했다.
대충, 이 status column을 둔다면, 실제 레코드를 테이블에서 제거하는게 아니라 status만을 바꾸게 될 것이라는 생각을 했다. 이렇게만 보면 좋아보였지만, 이는 이제까지 내가 간단한 프로젝트를 만드는데 있어 해오던 과정은 아니었다.
또한 모든 테이블에 status를 둠으로서 불편한 상황이 생겼었다. 예를들어, Order를 undelete 하려는 경우, OrderMenu 상에 존재하는 multiple row들 또한 undelete 를 해 주는 등... 관련된 테이블에 있어서도 undelete하는 것을 구현해야했다...
따라서 이와 관련한 질문글 내용을 조금 정리해 보았다.
여기서 말하는 "status" column은 실세계의 item의 상태를 말하는게, 아니라, 그 record자체의 상태를 말한다.
예를들어, active record, Inactive record 아니면, deleted record, approved record 따위의 상태를 나타낸다.
- 이를 통해, 어떤 record를 delete하기로 하였을 때, 실제 테이블에서 그 record를 삭제하는 것이 아니라, record의 상태를 "delete" 로 업데이트한다.
- 그리고는, record들을 가져올 때면 항상 그 status가 Active나 Approved인 ( 어떤 조건을 만족하는 ) record만을 불러오도록 한다.
- 만약 어떤 사용자가 실수로 delete를 하더라도, 그 삭제한 레코드는 복구 될 수 있어야 한다. 이 경우, 단지 그 레코드의 상태를 Active or Approved로 바꿔주기만 하면 되게 된다.
라는 생각을 할 수도 있었는데, 과연 이렇게 status column을 추가해 주는게 옳은 일일까???
- 이 column 에 대한 필요성이 분명하고 크다면 , 존재해야하는 것이다. 하지만 그 필요가 그렇게 크지 않다면, 적은 베네핏을 위해 큰 오버헤드를 갖게 되는 것
---- 가장 중요한 것은, 진짜로 application에서 "undelete" 라는 것이 필요한지에 달려있는 것이다. ( 실제로 시스템 내부의 모든 테이블에 대해 그런 column을 두는 것은, 시스템 내부 모든 테이블에 대해 undelete도 또 구현해야하는게 되고 이는 상당히..괴로운 과정일 수도 있다는 것이다 -- 연관된 테이블이 여러개일 것이고, 이들 모두에 대해 이과정을 해줘야함.. 예를들어 나의 경우, Order를 취소하고 다시 취소를 취소(undelete)하게 된다면, Order에 1:다 관계를갖고 있는 OrderMenu 항목 하나하나에 대해 다 undelete를 해야한다... )
- 데이터 자체가 매우 복잡해진다. 실제로 테이블에서 제거하는게 아니게 되기 때문에, 쿼리를 할 때 이 deleted row들이 여전히 계산이 되어야한다. 레코드들이 존재하지만, 실제로 이들은 deleted되었다는 정보를 추가적으로 항상 더 알고 있어야 하게 된다.
- 또는, 이 rows들은 제외시킨 View를 생성해서 사용해야 한다.
- 그리고 당연하게도.. DB 크기가 증가한다. 실제로 이 row들을 제거하지 않다보니 공간을 차지하고 있게 된다.
-----------
( 그럼, 이 값에 대한 필터링이 자주 일어날텐데, 여기에 index를 설정해야하는가에 대해서도 고민되었다. 하지만 index에 대해 잘 몰라서 이에 대해서도 찾아보았다 )
이런식으로 low cardinality column 에 대한 index를 추가하는 경우는 " 매우 rare한 값들에 대한 서칭을 해야할 때 " 임. 예를들어, 이 status의 값으로 New, Processed가 올 수 있는데, 95%의 record들이 Processed를 값으로 갖는 경우에, "New" 값을 갖는 레코드를 자주 서칭해야한다면, 이 column에 대한 index가 이 과정을 하는 것을 도와줄 수 있음.
- 하지만.. 보통은 이런 column 자체를 index로 하기보다는, multicolumn index의 일부중 하나로 사용하는 것을 추천한다고 한다. ( 예를들어, ( State,createdAt )에다가 index를 추가해 주면, State ='New' 이면서, createAt 으로 order by 하는 쿼리를 할 때, 속도를 높여줄 수 있다 )
https://dba.stackexchange.com/questions/101094/index-on-column-with-only-3-status
'DB' 카테고리의 다른 글
카티션 곱, JOIN 에서 USING, ON / JOIN 에서 ON 과 WHERE (1) | 2022.10.31 |
---|---|
SELECT DISTINCT 와 ORDER BY 가 함께 쓰이는 경우 정렬은 예상하지 못하게 일어난다 (0) | 2022.10.28 |