2012-11-13 5 views
2

하나의 테이블에 여러 모델을 사용하는 것이 가능합니까?하나의 테이블에 대해 다른 모델

나는 여러 유형의 "사람"(교사, 학생, 직원, 회사)이 있으며 같은 테이블에 저장하려고합니다. 그들은 모든 개인 데이터를 공통으로 갖고 있지만 다른 관계 (예 : 학생 -> 회사, 교사 -> 방 및 기타), 추가 정보 (예 : 회사 이름 : 회사 이름, 교사 : 교육) 등이 있습니다.

이러한 경우에 대한 유용한 정보를 얻는 것이 좋습니다.

답변

3

정말 간단합니다!

/** 
* @ORM\Entity 
* @ORM\InheritanceType("JOINED") 
* @ORM\DiscriminatorColumn(name="discr", type="string") 
* @ORM\DiscriminatorMap({"teacher" = "Teacher"}) 
*/ 
class Person 
{ 
    /** 
    * @ORM/Id 
    **/ 
    private $id; 
    /** 
    * @ORM/Column 
    **/ 
    private $name; 
    //setters getters and all the stuff 
} 

을 그리고 Teacher.php 파일 :

/** 
* @ORM\Table() 
* @ORM\Entity() 
*/ 
class Teacher extends Person 
{ 
    private $salary; 
} 

가 성공의 열쇠는 두 주석 위치 : 같은 기관을해야

@ORM\DiscriminatorColumn(name="discr", type="string") 
@ORM\DiscriminatorMap({"teacher" = "Teacher"}) 

먼저 말하고있다 ORM 무엇 열이 교사인지 여부를 확인하는 데 사용됩니다. 두 번째는 기본 Person 클래스를 확장하는 클래스를 말하고 전에 언급 한 column i에 무엇을 넣어야 하는지를 알려줍니다.그렇게하면 두 개의 테이블이 생기지 만 Teacher에서는 교사 엔티티에 추가하는 데이터 만 가져옵니다.

일반적으로 ORM을 사용할 때 객체 추상화 수준을 생각해야하며 DB (음, 그건 완전히 사실이 아니지만 일반적인 생각입니다 :) :)

+0

예! 고마워, 내가 정확히 찾고 있었던거야. – Ueli

1

권장하지 않습니다. 여기에 내가 하지이 작업을 수행하는 이유를 생각할 수있는 몇 가지 이유는 다음과 같습니다

교사와 학생들은 ID의 동일한 세트를 공유하는 경우, 무슨 일이 학생의 ID를 사용하여 교사를로드하고, 추가로 사람을 중지하는 것입니다
  • 가치 "급여"필드? 이 액세스를 제한 할 수는 있지만 사용자 지정 리포지토리 또는 기타 수정이 필요할 수 있습니다.
  • 교사가 급여를 받아야한다고 가정 해 봅시다. 학생과 교사가 동일한 테이블을 공유하면 데이터베이스는 학생에게 월급을주지 않고 해당 제약 조건을 적용 할 수 없습니다.
  • 학생에게는 월급이 없지만 데이터베이스는 어쨌든 해당 필드의 공간을 할당해야 할 수 있습니다.

IBM은 mapping inheritance in relational databases에 관한 훌륭한 게시물을 보유하고 있으며이 유형의 모델을 구현할 때 여러 번 언급했습니다. 그들은 (1) 하나의 테이블을 사용하여 모든 클래스 (제안한 방법), (2) 자식 클래스에 별도의 테이블 사용, (3) 모든 클래스에 대해 별도의 테이블 사용 등의 세 가지 메소드를 참조하십시오. 결국, 개인적 선호도에 따라 다르지만 일반적으로하는 방식은 모든 클래스의 모델을 만드는 # 2와 # 3의 혼합이지만 하위 클래스의 부모 클래스에 대한 액세스를 제한합니다. 대신 부모 데이터에 액세스하는 바로 가기 메서드를 작성하십시오. 이것을 고려하십시오 : 나는 상황이 요구하는 내용에 따라, 단순히 교사로 교사를 치료하거나, 사람으로 할 수 있기 때문에

class Person 
{ 
    private $id; 
    private $name; 

    public function getId() 
    { return $this->id; } 

    public function getName() 
    { return $this->name; } 
    public function setName($name) 
    { return $this->name; } 
} 

class Teacher 
{ 
    private $id; 
    private $person; // reference to Person table 
    private $salary; 

    public function getId() 
    { return $this->id; } 

    private function getPerson() 
    { return $this->person; } 

    public function getSalary() 
    { return $this->salary; } 
    public function setSalary($salary) 
    { $this->salary = $salary; } 

    public function getName() 
    { return $this->getPerson()->getName(); } 
    public function setName($name) 
    { $this->getPerson()->setName($name); } 
} 

나는 보통이 방법을 선택합니다. 그래서 내가 두 페이지가 있다고 가정 해 봅시다 : 그냥 인쇄 모든 사람의 이름을 출력합니다 하나 (교사 및 학생), 그리고 하나를 교사와 급여 :

// Assume: 
// $people = $this->getDoctrine()->getEntityManager()->getRepository("MyBundle:Person")->findAll() 

{% for person in people %} 
    {{ person.name }} 
{% endfor %} 


// Assume: 
// $teachers = $this->getDoctrine()->getEntityManager()->getRepository("MyBundle:Teacher")->findAll() 

{% for teacher in teachers %} 
    {{ teacher.name }} makes ${{ teacher.salary }} 
{% endfor %} 
관련 문제