2009-04-04 1 views
2

일반적으로 클래스를 설계하는 방법은 무엇입니까? 하나의 클래스 = 1 표. 다른 테이블에 외래 키를 포함하는 테이블은 어떻습니까?테이블 디자인을 기반으로 한 모델링 클래스

가정하자 나는이 다음 :

PersonTable 
--------------- 
person_id 
name 

PersonMapTable 
--------------- 
map_id 
type_id (fk) 
person_id 

PersonTypeTable 
------------------- 
type_id 
description 
parent_type_id 

AddressTable 
------------------- 
address_id 
address1 
address2 
city 
state 
zip 

AddressMapTable 
----------- 
address_map_id 
address_id 
person_id 

좋은 방법은 각 테이블을위한 클래스를 만드는 구성시겠습니까? 그렇다면 orm을 사용하지 않고 이러한 클래스를 데이터베이스에로드/저장하는 모범 사례는 무엇입니까? 간단한 코드 예제가 실제로 도움이 될 것입니다.

답변

3

테이블 당 하나의 개체가 반드시 좋은 디자인이라고 생각하지 않습니다. 모든 규칙에 맞는 하나의 크기를 제공하기는 어렵지만 오브젝트는 더 풍부하고 세분화 될 수 있습니다. 데이터베이스는 객체에 적용되지 않는 이유로 비정규 화 될 수 있습니다. 이 경우 표보다 많은 오브젝트가 있습니다. 1 및 1 : m 관계 :

귀하의 경우는 1이 포함됩니다

public class Person 
{ 
    // 1:m 
    private List<your.namespace.Map> maps; 
} 

public class Map 
{ 
    // 1:1 
    private your.namespace.Type; 
} 
+0

감사합니다. 다음과 같은 UI가 있다고 가정하십시오. Person_Type_Id, Person_Type 이름. Person person = new Person (Name, PersonType, PersonTypeId) 그리고 Person 생성자가 Map 객체를 생성하게 할 것인가? – zSynopsis

+0

UI? 우리는 끈기에 대해 이야기하고 있습니다. 그리고 "PersonType"? 디자인에 몇 가지 유형이 있습니까? 역할은 나와 같은 역할을합니다. 그렇다면 제안하는대로하지 않을 것입니다. – duffymo

+0

TypeTable (Value = id, Text = Type)에서 생성 된 목록 상자가있는 사용자 인터페이스가 있습니다. 5-10 인 유형 (이 숫자는 하루에 증가합니다)이 있습니다. – zSynopsis

1

난 당신이 많은 관계로 많은이 특히, 난 항상 테이블 당 클래스가 있음을 언급하지 않았다. 위의 테이블을 기반으로 나는 2 개의 클래스를 가질 것입니다 ... 왜 당신이 둘 다 id와 person_type_id를 가지고 있는지 확실하지 않습니다. 나에게 그들은 같은 것이지만 여기에는 클래스가 있습니다.

Person 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public List<PersonType> { get; set; } 
} 

PersonType 
{ 
    // I would discourage from using Type as property name as it is a keyword... 
    public string [Type] { get; set; } 
} 
+0

그래, 내가 실수 한거야. 감사합니다 – zSynopsis

+0

귀하의 환영합니다! 나에게 답을 표시 할 수 있니, 고마워! – bytebender

1

사용자가 데이터 입력 점원이 아니라면 일반적으로 유스 케이스/사용자 스토리에서 클래스를 설계하는 것이 좋습니다. 데이터베이스가 이미있는 경우에도 마찬가지입니다.

이유? 사용자가 자신의 일을 돕기 위해 소프트웨어를 기대하기보다는 소프트웨어를 사용하는 것이 자신의 직업이라고 가정하는 것은 너무 쉽습니다.

분명히 그들은 어느 시점에서 교차해야합니다. 나는 Fowler의 책이 시작하기에 좋은 곳이라는 데 동의한다. 그러나 나는 그가이 견해를 강화할 것이라고 생각한다.

