프로젝트 Readme를 쓰기위해 ERD명세서를 만들고 있다. ERD명세서는 프로젝트 기획할 때 한번, 최종 발표 전 한 번, 그리고 지금 총 3번째 만드는 중인데, 그릴 때 마다 매번 헷갈린다. 또한 매번 그릴때마다 과거에 틀렸던 점을 발견하고 있다. Diagram 자체의 표기법이 완전히 정확하지 않더라도 개발에 큰 문제는 없었지만 리드미에 올리는 ERD는 정확해야 하므로 천천히 정리해본다.
* 일반적인 글과 다르게, 해당 글의 순서는 ERD Cloud에서 ERD를 그릴 때 선택하는 논리적 순서대로, 관계차수(Cardinality ,1:1, 1:N, M:N) -> 참여도(mandatory/optional) -> Relationship(식별/비식별 관계)순으로 다루겠다.
0. Prerequisite
- ERD : Entity Relationship Diagram, 개체-관계-도
- 정규화 : https://mangkyu.tistory.com/110
- 관련 용어(Entity, Attribute,Domain, PK, FK 등)
- key의 개념
- DB 이상현상 : https://dev-coco.tistory.com/63
1.관계차수(Relationship Cardinality)
Cardinality : 각 entity사이의 한 개체는, 다른 entity의 몇 개의 개체와 대응하는가?
카디널리티는 관계선의 끝 부분을 결정한다. 관계선의 끝이 하나의 점이면 one, 세 점(까마귀발)이면 Many이다.
one은 Many(까마귀 발)와 합쳐져서 '하나 또는 다수'의 의미가 될 수 있다.(=참여도)
1.1 일대일(One to one) : 1 : 1,
ex) 학생_tb과 신체정보_tb(키,몸무게...). 하나의 학생개체는 하나의 신체정보 개체와 대응한다. (전제 : 여러 날짜의 신체정보를 담는 것이 아님)
1.2 일대다(One to many) : 1 : n,
ex)교수님과 수업하는 학급 : 한명의 선생님은 여러 학급을 강의함
강의실과 강좌tb : 하나의 강의실에는 여러 강좌가 열린다.
1.3 다대다(Many to many) : m : n
학생tb과 동아리tb가 있다면?
학생tb 입장으로 볼 때 한 학생은 방송부, 밴드부 등 여러 동아리에 들어갈 수 있다.
마찬가지로 동아리tb 입장으로 보아도 하나의 동아리는 여러 학생을 가진다. 즉 m : n이다.
m:n 관계가 성립될 경우 데이터에 중복이 발생하고 갱신이상(Anomaly)이 일어난다.
m:n 관계를 해소하려면 정규화를 통해 중간테이블(Link table, Join table)이 필요하다. 즉, 학생-동아리 tb다.(사진의 Student_Interest 테이블)
학생-동아리(흥미) tb에는 stu_id와 club_id와 같은 FK 2개로 이루어진다.
다른 예로는 user_tb와 team_tb가 있을 때 team_member_tb가 있겠다. 마찬가지로 중간테이블인 team_member_tb에는 user_id와 team_id FK 2개로 user와 team의 관계를 설명할 것이다.
*참고 : 카디널리티는 어느 맥락에서 사용되냐에 따라 그 의미가 비슷하면서도 다릅니다.
1.관계차수와 같은 뜻으로는 사상수(mapping cardinality)라고도 부르기도 합니다.
2.Cardinality는 SQL에서는 중복도와 같은 지표로서도 사용되며, ex) 주민등록번호와 사람의 cardinality는 높고, 성별과 사람의 cardinality는 매우매우 낮다.
3.일반적으로는 하나의 릴레이션(테이블)에서 입력된 튜플(레코드,row)의 수를 뜻합니다. Ex) 만약 대한민국국민_tb가 있다면 그 카디널리티는 약 5,000만
2.참여도
관계선의 맨 끝 전에 있는 세로선 또는 원형의 기호.
참여도는 2가지 기호로 결정된다.
|(필수, mandatory ) or O(Optional, 선택).
Mandatory의 M은 기호 |를 포함하고있고 Optional의 O는 기호 O를 포함하고 있다로 이해하면 쉬울듯.
Optional
ex) 학생은 동아리에 들 수도 있고 안들 수도 있다. ( 어미 : ~수도 있다.)
ex) 유저는 게시판에 글을 쓸 수도 있고 안쓸 수도 있다. (= 없거나~ )
따라서, student_tb와 club_tb가 있다고 할 때, club_tb의 끝 부분에는 'O'이 붙어야한다.
Mandatory
잘 설명된 예시. (어미 : ~있다. / 존재한다)
관계차수와 참여도를 종합하면?
ERD Cloud에서는 아래와 같은 종류의 관계선을 사용할 수 있다.
이를 표로 정리해보면,
Optional | one + many | 없거나 한개 또는 여러개 | |
Optional | many | 없거나 여러개 | |
Optional | one | 없거나 한개 | |
Mandatory | many | 한개 또는 여러개 | |
Mandatory | one | 무조건 한개. Only one | |
null | many | 여러개 | |
null | one | 한개 |
4.식별자/비식별자 관계
식별자 관계(실선)
강한 연결관계 표현
-> 부모테이블의 기본 키(주 식별자, identifier)를 자식테이블에서 기본 키로 사용하는 경우
ex1) user_tb와 role_tb, user-role_tb와 같은 m:n 관계에서 join table과 2개의 부모테이블
=> 실선(전제: 하나의 유저는 하나의 role을 가진다)
User-role tb에서는 user_tb의 기본키와 role_tb의 기본키를 갖는다.ex)유저아이디가 1에 해당하는 유저는 역할아이디 9에 해당하는 역할을 갖는다
ex2) 한 학생이 3대운동을 몇 치는지 나타낼 때,
학생_tb(학번, 이름...) 과 3대기록_tb(student_id, squat, bench, deadlift) => 기본키가 그대로 사용되므로 실선.
*만일 1:n 관계라면(예: 여러 일자의 3대 데이터를 담는 경우) 자식테이블인 3대기록_tb에서 학번은 중복되므로 기본키가 될 수 없음에 유의.
비식별자 관계(점선)
약한 연결관계 표현
-> 부모테이블의 기본키를 자식테이블이 가지고는 있으나 기본키로 사용하지 않는 경우
user_tb와 team_tb이 있을 때, team_tb의 컬럼 'leader_user_id'는 team_tb에서 기본키가 아닌 user_id의 외래키(기본키x) => 점선
user_tb와 article_tb(게시글)가 있을 때 하나의 유저는 여러 게시물을 작성할 수 있으므로 식별자가 될 수 없다. 따라서 article_tb에서 user_id는 기본키가 아님 => 점선
(꼭 식별자 가능여부를 따지지 않더라도 게시글은 article_id라는 그 테이블만의 식별자를 가짐이 명확하므로 점선이다.)
대부분의 경우는 비식별자 관계이다. (유연성)
한마디로 정리하면?
(조금 야매지만)
자식테이블(끝 점)이 부모테이블(시작 점)의 기본 key를 참조할 때,
그 기본 key가 자식테이블에서 반드시 최상단에 있어야한다면 실선 (이 경우 자식테이블에서는 기본키가 없다)
조금 아래에 있어도 무방하다면 점선으로 생각할 수 있다.
3.Reference
https://www.erdcloud.com/d/TzHsgqxPRGzWGzytR
내용에 잘못된 점이 있다면 편하게 말씀해주세요.
'Back-End > DB' 카테고리의 다른 글
RDBMS, mySQL 기초, 기초 쿼리 (Select, Insert, Create, update, delete) (0) | 2023.07.21 |
---|---|
[오류해결] new function시 오류 : log_bin_trust_function_creators variable (0) | 2023.07.21 |
mySQl 다운로드 / 설치방법 (간단) (0) | 2023.07.19 |