님의 질문을 쭈욱~ 읽어 보고 행여 도움이 될까 싶어서 글을 올립니다. 많은 DB를 직접 모델링 하실수록 나타나는 새로운 개체를 면밀히 관찰하심이 DB모델링 스킬의 레벨업을 직접적으로 경험하실 수 있으실 껍니다.
당구를 재미있게 배울때 사람 머리가 당구공처럼 보여진다죠? 전 당구를 잘 못처서 그런 경지에 오르지는 못했지만 DB모델링을 공부하시면 눈으로 들어오는 기하학적인 형상까지 어떻게 개채를 잡으면 DB속에 넣을까 고민하시게 될껍니다.
개체를 잡는 것이 중요합니당
>> 질문 1. 부모와 자식 엔티티를 확연히 나누는 기준이 있는지요?
>> 저같은 경우는 일단 엔티티를 놓으면 그냥 동물적으로
>> 이건 부모엔티티다, 자식엔티티다 감이 와서 그냥 그렇게 하거든요
>>
개체의 성질을 잘 파악하셔야 합니다. 많은 모델링을 통해서 거의 직관적으로 엔티티를 결정하고 관계를 맺지요. 그런다음에 부르기 쉽게 부모 엔티티 자식엔티티라고 쉽게 부르는 겁니다.
님께서도 우선 부모엔티티 먼저잡고 자식엔티티 먼저잡고 하지는 않으실껍니다. 개체를 먼저 잡고 개채간의 관계를 도출할때 그제서야 부모 자식간에 있는 엔티티가 생길껍니다.
편하게 말하자면 부모엔티티는 부모엔티티의 주키혹은 유일키가 다른 엔티티에 의해서 참조되어지는 엔티티를 말하는 걸껍니다.
자식엔티티는 1개 이상의 외래키를 가지는 엔티티라고 보시면 됩니다.
ERD를 보니 Team이 부모, Player가 자식 테이블이네요
>> 그리고 관계가 실선으로 되어 있는것은 종속적인 관계를 의미 한다고 합니다.
>> 종속적인 관계에는 existence dependent, identification dependent 이렇게 두가지가 있는데
>> 이 모델에서는 existence dependent는 아니지만 identification dependent랍니다.
>> 즉, 선수는 팀에 속해있지 않아도 존재할수 있기떄문에 existence dependent 가 아니고
>> 선수는 팀의 team-id 키 없이는 분간할 수 없기때문에 identification dependent라고 합니다.
>>
종속적인 관계는 자식테이블의 외래키로 쓰이는 값이 부모테이블의 주키 혹은 유일키에 꼭 나타나거나 NULL이어야 한다는 말을 뜻할껍니다.
문맥을 읽어보니 Foreign key Constraints FK가 NULL을 허용하면 existence dependent이고 (====> 이것은 지금은 어느팀에 있을지는 몰라도 Player를 등록할 수 있다는 것을 의미합니다. 나중에 부모테이블의 주키 혹은 유일키에 나타나 있는 값으로 UPDATE를 할 수 있음을 의미합니다)
Foreign Key Constraint의 정의에서 FK가 NULL을 허용하지 않으면 identification dependent이가 되는 걸껍니다. (===>이것은 Player를 등록하려면 반드시 팀이 우선 결정되어 있어야 함을 의미합니다. 나중에 UPDATE될때 되더라도 NULL이나 부모테이블의 주키 혹은 유일키를 참조하는 값이 자식테이블의 FK의 값으로 나타나 있어야 됩니다.)
님께서 만드신 테이블이 왜서 identification dependent이냐 하면 Player의 주키가 player_id + team_id로 되어 있기 때문입니다. 무엇보다도 주키를 구성하는 이 복합키의 값중 하나라도 미진하게 된다면(NULL이라면) 키의 요건에 해당되지 않기 때문에 기필코 team_id 의 FK constraint에 NOT NULL을 넣어 주실껏이기 때문입니다.
>> 질문 2. existence dependent, identification dependent 의 개념에 대해서는
>> 대충을 이해하겠는데, 특히 identification dependent 개념이 조금 모호합니다.
>> 이걸 조금 쉽게 설명해 주실수 있는지?
>>
>> 일단 여기까지고
===> 위의 설명에서 해결된것 같고요...
>> 이제 Physical layer 적인 관점(?)으로 질문을 드리면
>> 그림에서 보시다시 PLAYER의 team-id가 FK로 설정이 되어 있습니다.
>>
>> 질문 3. 이 관계를 어떻게 표현해야 하는지
>> PLAYER의 team-id 는 TEAM에 대해서 FK 로 되었다 로 표현하나요?
>> TEAM은 PLAYER의 team-id 를 FK로 가지고 있다고 표현해야 하는지?
>> 어느 엔티티의 관점에서 봐야할지 헷갈립니다.
Player 테이블은 크게 2개의 Key Constraint를 가지게 됩니다.
ALTER TABLE player
ADD CONSTRAINT player_comp_pk PRIMARY KEY(player_id, team_id);
ALTER TABLE player
ADD CONSTRAINT player_team_id_fk FOREIGN KEY(team_id)
REFERENCES team(team_id);
===> player 테이블은 team을 "참조"하는 외래키 team_id를 가지고 있습니다.
크게 2개라는 말은 보통 NOT NULL 제약조건은 CREATE TABLE에서 attribute를 정의하면서 NOT NULL를 같이 쓰기때문에 그렇게 쓴겁니다.
>> 질문 4. FK가 있기때문에 부모의 튜플들을 삭제할수 없다가 아니라
>> 이 관계를 DB스키마를 작성할때 FK constraint 를 걸어 줄때 정해주는
>> 것에 따라 정해진다는것이 맞는지요?
>> 이 질문은 지난 코멘트에서 거의 이해가 됬습니다.
>> 그럼 한가지, MySQL과 같이 FK 가 지원하지 않는 DB는
>> 이것을 프로그래머가 프로그램로직에서 FK constraint 을 고려해야
>> 한다는 것인가요?
님께서 말씀하신대로 FK를 정의할때 ON DELETE CASCADE 절을 다시면 부모 테이블의 tuple을 삭제할때 자식테이블에 FK로 그 값을 가진 튜플역시 사라지므로 엄밀히 말하면 FK가 있기때문에 부모의 튜플을 삭제할 수 없다는 아니겠지요. 즉 Constraint정의에 따라 다르나...
보통은 그렇게 이야기를 많이 합니다. ON DELETE CASCADE를 앵간해서는 안쓰니까요.
한번 정해진 키를 지우거나 바꾸는 것은 DB로서는 매우 신중하고도 조심스럽고 비용도 많이 들게 되니까요.
MySQL에서는 아직까지의 버전중에서는 참조무결성(reference integrity)를 지원해 주지 않는다고 알고 있습니다. 그만큼 DB운영면에서는 참조무결성을 유지하는 것이 비용이 많이 든다고 할 수 있을껍니다. 이러한 참조무결성을 보장하지 않는 DB에서도 application level에서 logic으로 구현해 줄 수 있습니다.
제가 말씀드리고 싶은것은 꼭 lock과 함께 구현해야 올바른 참조무결성을 보장받으실 수 있다는 겁니다.
예를 들어 다음과 같은 경우를 생각해 보실 수 있을껍니다.
부모테이블에서 한 행을 delete나 update하고자 할때 해당하는 자식테이블에서 그 delete나 update하려는 tuple의 key값으로 insert나 update를 못하도록 막기위해서 자식테이블에 lock을 걸어야 할 것입니다.
이와같은 경우를 고려하셔서 적절히 application level에서 FK를 잘 운용하신다면 DB 를 직접 건드리시지 않는 이상 참조무결성은 잘 유지될겁니다.
PS.
application level에서 FK를 관리하기란 참으로 힘들껍니다. 프로그래머 입장에서.. 성능면에서도 그다지 추천하지는 않습니다. 그래서 참조무결성이 지원되는 DB를 사용하는 것이 수월~ 합니다.(MySQL보다는 빠르지는 않을껍니다!!!)
MySQL에서 많은 FK로 역어저있는 DB를 프로그래밍하시기 보다는 상용DB가 낫겠죠.. 비용이 부담이 되신다면 PostgreSQL은 훌륭한 DB 일껍니다.
|