클래스와 데이터베이스를 모두 얻는 데 도움이되는 모델링 퍼스펙티브가 필요한 경우에는 오브젝트 역할 모델링을 고려하십시오.

2

엔티티에 테이블을 매핑하는 경향이 있지만 대부분 어려운 규칙은 아닙니다. 때로는 문제의 특정 엔티티에 대한 저장소가 특정 엔티티를 둘러싼 일반적인 문제를 해결하는 것이 더 나은 경우가 있습니다. 즉, 결과적으로 엔티티로 존재해야하는 테이블이 없어도 다른 테이블을 처리하게됩니다. 나는 (종속 데이터가 항상 엔티티로 검색 할 필요가 매우 구체적인 계획 경우를 제외하고)하지 않을무엇

는 다른 개체의 속성으로 엔티티의 엔티티 또는 콜렉션을 설정합니다. 대신, 해당 엔티티는 ID를 통해 발견 할 수 있습니다. ID는 상위 엔티티의 특성이거나 상위 엔티티와 관련하여 연관된 저장소를 통해 발견 할 수 있습니다.

다른 엔터티의 하위 엔터티가 함께 번들로 묶일 필요가있는 경우 "info"도우미 클래스를 사용하여 필요한 모든 데이터를 함께 가져옵니다.예를 들어 엔티티 클래스 Widget이 있고 하위 개체 Part 개체가있는 경우 WidgetInfo 클래스를 만들고 속성으로 Widget 인스턴스를 포함하고 다른 속성으로 Part 개체 컬렉션을 포함합니다.

이렇게하면 모든 엔티티 클래스는 가능한 한 가벼운 상태로 유지되며 종속 데이터를로드해야한다고 가정하지 않습니다. 또한 엔터티 클래스에서 자식 개체 컬렉션을 만드는 경우 일반적으로 문제가되는 지저분한 ORM 영역으로 리포지토리 모델을 깨끗하게 유지합니다. ORM없이 수행하면 자식을로드 할 것인지 아닌지, 그리고 자식이로드되었거나로드되지 않았다고 가정 할 때의 지저분한 문제가 발생합니다.

0

ORM (Object-Relational Mapping)을 사용하려는 경우 테이블 디자인에 영향을 줄 수 있습니다. 예를 들어, Hibernate은 같은 트리에서 혼합 상속 매핑 전략을 선호하지 않습니다.

ORM을 사용하지 않는다고 특별히 명시 했으므로 전통적인 데이터베이스 디자인 주체를 따를 수 있습니다. 이는 일반적으로 세 번째 정규형 (read about database normalization here)으로 정규화 한 다음 성능 제약 조건 (read about denormalization here)을 충족시키기 위해 비정규 화하는 것을 클래스 당 하나의 테이블로 시작하는 것을 의미합니다.

ORM을 사용하지 않고 개체를로드하고 저장하는 방법에 대한 질문은 데이터 액세스 개체 (DAO 초)를 사용하는 것이 좋습니다.

public interface ICustomerDao 
{ 
    public void insert(Customer customer) throws CustomerDaoException; 
    public void update(long id, Customer customer) throws CustomerDaoException; 
    public void delete(long id) throws CustomerDaoException; 
    public Customer[] findAll() throws CustomerDaoException; 
    public Customer findByPrimaryKey(long id) throws CustomerDaoException; 
    public Customer[] findByCompany(int companyId) throws CustomerDaoException; 
} 

당신은 당신이 사용하는 언어를 지정하지 않았지만, 상관없이 유용 DAO에 대한 this example using Java generics을 찾을 수 있습니다 : 다음은 간단한 예입니다.

0

각 테이블에 대한 클래스를 만드는 것이 좋을까요? 그렇다면 에 대한 모범 사례는 무엇입니까? orm이없는 데이터베이스 등의 클래스를 다시로드하고 저장 하시겠습니까?

