2009-10-21 3 views
1

비정규 화 또는 테이블 계층 관계와 관련된 모범 사례에 대한 질문이 있습니다.SQL/MySQL 구조 (비정규 화 또는 관계형 유지)

예를 들어 사용자가 주문에 대해 결제 할 수있는 앱이 있다고 가정 해 보겠습니다. orders 테이블에 주문 정보를 저장하고 지불이라는 지불 테이블을 가지고 있습니다. Payments에는 orders 테이블에 대한 외부 키가 있습니다.

내가 신용 카드, 수표 또는 페이팔로 지불 할 수 있다고 가정하고 지불에 대한 정보를 저장하려고합니다.

제 질문은 다른 지불 데이터와 지불 테이블 간의이 관계를 처리하는 가장 좋은 방법입니다. 지불 유형에는 모두 서로 다른 데이터가 있습니다. 그래서 나는 지불 테이블을 비정규 화하고 신용 카드, 수표 및 페이팔 정보 필드를 거기에 넣은 다음 필요에 따라 필드를 사용합니다. 또는 지불 유형을 지정하고 자신의 테이블에 정보를 저장할 수 있지만 올바른 신용 카드, 수표 또는 페이팔 정보 테이블에서 데이터를 가져 오려면 응용 프로그램 수준에서 논리를 사용해야합니다.

+0

각 지불 유형에 대해 저장해야하는 정보는 어떻게 다릅니 까? 지불을 위해 나는 일반적으로 지불 유형 (수표, CC, 페이팔 등)과 수표 번호, 신용 카드 승인 번호, 페이팔 거래 번호 등 단일 DocumentID 열을 저장합니다. –

+0

지불은 단지 쉬운 예입니다. 이 유형의 실제 사용량은 유형 당 약 20 개의 고유 한 열이있는 훨씬 더 복잡합니다. – Jestep

답변

1

데이터베이스를 정규화 된 상태로 유지하도록 선택했습니다.

하지만 내가 올바른 신용 카드에서 데이터를 얻을 테이블을 확인하거나 페이팔 정보에 응용 프로그램 수준에서 논리를 사용해야합니다 ...

당신은 논리를 사용해야합니다 (또는 적어도 매핑). 테이블에서 데이터를 가져올 테이블 또는 액세스 할 테이블의 필드.

0

그래서 나는 테이블을 테이블을 비표준으로 만들고 신용 카드를 넣고 확인하고 페이팔 정보 필드와 을 입력 한 다음 필요에 따라 필드를 사용하기 만하면됩니다.

예. 그러나 이것은 "비정규 화"가 아닙니다. 클라이언트 테이블에 주문 정보를 저장하면 비정규 화됩니다. 지불 테이블의 지불을 정확하게 설명하기 위해 Nullable 컬럼을 추가하는 것은 아닙니다.

+0

nullable 열을 갖는 것이 일부 비정규 화 레벨을 나타낼 것이라고 주장 할 수도 있습니다. –

+0

어떤 정규화 규칙을 위반했는지는 확실하지 않지만 지불 테이블의 열은 해당 지불과 관련이 없으며 어느 정도의 비정규 화를 나타냅니다. –

1

비정규 화 된 상태로 유지 한 다음 다시 데이터를 다시 볼 수 있도록 만드는 방법은 무엇입니까? 당신은 두 세계에서 최고의 것을 얻습니다. IIRC, MySQL은 버전 5에서 뷰를 도입했습니다.

0

ORM 도구와 마찬가지로 서브 클래스 별 아이디어를 사용할 수 있습니다. 이 경우 지불 테이블에 대한 각 쿼리에 대한 조인이 필요하지만 ...

각 지불 유형에 대한 테이블을 만들어 신용 카드 지불 및 수표 지급 테이블을 갖게하십시오. 공통 필드는 지급 테이블에 있으며 특정 필드는 하위 테이블에 있습니다. 하위 테이블 기본 키는 지불 테이블의 ID에 대한 외래 키입니다.

새 지불을 추가하려면 먼저 지불 필드에 공통 필드를 삽입하고 생성 된 ID를 가져온 다음 특정 필드를 특정 서브 테이블에 삽입해야합니다.

쿼리하려면 지불 테이블로 서브 테이블을 결합해야합니다. 뷰를 사용하면 쉽게 만들 수 있습니다.

이렇게하면 데이터베이스는 여전히 정규화되고 널 열이 없습니다.

0

부분적으로는 사용중인 프레임 워크 (있는 경우)에 따라 다릅니다. 예를 들어, Ruby on Rails 방식은 일반적으로 지불 테이블에 지불 유형을 저장 한 다음 각 지불 유형 (PayPal, 신용 카드 등)별로 다른 테이블을 사용하는 것입니다.

다른 테이블에서 동일한 데이터를 반복하는 경우 레일즈는 필요한 테이블 만 사용하여 같은 테이블에 모든 데이터를 저장하는 방법을 제공하지만 별도의 개체. 예를 들어, 당신은 abstract_payments 테이블을 가진 AbstractPayment 오브젝트를 가지지 만, 또한 AbstractPayment로부터 상속 받고 abstract_payments 테이블을 사용하는 PayPalPayment와 CreditCardPayment 오브젝트를 가질 수 있습니다. 지불 유형을 결정하는 데 필요한 것은 abstract_payments의 열로 어떤 유형인지 알려주는 것입니다 (아마도 문자열이지만 선택하면 정수가 될 수 있습니다). 이를 STI이라고합니다.

당신이 사용하는 프레임 워크/언어가 무엇이든, 똑같은 아이디어가 분명히 적용될 수 있습니다. 올바른 솔루션은 얼마나 많은 다른 지불 유형을 가지고 있느냐에 달려 있습니다.

0

최대한 정규화 된 상태로 유지하십시오. 완전 정규화 된 스키마의 성능이 응답 시간을 향상시키기 위해 비정규 화를 필요로 할 때만 비정규화할 수 있으며 응용 프로그램 내의 개별 쿼리와 관련된 특정 성능 문제를 처리하기 위해 경우에 따라이를 수행합니다.

이것은 복잡한 문제입니다. 데이터베이스 정규화에는 익숙한 도메인 지식과 해당 도메인 모델이 응용 프로그램 내에서 어떻게 조작되고 활용되는지 숙련 된 분석이 필요합니다. 성능을 비정규 화하는 것은 성능 문제가 발생하기 전에 예측할 수 있도록 응용 프로그램의 사용 패턴을 충분히 이해하고 있어야합니다. (실제로 프로덕션 환경에서 발생할 때까지 기다리는 것은 너무 늦습니다. 데이터베이스의 기본 스키마 변경이 매우 비쌉니다.) 그리고 어떤 비정규 화 기술 그들을 다루기 위해 사용하는 것.

0

는 다음과 같은 요인에 가중치를해야합니다 단일 테이블 SQL 쿼리가 어느 경우에 될 것입니다 얼마나 복잡한

  • 에 모든 데이터를 입력하는 경우

    • 얼마나 많은 공간이 낭비됩니다.

    다른 테이블을 사용하는 경우 조인을 사용해야합니다. 모든 것을 하나의 테이블에 넣으면 중요하지 않은 행을 "무시"하는 마술을 찾아야합니다 (모든 신용 카드 결제를 언제 찾을 수 있는지 말하기 : 쿼리는 다른 모든 것을 무시해야합니다) .

    특수한 데이터를 특별한 테이블로 옮기면 후자의 부분이 더 복잡해집니다.

  • 관련 문제