'것'
SQLD 하게 되면 제일 먼저 배우는게 엔터티, 관계 그리고 속성이다. 그 중에서도 엔터티는 설명이 그냥 '어떤 것'이다. 그니까 말 그대로 어떤 '것'이요. 엔터티의 정의를 보면
업무에 필요한 정보를 저장하고 관리하기 위한 집합적인 것
이라고 하는데 진짜로 어떤 것이다. 엔터티가 뭐예요? 어떤 것이요. 그래서 어떤거요? 그냥 '것'이다.
엔터티의 분류
엔터티는 물리적으로 존재하는지에 따라 유형엔터티와 무형엔터티로 나누고, 무형엔터티는 또 개념엔터티와 사건엔터티로 나눈다. '것'들 중에서도 물리적인 형태가 존재하는... 피카츄 돈까스(...)나 초코칩프라페, 자바칩프라푸치노, 변기, 자같은 것들은 물리적인 형태가 존재하기때문에 유형 엔터티라고 볼 수 있다. 유니콘... 갸는 형태가 없으니 일단 유형은 아님... 내 남자친구... 질량이 0인데 엔터티라고 정의할 수 있나?
개념엔터티와 사건엔터티는 둘 다 물리적인 형태는 없다. 그럼 둘이 뭔 차이냐고? 개념 엔터티는 형체는 없지만 업무상 관리가 필요한 것들(예: 수업, 업무 자체)이고 사건 엔터티는 형체도 없고 뭐 할때마다 발생하는 엔터티들이다. 예를 들어서 내가 집에 쳐들어온 바선생을 잡았어, 그러면 나라는 엔터티가 집에 들어온 바퀴벌레를 쳐 죽이는 사건이 생긴거다.
예를 들어보자. 피카츄라는 엔터티와 라이츄라는 엔터티는 서로 진화관계이다. 그리고 내가 천둥의 돌을 써서 피카츄를 라이츄로 만들게 되면 진화한다는 사건 엔터티가 생겨나게 되는 것이다. 이 진화관계 나중에 ERD 설명할때 한번 더 다룰 예정임. 미끄네일과 미끄래곤 역시 특정 조건을 만족하게 되면 진화하는 관계로 묶여있고, 비가 오는 날씨에 레벨 50 이상을 만족하게 되면 진화한다는 사건 엔터티가 발생하게 된다. 내가 편의점에 가서 신상으로 나온 캬라파키를 샀어, 그러면 편의점과 나 사이에 거래라는 사건 엔터티가 발생하게 된다.
그러니까 '것'들을 형태유무, 특징에 따라 유형, 무형, 사건 엔터티로 나눈다. 여기까지 이해하셨죠?
엔터티의 특징
1. 해당 업무에서 관리가 필요한 정보만을 포함한다.
예를 들어보자. 스토리에 쓸 포켓몬을 잡을때는 이 포켓몬의 종족값, 타입, 그리고 어떤 기술을 배우는지가 중요하지 이 포켓몬의 키나 몸무게는 별로 중요하지 않다. 이건 실전 할 때도 마찬가지라서 이 포켓몬이 어떤 유형인지, 성격은 뭘 써야 하는지, 개체값과 노력치는 어떻게 해야 하는지, 기술이랑 지닌 물건은 뭘로 세팅하는지, 어떤 파티에 쓰는지가 중요하지 여기서 키랑 몸무게가 그렇게 중요하지는 않다. 그러니까 내가 라이츄를 스토리 밀 때 쓸 거면 얘는 전기쥐고(쥐 맞음) 기배가 어떻고 성격은 어떻고 몇레벨에 뭘 배우는지(이건 사실 피카츄일 때 중요함)가 중요하지 이 주황뚱쥐가 몇kg 나가는지는 별로 쓸모가 없다 이거요.
좀 더 쉬운 예시를 들어보자. 요즘 이력서에 지원자 키나 몸무게 쓰게 되어있음? 아뇨, 옛날 양식을 그대로 쓰는거라면 몰라도 요즘은 키, 몸무게, 가족관계 기재 안 한다. 왜죠? 답은 간단하다. 일할때 그게 쓸모가 있음? 회사에서 사원이라는 엔터티를 관리할 때 필요한 건 이 사원의 이름, 사번, 그리고 어느 부서에서 일하는지이지 이 사람이 장남인지 장녀인지가 아니다.
그러니까 이 특징을 한마디로 요약하자면 엔터티에는 사족을 달면 안 된다, 이 얘기다.
2. 유일한 식별자에 의하여 식별이 가능해야 한다.
이건 DB를 한 번이라도 만져보신 분들이라면 아! 이거! 할 수도 있는 특징인데… 여러분들 회원가입할 때 아이디 입력하고 뭐 합니까? 그죠 중복확인 하죠. 왜죠? 다른 사람하고 아이디가 겹치면 안되잖음.
엔터티 내부에는 인스턴스라는 게 들어있고, 이게 우리가 주로 DML로 주물주물하게 되는 요소들이다. 그러니까 포켓몬이라는 엔터티 안에 있는 이상해씨, 꼬부기, 파이리 이런 애들이 인스턴스인 셈. 그리고 포켓몬들은 각각 유일한 식별자(보통 PK)에 의해 식별이 가능한'데'... 포켓몬의 경우 이름만으로는 완전히 식별이 안 된다. 왜죠? 라이츄 하면 원종(관동) 라이츄, 알로라이츄(캬라멜뚱쥐), 메가라이츄(XY 두개) 네마리잖아요. 그러면 이 라이츄들 사이에서도 특정 라이츄까지 같이 찝어낼 수 있는 식별자가 있어야 한다.
3. 영속성으로 존재하는 다수(둘 이상)의 인스턴스들의 집합체여야 한다.
포켓몬이라는 엔터티 안에는 다수의 포켓몬들이 인스턴스로 들어가있고, 이 인스턴스가 세대에 따라서 추가될 수는 있지만(새 세대 나오면 전국도감 번호 늘어남) 포켓몬의 타입이 일부(혹은 전체) 바뀌는 걸 제외하면 포켓몬의 도감 번호나 키같은건 안 바뀐다. 그러니까 피카츄의 도감번호가 뜬금없이 25번에서 다른걸로 바뀌진 않을 거 아뉴. 지역도감 번호는 별개지만 전국도감 번호는 안바뀐다. 영속성으로 존재하는 자료라는 건 이런 식으로 장기간 유지되는 자료를 의미한다.
4. 업무 프로세스에 의해 이용되어야 한다.
이건 또 무슨 소리고? 만들었으면 쓰라 이 얘기. CRUD 중 한 과정에라도 써먹어야 한다. CRUD 매트릭스라는걸 쓴다는데... 아무튼 여기서 어느 한 부분에라도 안 쓰는 건 이걸 써야 하는데 안 쓴거거나 필요없는거거나 둘 중 하나다.
5. 반드시 속성이 필요하다.
ERD에서 엔터티를 만들때 보통 스키마도 같이 정한다. 스키마는 또 나중에 다룰 수 있으면 다루겠지만 엔터티에 들어가는 인스턴스들이 뭐고 어떤 애고 제약사항은 뭐가 있는지(예: 빈칸이면 안됨)를 명시하는거다. 엔터티를 어떤 '것'이라고 했는데, 어떤 '것'이 존재하기 위해서는 그게 뭔지를 정의해줘야 한다. 왜 우리 SQL에서 표 만들때 CREATE TABLE문만 달랑 쓰지 않고 그 안에 칼럼 타입 칼럼 타입 이렇게 쓰잖아요.
6. 주 식별자만 있고 속성이 없는 엔터티는 바람직하지 않다.
이건 또 뭔 소리여? 여러분들 게시판에 글 번호만 있고 글 제목이랑 내용 없으면 어때요? 이게 게시판임? 아니죠. 여기서 주식별자라는 건 PK, 그니까 프라이머리 키를 얘기하는건데 PK는 데이터베이스에서 유일한 행을 찝어낼 때 사용하는 키임. 이건 임의로 번호를 붙일 수도 있고(사번이나 학번같은거) AUTO_INCREMENT 속성을 주거나 할 수도 있는데, 이 번호만 있으면 안된다는 얘기다. 위에 예시로 든 게시판이라면 글 번호 말고 제목, 본문, 댓글 개수 이런 것들도 포함해야 한다는 얘기.
7. 다른 엔터티와 적어도 하나 이상의 관계를 가져야 한다.
물론 독고다이여야 하는 엔터티도 있다. 통계성 엔터티, 코드성 엔터티, 시스템 처리용 엔터티가 그 예시인데 얘네 빼고는 전부 다른 엔터티와 적어도 하나 이상의 관계를 가져야 한다. 사람은 혼자서 못 살아요. 근데 여기에 포켓몬을 예시로 들기가 대단히 애매한데, 포켓몬 중에도 진화 안 하는 포켓몬이 있음. 개중에도 폼체인지는 되는 포켓몬이 있긴 하지만 그것도 없는 포켓몬도 있다. 에몽가라던가.
어떤 '것'이 존재하기 위해서는 이게 뭔지를 정의해야 하고, 다른 '것'들과 관계를 맺어야 한다. 에몽가는 진화를 하지 않지만 어쨌든 야생 포켓몬으로 나와서 트레이너가 잡을 수 있는것처럼.
변수도 그렇지만 엔터티 이름 지을때 김엔터티 박엔터티 이따구로 짓지 말자. 나도 내 포켓몬 이름 말고는 장난식으로 안 짓는다. 포켓몬 이름은 막 짓는 양반이