ORM을 사용 중입니다. 관계형 테이블에 오브젝트를 맵핑 중입니다. 사전 작성된 라이브러리를 사용하든 사용하지 않든 귀하의 전화입니다. 그렇지 않으면 기존 ORM의 모든 종소리와 휘파람을 사용하지 않아도된다.

이렇게하는 가장 일반적인 두 가지 방법은 ActiveRecord 패턴과 Data Mapper 패턴입니다. 각각에는 그것의 이점과 불리가있다.

ActiveRecord 패턴을 사용하면 속성이 테이블 열을 정의하는 클래스를 정의 할 수 있습니다. 이 클래스의 각 인스턴스는 데이터베이스의 행에 해당하며 새 인스턴스를 만들고 저장하여 데이터베이스에 새 행을 만듭니다. 여기에 대한 자세한 내용은 여기를 참조하십시오. http://en.wikipedia.org/wiki/Active_record_pattern

데이터 매퍼 패턴에서 각 테이블에 대한 테이블 개체를 정의하고 기존 클래스에 테이블의 열을 할당하는 매퍼 함수를 ​​작성합니다. SQLAlchemy는 기본적으로이 패턴을 사용합니다 (ActiveRecord 유형 확장 모듈이 있지만 SQLAlchemy의 기능을 다른 인터페이스에 적용합니다.)이 패턴에 대한 간단한 소개는 SQLAlchemy의 설명서 http://www.sqlalchemy.org/docs/05/ormtutorial.html에서 찾을 수 있습니다. 섹션 "표, 클래스 및 매퍼 모두 한 번에 선언적으로 만들기"라는 절에서 SQLAlchemy를 사용하여 ActiveRecord에 대해 설명합니다.

ActiveRecord 패턴은 설정하기가 쉽고 작업하기가 쉽고 데이터베이스를 명확하게 나타내는 클래스를 제공하므로 가독성 측면에서 이점이 있습니다. 부수적 인 이점으로, ActiveRecord 클래스의 선언적 성격은 데이터베이스 스키마에 대한 명확하고 명확한 문서화의 역할을합니다.

데이터 매퍼 패턴을 사용하면 데이터가 클래스에 매핑되는 방식을 훨씬 유연하게 지정할 수 있으므로 테이블과 클래스 간의 일대일 관계에 더 많이 묶이지 않아도됩니다. 또한 지속성 계층을 비즈니스 코드와 분리합니다. 즉, 필요할 경우 나중에 다른 지속성 메커니즘을 스왑 할 수 있습니다. 또한 데이터베이스를 백업 할 필요없이 클래스를보다 쉽게 ​​테스트 할 수 있음을 의미합니다.

SQLAlchemy의 매퍼 구성에 대한 자세한 내용은 http://www.sqlalchemy.org/docs/05/mappers.html을 확인하십시오. SQLAlchemy와 같은 라이브러리를 사용할 계획이 없다고해도, 문서는 클래스를 데이터베이스 테이블에 매핑 할 때 고려해야 할 몇 가지 옵션을 보여줍니다.

0

이 클래스에 대한 데이터베이스 관점에서의 접근 방식은 많은 코드를 빠르게 빠르게 만들 수 있습니다. 그러나이 코드의 좋은 부분은 어떤 용도로도 사용되지 않거나 심각한 변이가 필요할 수 있습니다. 즉, 디스플레이 및 워크 플로가 일치하지 않는 특정 클래스를 만들 수 있습니다.

먼저 앱, 사용자의 요구, 일반적인 워크 플로 등을 고려해보십시오. 실제로 실제로 사용할 수있는 것처럼 보이게 만듭니다 (예 : 디스플레이를 조롱하십시오).

디스플레이를 사용하고 필요에 따라 스토리지 (db 디자인)를 모델링하는 데 필요한 클래스에 집중하십시오. 대부분의 수업이 자연스럽게 디스플레이에 대한 솔루션을 제공하는 경향이 있으므로 직선 테이블 수업을 몇 번만 할 수있는 기회가 있습니다.

행운을 빈다.