DB 설계를 잘 해야하는 이유

정민교·2023년 6월 25일
0

DB

목록 보기
1/12
post-thumbnail

✔️DB 설계를 잘 못하면 발생하는 현상들

📌insertion anomalies

EMPLOYEE_DEPARTMENT

empl_idempl_namebirth_datepositionsalarydept_iddept_namedept_leader_id
1짱구.........1000dev1
2철수.........1000dev1

위와 같은 테이블이 있다고 가정합시다.

위에 테이블에서 dept_id, dept_name, dept_leader_id는 짱구와 철수 모두 중복된 데이터입니다.

이런 중복 데이터가 많아지면 문제가 하나만 저장하면 되는데 여러 번 저장해야 되니까 저장공간을 더 차지합니다.

또 데이터 불일치 문제가 발생할 수 있습니다.

짱구와 철수 모두 dev 부서인데 실수로 철수의 부서 이름을 deb로 잘못적을 수도 있는 것입니다.

🚨아직 부서 배치를 받지 못한 임직원을 추가한다면?

empl_idempl_namebirth_datepositionsalarydept_iddept_namedept_leader_id
1짱구.........1000dev1
2철수.........1000dev1
3유리.........nullnullnull

유리가 새로 입사를 하게 됐다면 아직 부서가 결정되지 않았습니다. 따라서 부서 관련 attribute값에 null값을 넣었습니다.

DB에서 null 값은 '아직 어떤 값인지 알 수 없음'의 의미입니다. three-valued-logic이라서 그런건데 이는 어렵지 않으므로 따로 찾아보시기 바랍니다.

어찌됐든 DB에서 null값이 많은 것은 좋지 않습니다. 가능한 null 값은 적게 쓰는 것이 좋습니다.

🚨부서는 생겼는데 아직 아무도 부서에 배치된 사람이 없는 경우?

empl_idempl_namebirth_datepositionsalarydept_iddept_namedept_leader_id
1짱구.........1000DEV1
2철수.........1000DEV1
3유리.........nullnullnull
4nullnullnullnull1001QAnull

부서가 새로 생겨서 부서 정보를 넣으려고 했는데 위 테이블은 직원 정보까지 포함하고 있어서 직원 정보도 넣어야 합니다. 하지만 이 부서에 아직 한 명도 없습니다.

그래서 직원 정보에 다 null 값을 넣어주게 됐습니다.

empl_id가 4인 이유는 empl_id가 pk이기 때문입니다. 따라서 null값을 넣을 수 없어 값을 정해주어야만 합니다.

부서 정보만 저장하는 tuple을 추가하는 것도 찝찝한데 있지도 않은 직원을 식별하는 pk도 추가해야하며, 많은 null값을 써야하는 문제가 발생합니다.

🚨QA 부서에 새 직원이 들어왔다면?

자 이제 QA 부서에 새 직원이 들어왔고 이 직원이 부서 리더가 되었습니다.

empl_idempl_namebirth_datepositionsalarydept_iddept_namedept_leader_id
1짱구.........1000DEV1
2철수.........1000DEV1
3유리.........nullnullnull
4nullnullnullnull1001QAnull
5채성아.........1001QA5

채성아가 들어와서 새로운 tuple을 추가해주었습니다. 이제 4번째 tuple은 필요 없으니까 또 삭제해주어야합니다. 매우 번거롭습니다.

그러면 '그냥 4번째 tuple을 업데이트 해주면 되는 것이 아니냐' 할 수 있는데, 이렇게 매번 null값으로 들어있는 tuple을 찾아다닐 수도 없는 노릇입니다.

📌deletion anomalies

채성아가 퇴사했다고 해봅시다. 그래서 채성아를 나타내는 tuple을 삭제하려고 하니까 부서 정보까지 사라지는 일이 발생하게 됩니다.

QA라는 부서는 아직 남아있는데 말입니다.

그래서 채성아 tuple의 직원 정보에 해당하는 attribute 값만 null로 넣어주도록 했습니다.

empl_idempl_namebirth_datepositionsalarydept_iddept_namedept_leader_id
1짱구.........1000DEV1
2철수.........1000DEV1
3유리.........nullnullnull
5nullnullnullnull1001QAnull

그랬더니 이번에는 너무 많은 null값을 사용하게 됐습니다. 또 직원은 없는데 직원을 식별하는 id도 있죠

📌update anmalies

empl_idempl_namebirth_datepositionsalarydept_iddept_namedept_leader_id
1짱구.........1000DEV1
2철수.........1000DEV1
3유리.........nullnullnull

이 상태에서 DEV 부서 이름이 DEV1로 바뀌었습니다.. 그런데 짱구의 부서명만 DEV1로 바뀌었다고 가정해봅시다.

철수도 짱구와 똑같은 부서인데 둘의 부서이름이 다릅니다. 데이터 불일치가 발생합니다.

📌spurious tuples

가짜 tuple이라는 의미입니다.

DEPARTMENT_PROJECT

dept_idproj_idproj_nameproj_location
10002000떡잎짱구집
10002001마을철수집
10012002방범대짱구집
10022003출동유리집

DEPARTMENT_LOCATION

dept_nameproj_location
해바라기반짱구집
해바라기반철수집
장미반짱구집
원장실유리집

위 테이블은 일단 대충봐도 이상합니다. dept_name은 DEPARTMENT_PROJECT에도 있어야 할 것 같은데 일단 없습니다.

이 상태에서 두 테이블을 natural join한다고 해봅시다.

dept_idproj_idproj_nameproj_locationdept_name
10002000떡잎짱구집해바라기반
10002000떡잎짱구집장미반
10002001마을철수집해바라기반
10012002방범대짱구집해바라기반
10012002방범대짱구집장미반
10022003출동유리집원장실

natural join 결과를 잘 보면 이상합니다.

1,2번 tuple을 보면 부서 아이디가 같은데 부서 이름이 다릅니다.

4,5번 tuple도 보면 부서 아이디가 같은데 부서 이름이 다릅니다.

join 하면서 가짜 정보가 생긴 것입니다. 원래 없던 정보가 생긴 것이죠.

📌join과 aggregate function 사용의 문제

null 값이 있는 attribute로 join하는 경우 상황에 따라 예상과 다른 결과가 발생할 수 있으며,

aggregate function에서 count()를 사용할 때 null 값이 있는 attribute에 사용하면 count는 null 값을 세지 않기 때문에 예상과 다른 결과가 발생할 수 있습니다.

📌왜 이런 문제가 발생했는가?

테이블 스키마를 잘못 짯기 때문에 이런 문제가 발생하는 것입니다.

다음과 같은 내용을 고려하며 테이블을 설계해야 합니다.

  • 테이블을 설계할 때는 하나의 관심사에 관련된 attribute만 묶어서 설계하는 것이 바람직합니다.

  • 중복 데이터를 최대한 허용하지 않도록 설계하는 것이 바람직합니다.

  • join 수행시 가짜 데이터가 생기지 않도록 설계하는 것이 바람직합니다

  • null 값을 최대한 줄일 수 있는 방향으로 설계하는 것이 바람직합니다.

✔️정리

지금까지 DB 설계를 잘못하면 발생할 수 있는 문제에 대해 알아보았습니다.

다음 포스팅에서는 올바른 DB 설계를 위한 정규화에 대해 알아보겠습니다.

profile
백엔드 개발자

0개의 댓글