문제

내용주 작은 사무실 공급 회사가 스위칭 공급업체 및 내가 찾는 것을 통해 그들의 전자 콘텐츠를 올 강력한 데이터베이스 schema;우리의 이전 스키마가 꽤 많이 그냥 버려지 않고 함께 모든 생각에서 모두,그것은 매우 많이 주도하는 견딜 수 없는 데이터 모델로 손상,일치하지 않는 정보입니다.

새로운 공급업체의 데이터보다 훨씬 더 오래된 중 하나,하지만 데이터의 것 hypernormalized.예를 들어,그들의 제품 카테고리 구조는 5 단계:마스터학과,부서,클래스를,제품 블록입니다.또한 제품의 콘텐츠 차단은 긴 설명이 검색 조건과 이미지에 대한 이름은 제품(의 아이디어 제품 블록을 포함 제품의 모든 변화-예를 들어,특히 펜에 올 수도 검은색,파란색 또는 빨간색 잉크;이러한 모든 항목은 기본적으로 같은 것,그래서 그들은 적용하는 하나의 제품 블록).에서 데이터를 받았어,이것은으로 표시되는 제품이블(I 이 말하는"표"그러나 그것은 평평한 파일 데이터로)가 참조하여 제품 블록의 고유 ID 입니다.

내가 노력하고 있으로 올 견고한 스키마에 맞게 데이터 나비 때문에,나는야 그것을 로드하는 비교적 빨리,그리고 데이터들이 내게 주지 않는 것을 일치 데이터의 유형은 그들이 제공하는 데모에서 그들의 샘플 웹사이트(http://www.iteminfo.com).어떤 경우에,내가지 않고 다시 사용하는 프레젠테이션 구조는 그래서 그것은 논쟁점,그러나 나는 검색을 얻을 수있는 사이트의 몇 가지 아이디어를 어떻게 구조화하는 것들입니다.

내가 모르는 것입을 해야 하는지 아닌지를 유지 데이터에서는 이 형식 또는 예:통합 마스터/학과/클래스/서브 클래스로는 하나의"종류",테이블을 사용하여 자신을 참조하는 관계는 링크의 제품 블록(제품 블록 별도 보관해야로 그것은"카테고리는"이와 같이,하지만 그룹의 관련 제품을 제공하고).현재,제품 블록 테이블을 참조 하위 테이블이 변경"category_id 면"나는 통합합니다.

나는 아마를 만드는 것 전자 상거래를 만들이 데이터의 사용으로 루비 레일(또는 그 내 계획에서 어떤 율)그래서 나는 걸 나중에거나 부풀 응용 프로그램-어쩌면 내가 그것을 너무 많이 생각했지만 오히려 미안한 것보다 안전;우리의 이전 데이터 되었다고 비용이 회사의 수천 수만 달러를 잃 판매 때문에 일관성이 없고 부정확한 데이터이다.또한 난에서 휴식 레일을 조금 규칙을 확인해서는 데이터베이스에 견고하고 적용하는 조건(나는 계획에 그것을 하고 있는 응용 프로그램 수준에서,너무),그래서 그게 무언가를 생각해야합니다.

어떻게 당신은 낚시 도구 상황이 같은가?유지 하는 마음에 나는 데이터를 로드할 이미 평지에서 파일을 흉내내는 테이블의 구조물(나는 문서를 말하는 열이는 그 무엇을 참조 설정);나가려고 결정할 경우를 유지해야로 그들을 정규화은 현재와 같은 경우,또는 나는 찾아야 한 통합;내가 알고 있어야의 각 방법이 어떻게는 방법에 영향을 미칠 것입니다 나는 프로그램을 사용하여 사이트 레일 이후 할 경우 결합이있을 것이다,근본적으로 4 개의 범주에는 하나의 테이블이지만,확실히 보인다고 보다 더 쉽게 관리할 수 있습니다 별도의 테이블에 대한 각각의 수준을,이후 외에 하위 클래스(는 직접 링크를 제품 블록)없 을 제외하고 아무것도 표시는 다음의 수준의 범주니다.나는 항상 손실을"최상의 방법"을 처리하는 데이터이 나는 알아 말의"정상화될 때까지 그것을 아픈,다음 비정규화하여 작동 할 때까지"그러나 나는지 그것을 구현하기 위해 지금까지.

도움이 되었습니까?

해결책

내가 선호하는 것"hypernormalized"접근 방식을 통해 비정상 데이터 모델을 제공합니다.자기 표를 참조하 당신이 언급할 수 있습의 수를 줄이고 단순화하는 삶에서 어떤 방법으로,그러나 일반적으로 이 유형의 관계로 까다로운 일이 될 수 있습니다.계층 쿼리가 고통으로 매핑을 개체 모델이(갈 것을 결정하는 경우에 당신은 경로).

의 몇 가지 여분의 조인을 해치지 않고 응용 프로그램의 유지 관리성을 향상시켜준다.지 않으면 성능 저하로 인한 과도한 번호의 결합,선택하는 것입니다 남기는 것처럼 그들이 있습니다.추가 보너스로 이러한 수준의 테이블이 필요한 추가 기능을 추가,당신은 문제가 발생하기 때문에 당신 합병으로 그들 모두는 자기를 참조하는 테이블.

다른 팁

나는 부모-자식 계층에 대한 자기 참조 테이블 구조에 대한 비판에 전적으로 동의하지 않습니다. 링크 된 목록 구조는 UI 및 비즈니스 계층 프로그래밍이 대부분의 경우 더 쉽고 유지 관리 가능합니다. 링크 된 목록과 트리는 UI 및 비즈니스 계층이 일반적으로 구현 될 언어 로이 데이터를 표현하는 자연스러운 방법이기 때문입니다.

이러한 구조에 대한 데이터 무결성 제약 조건을 유지하기가 어렵다는 비판은 완벽하게 유효하지만 간단한 솔루션은 더 강한 점검 제약 조건을 호스팅하는 폐쇄 테이블을 사용하는 것입니다. 폐쇄 테이블은 트리거로 쉽게 유지 관리됩니다.

트레이드 오프는 UI 및 비즈니스 계층 코드에서 훨씬 덜 복잡하기 위해 DB (폐쇄 테이블 및 트리거)에서 약간의 복잡성입니다.

내가 올바르게 이해하면 별도의 테이블을 가져 와서 자체 참조 FK와 함께 단일 테이블에 보관 된 계층 구조로 바꾸고 싶습니다.

이것은 일반적으로보다 유연한 접근법 (예 : 다섯 번째 레벨을 추가하려는 경우)이지만 SQL 및 관계형 데이터 모델은 MS SQL 서버 CTE와 같은 새로운 구문에서도 이와 같은 링크 된 목록과 잘 작동하지 않습니다. 분명히 CTE는 훨씬 나아졌습니다.

제품이 항상 계층의 네 번째 수준에 있어야하는 것처럼 물건을 시행하는 것은 어렵고 비용이 많이들 수 있습니다.

당신이 이런 식으로하기로 결정했다면, Joe Celko 's를 확실히 확인하십시오. Smarties 용 SQL, 나는 SQL로 계층 구조를 모델링하고 작업하는 것에 관한 섹션을 두 개라고 생각합니다.Joe Celko의 나무와 Smlies for Smarties의 Trees and Hierrarchies).

Normalization 데이터 무결성, 즉, 각 정상적인 형태는 데이터가 일관되지 않는 상황의 수를 줄입니다.

일반적으로 denormalization 더 빠른 목표가 있습니다 querying, 그러나 공간이 증가하고 증가합니다 DML 시간, 그리고 마지막으로 데이터를 일관되게 만드는 노력이 증가했습니다.

하나는 일반적으로 코드를 더 빨리 씁니다 (코드가 빠르지 않고 더 빨리 씁니다). 데이터가있는 경우 코드가 오류가 덜 발생합니다. normalized.

자체 참조 테이블은 거의 항상 정규화 된 테이블보다 쿼리에 훨씬 더 나빠지고 성능이 나빠질 수 있습니다. 하지 마십시오. 그것은 당신이 더 우아하다고 생각할 수도 있지만, 그것은 데이터베이스 설계 기술이 아니며 매우 열악한 것입니다. 개인적으로 당신이 묘사 한 구조는 나에게 과도한 정규화되지 않은 소리가 좋지 않습니다. 적절하게 정규화 된 데이터베이스 (기본 값뿐만 아니라 기본 값, 트리거 (복잡한 규칙에 필요한 경우) 및 데이터 검증 제약 조건이 적합한 데이터베이스도 일관되고 정확한 데이터를 갖는 것으로 훨씬 더 가능성이 있습니다. 나는 데이터베이스가 규칙을 시행하는 것에 동의합니다. 아마도 규칙이 적절한 장소에서 시행되지 않았고 사람들이 쉽게 돌아올 수 있었기 때문에 마지막 응용 프로그램이 잘못된 데이터를 가진 이유의 일부일 것입니다. 응용 프로그램도 확인해서는 안됩니다 (예를 들어 Datbase가 삽입에서 실패하지 못하는 데 유효하지 않은 날짜조차 없습니다). 당신의 재 설계 이후, 나는 완벽하게 일반적인 정규화 된 구조를보다 우아하게 보이게하는 것보다 필요한 제약 조건을 설계하고 올바른 데이터 유형 (예를 들어 문자열 데이터로 저장하지 마십시오)을 선택하는 데 더 많은 시간과 노력을 기울일 것입니다.

나는 가능한 한 모델에 가깝게 가져올 것입니다 (가능하다면 평평한 버전이 아닌 스키마와 일치하는 파일을 얻을 것입니다). 데이터를 모델로 직접 가져 오면 내부 응용 프로그램의 모델로 변환 된 가정을 중단하기 위해 보내는 데이터가 시작되면 어떻게됩니까?

데이터를 가져오고, 정신 검사를 실행하고, 가정이 위반되지 않은지 확인하는 것이 좋습니다. 그런 다음 응용 프로그램 별 모델이있는 경우 응용 프로그램에서 최적의 사용을 위해이를 바로 변환하십시오.

거절하지 마십시오. Denormalizate를 통해 좋은 스키마 디자인을 달성하려는 것은 뉴욕에서 멀어지면서 샌프란시스코에 도착하는 것과 같습니다. 어떤 길을 가야하는지 말하지 않습니다.

당신의 상황에서, 당신은 정규화 된 스키마가 원하는 것을 알아 내고 싶습니다. 소스 스키마를 주로 기반으로 할 수 있지만 데이터의 기능 종속성 (FD)이 무엇인지 배워야합니다. 소스 스키마 나 평평한 파일은 모든 FD를 귀하에게 공개 할 수 없습니다.

정규화 된 스키마의 모습을 알면 이제 필요에 맞는 스키마를 설계하는 방법을 알아 내야합니다. 스키마가 완전히 정규화 된 것보다 다소 적습니다. 그러나 평평한 파일의 데이터와 내림진 스키마의 데이터 간의 변환을 프로그래밍하는 데 어려움을 겪을 수 있습니다.

당신은 당신의 회사의 이전 스키마는 불일치와 부정확성으로 인해 수백만 달러의 비용이 듭니다. 스키마가 정규화 될수록 내부 불일치로부터 더 많은 보호를받습니다. 이것은 당신이 부정확성에 대해 더주의를 기울일 수있게 해줍니다. 일관되게 잘못된 일관된 데이터는 일관되지 않은 데이터만큼 오해의 소지가있을 수 있습니다.

당신의 상점 (또는 당신이 구축하는 것이 무엇이든, 그에 대해 명확하지 않음)는 항상이 공급 업체의 데이터를 사용할 것입니까? 공급 업체를 변경하거나 다른 공급 업체를 추가 할 수 있습니까?

그렇다면 만나는 일반 스키마를 설계하십시오 당신의 벤더 데이터를 필요로하고 매핑합니다. 개인적으로 나는 차라리 자체 참조 범주 (계층 적) 테이블의 (엄청나게 작은) '고통'을 겪고 있습니다. 또는 단지 세 가지가있는 제품 라인을 소개했습니다 ...

나를 위해, 진짜 질문은 다음과 같습니다. 모델에 더 잘 맞는 것은 무엇입니까?

튜플과 목록을 비교하는 것과 같습니다.

  1. 튜플은 고정 된 크기이며 이질적입니다. "초본화"됩니다.
  2. 목록은 중재 크기이며 균질합니다.

목록이 필요할 때 튜플이 필요할 때 튜플을 사용합니다. 그들은 근본적으로 서버 다른 목적을합니다.

이 경우 제품 구조는 이미 잘 정의되어 있습니다 (그리고 나는 변하지 않을 것이라고 생각합니다) 그러면 나는 "튜플 접근"을 고수 할 것입니다. 목록의 실제 전원/사용 (또는 재귀 테이블 패턴)은 필요할 때입니다. 확장하다 BOM 또는 계보 나무와 같은 임의의 깊이.

필요에 따라 일부 데이터베이스에서 두 가지 접근 방식을 모두 사용합니다. 그러나 재귀 패턴의 "숨겨진 비용"도 있습니다.이 패턴은 모든 ORM (AR에 대해 확실하지 않음)이 잘 지원하지 않는다는 것입니다. 많은 최신 DBS는 "Join-Stroughs"(Oracle), 계층 ID (SQL Server) 또는 기타 재귀 패턴을 지원합니다. 또 다른 접근법은 세트 기반 계층을 사용하는 것입니다 (일반적으로 트리거/유지 보수에 의존). 어쨌든 사용 된 ORM이 재귀 쿼리를 잘 지원하지 않으면 수동 쿼리/뷰 생성 또는 트리거와 같은 관리 측면에서 DB 기능을 직접 사용하는 추가 "비용"이있을 수 있습니다. 펑키 한 ORM을 사용하지 않거나 Ibatis와 같은 논리 분리기를 사용하는 경우이 문제도 적용되지 않을 수 있습니다.

성능에 관한 한, New Oracle 또는 SQL Server (및 기타) RDBM에서는 매우 비교하여 내 걱정이 가장 적어야합니다. 그러나 RDBMS 및 휴대 성 문제에 사용할 수있는 솔루션을 확인하십시오.

자체 참조 테이블을 갖는 옵션 만 고려할 때 데이터베이스에 계층 구조를 소개하지 않는 것을 추천하는 모든 사람. 이것이 데이터베이스에서 계층을 모델링하는 유일한 방법은 아닙니다. 재귀 쿼리를 사용하지 않고 더 쉽고 빠른 쿼리를 제공하는 다른 접근 방식을 사용할 수 있습니다. 계층에 큰 노드 (카테고리) 세트가 있다고 가정 해 봅시다.

set1 = (node1 node2 node3 ...)

이 세트의 모든 노드는 다른 노드 또는 중첩 세트를 포함하는 다른 세트 자체가 될 수 있습니다.

node1 = (node2 node3 = (node4 node5 = (node6) node7)))))

자, 어떻게 우리가 그것을 모델링 할 수 있습니까? 각 노드가 포함 된 노드의 경계를 설정하는 두 가지 속성을 갖도록합시다.

노드 = {id : int, min : int, max : int}

계층 구조를 모델링하려면 그에 따라 최소/최대 값을 할당합니다.

node1 = {id = 1, min = 1, max = 10}
node2 = {id = 2, min = 2, max = 2}
node3 = {id = 3, min = 3, max = 9}
node4 = {id = 4, min = 4, max = 4}
node5 = {id = 5, min = 5, max = 7}
node6 = {id = 6, min = 6, max = 6}
node7 = {id = 7, min = 8, max = 8}

이제 Set/Node5의 모든 노드를 쿼리하려면 :

n을 선택하여 노드에서 n으로 n, n, 노드로 s로
여기서 s.id = 5 및 s.min <n.min 및 n.max <s.max

많은 레코드가 영향을 받기 때문에 새 노드를 삽입하거나 계층 구조 내에서 일부 노드를 이동하려는 유일한 리소스 소비 작업은 계층 자체가 자주 변경되지 않기 때문에 괜찮습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top