The problem of subtypes
참조 : Java Persistence with Hibernate
객체에서는 상속이라는 것이 있는데 DB에는 그런게 없기 때문에 발생하는 문제입니다.
객체는 클래스라는 타입이 있고 이러한 타입이 상속되는 반면에 DB에 있는 Table은 type이 아니기 때문에 supertable 이나 subtable 같은 단어는 없습니다. 5장 5.1 "Mapping class inheritance"(p192)에서 이 문제에 대한 해결 방법이 나와 있습니다.
ck1.bmp
만약에 위와 같은 상속 구조를 DB로 표현하는 방법으로 책에서는 네가지 방법(크게 세가지)을 소개하고 있습니다.
1. Table per concrete class(with implicit polymorphism)
dk2.bmp상속의 특징 중에 상위 클래스의 속성을 물려 받는 특징은 살렸지만... 다형성은 이용하지 못하겠습니다. 또한 상위 클래스의 속성이 변하게 되면 이런 테이블들 또한 일일히 변하게 되어야 하기 때문에 난감할 수 있겠습니다.
다형성이 필요없고 상위 클래스의 변동이 거의 없는 경우에 사용할 수 있겠습니다.
2. Table per concrete class(with unions)
dk3.bmp매핑을 1번과는 조금 다른 방법으로 하지만 테이블의 구조는 1번과 거의 같은 구조의 스키마를 보이게 됩니다. 상위 클래스에 있는
속성들을 중복해서 선언하지 않고 <union-subclass> 태그를 이용해서 매핑 시킬 수 있습니다. 이 때
테이블의 주키도 역시 공유가 되기 때문에 같게 됩니다. 그리고 다형성을 이용할 수 있습니다.
3. Table per class hierarachy
ck2.bmp가장 단순하고 성능도 좋은 매핑 전략입니다. 아예 하나의 테이블 안에 넣어 뒀기 때문에 다형성을 사용할 수 있으며 표현하기도 간단합니다.
그런데 하위 클래스들의 속성들은 전부 nullable이어야 한다는 제약이 있습니다. 생각해보면 당연합니다. Employee에 대한 정보를 넣고 싶은데 PartTimeWorker에 대한 정보가 없다고 못 넣는 다는 건.. 좀.....그렇쵸. 그리고 WORKER_TYPE 과 같은 구분자가 필요한데요. 이건 객체에 표시하진 않고 DB에서만 사용됩니다.
그리고 주키 아닌 속성에 종속되는 컬럼 들이 있기 때문에 정규화를 만족시키지 못한다는 것 역시 단점입니다.
4. Table per subclass
ck3.bmp
상속을 외례키를 사용한 관계로로 표현하는 방법입니다. 3번의 정규화 문제가 해결 됐다는 것이 장점이고 다형성은 join을 사용해서 가능합니다. 구분자도 필요없게 되었습니다. 하지만 맵핑 설정하는 것이 조금 복잡하네요. ~.~ 그리고 복잡한 상속 구조에서의 성능이 굉장히 안좋은 것 같습니다.
이 들 여러 전략들 중에 어느것을 사용할 지는 그때 그때 다르겠지만 3번과 4번이 가장 자주 사용될 듯 한 기분입니다.