더 나은 데이터베이스 디자인은 무엇입니까?더 많은 테이블 또는 더 많은 열?[닫은]

StackOverflow https://stackoverflow.com/questions/59482

문제

이전 동료는 더 적은 수의 열이 있는 더 많은 테이블이 있는 데이터베이스가 더 많은 열이 있는 더 적은 수의 테이블이 있는 데이터베이스보다 낫다고 주장했습니다.예를 들어 이름, 주소, 도시, 주, 우편번호 등이 포함된 고객 테이블이 아닌열에는 이름 테이블, 주소 테이블, 도시 테이블 등이 있습니다.

그는 이 디자인이 더 효율적이고 유연하다고 주장했습니다.어쩌면 더 유연할 수도 있지만 그 효율성에 대해 언급할 자격은 없습니다.비록 그것이 더 효율적이더라도, 추가된 복잡성으로 인해 이러한 이점이 더 클 수 있다고 생각합니다.

그렇다면 더 많은 열이 있는 더 적은 수의 테이블보다 더 적은 수의 열이 있는 더 많은 테이블에 상당한 이점이 있습니까?

도움이 되었습니까?

해결책

나는 데이터베이스를 설계할 때 따르는 몇 가지 매우 간단한 경험 법칙을 가지고 있는데, 이는 이와 같은 결정을 내리는 데 도움이 될 수 있다고 생각합니다....

  1. 정규화를 선호합니다.비정규화는 모든 필수 절충 사항을 갖춘 최적화의 한 형태이므로 다음과 같이 접근해야 합니다. 야그니 태도.
  2. 데이터베이스를 참조하는 클라이언트 코드가 재작업으로 인해 클라이언트를 대대적으로 재설계할 필요가 없도록 스키마에서 충분히 분리되었는지 확인하십시오.
  3. 성능이나 쿼리 복잡성에 대한 명확한 이점을 제공하는 경우 비정규화를 두려워하지 마십시오.
  4. 스키마의 핵심을 비정규화하는 대신 뷰 또는 다운스트림 테이블을 사용하여 비정규화를 구현합니다. 데이터 볼륨과 사용 시나리오가 허용하는 경우.

이러한 규칙의 일반적인 결과는 초기 디자인이 중복 제거에 중점을 두고 열보다 테이블을 선호한다는 것입니다.프로젝트가 진행되고 비정규화 지점이 식별됨에 따라 전체 구조는 다른 귀중한 이점을 대신하여 제한된 중복성과 열 확산을 절충하는 균형을 향해 발전할 것입니다.

다른 팁

나는 더 많은 테이블을 선호한다고 주장하고 싶지만 특정 지점까지만 가능합니다.예시를 사용하여 사용자 정보를 USERS와 ADDRESS라는 두 개의 테이블로 분리하면 사용자당 여러 주소를 가질 수 있는 유연성이 제공됩니다.이에 대한 한 가지 확실한 적용은 별도의 청구서 수신 주소와 배송 주소를 가진 사용자입니다.

별도의 CITY 테이블을 갖는 것을 선호하는 주장은 각 도시의 이름을 한 번만 저장한 다음 필요할 때 참조하면 된다는 것입니다.이렇게 하면 중복이 줄어들지만 이 예에서는 과잉이라고 생각합니다.공간 효율적일 수 있지만 데이터베이스에서 데이터를 선택할 때 조인에 대한 대가를 치르게 됩니다.

테이블/열에 관한 질문이 아니라 정규화에 관한 질문처럼 들립니다.어떤 상황에서는 높은 수준의 표준화 (이 경우 "더 많은 테이블")은 훌륭하고 깔끔하지만 관련 결과를 얻으려면 일반적으로 많은 수의 JOIN이 필요합니다.그리고 데이터 세트가 충분히 크면 성능이 저하될 수 있습니다.

제프가 썼다 StackOverflow의 디자인에 관해 조금 설명하겠습니다.Jeff가 링크한 게시물도 참조하세요. 감히 오바산조.

완전히 정규화된 디자인(예: "추가 테이블")은 더 유연하고 유지 관리가 더 쉬우며 데이터 중복을 방지합니다. 즉, 데이터 무결성을 적용하기가 훨씬 더 쉬워집니다.

이는 정상화해야 하는 강력한 이유입니다.먼저 정규화한 다음 비정규화만 선택하겠습니다. 특정한 테이블 ~ 후에 성능이 문제가 되고 있는 것을 확인했습니다.

내 경험에 따르면 현실 세계에서는 매우 큰 데이터 세트가 있어도 비정규화가 필요한 지점에 도달하지 못합니다.

데이터베이스 취향에 따라 다릅니다.예를 들어 MS SQL Server는 더 좁은 테이블을 선호하는 경향이 있습니다.이는 또한 보다 '정규화된' 접근 방식입니다.다른 엔진은 그 반대 방향을 선호할 수도 있습니다.메인프레임은 이러한 범주에 속하는 경향이 있습니다.

각 테이블에는 기본 키로 고유하게 식별되는 엔터티와 관련된 열만 포함되어야 합니다.데이터베이스의 모든 열이 모두 동일한 엔터티의 특성인 경우 모든 열이 포함된 테이블 하나만 있으면 됩니다.

그러나 열 중 하나라도 Null일 수 있는 경우 이를 정규화하려면 기본 테이블에 대한 외래 키를 사용하여 각 Null 허용 열을 자체 테이블에 넣어야 합니다.이는 일반적인 시나리오이므로 보다 깔끔한 디자인을 위해 기존 테이블에 열보다 더 많은 테이블을 추가하는 것이 좋습니다.또한 이러한 선택적 속성을 자체 테이블에 추가하면 더 이상 null을 허용할 필요가 없으며 수많은 NULL 관련 문제를 피할 수 있습니다.

다중 테이블 데이터베이스는 이러한 일대일 관계 중 하나가 향후 일대다 또는 다대다가 될 수 있는 경우 훨씬 더 유연합니다.예를 들어 일부 고객에 대해 여러 주소를 저장해야 하는 경우 고객 테이블과 주소 테이블이 있으면 훨씬 쉽습니다.주소의 일부 부분은 복제하고 다른 부분은 복제하지 않아야 하는 상황을 실제로 볼 수 없으므로 별도의 주소, 도시, 주 및 우편번호 테이블이 약간 오버될 수 있습니다.

다른 모든 것과 마찬가지로:때에 따라 다르지.

열 수와 테이블 수에 관한 엄격하고 빠른 규칙은 없습니다.

고객이 여러 주소를 갖고 있어야 하는 경우 이를 위한 별도의 테이블이 적합합니다.City 열을 자체 테이블로 정규화해야 할 타당한 이유가 있는 경우에도 그렇게 할 수 있지만 일반적으로 자유 형식 필드이기 때문에 이전에는 본 적이 없습니다.

테이블이 무겁고 정규화된 디자인은 공간 측면에서 효율적이고 "교과서처럼" 보이지만 매우 복잡해질 수 있습니다.고객의 이름과 주소를 얻기 위해 12개의 조인을 수행해야 할 때까지는 괜찮아 보입니다.이러한 디자인은 그렇지 않습니다. 자동으로 가장 중요한 성능 측면에서 환상적입니다.쿼리.

가능하면 복잡성을 피하십시오.예를 들어, 고객이 주소를 두 개(임의로 많지 않음)만 가질 수 있는 경우 모든 주소를 단일 테이블(CustomerID, Name, ShipToAddress, BillingAddress, ShipToCity, BillingCity 등)에 유지하는 것이 합리적일 수 있습니다.

Jeff의 게시물은 다음과 같습니다. 주제에.

열 수가 적은 테이블을 사용하면 이점이 있지만 위의 시나리오를 살펴보고 다음 질문에 답해야 합니다.

고객이 2개 이상의 주소를 가질 수 있습니까?그렇지 않은 경우 별도의 주소 테이블이 필요하지 않습니다.그렇다면 별도의 테이블이 도움이 됩니다. 테이블에 더 많은 열을 추가하기가 더 어려워지는 상황에서 필요에 따라 더 많은 주소를 쉽게 추가할 수 있기 때문입니다.

첫 번째 단계로 정규화를 고려하고 있으므로 도시, 카운티, 주, 국가를 별도의 열로 사용하는 것이 더 나을 것입니다.오늘날의 DBMS-es와 함께 SQL 언어의 강력한 기능을 사용하면 나중에 다른 비정규화된 보기에서 데이터를 확인해야 할 경우 데이터를 그룹화할 수 있습니다.

시스템을 개발할 때 개선 사항이라고 생각되면 일부 부분을 '비정규화'하는 것을 고려할 수 있습니다.

이 경우에는 균형이 필요하다고 생각합니다.테이블에 열을 넣는 것이 합리적이라면 테이블에 넣고, 그렇지 않으면 넣지 마세요.동료의 접근 방식은 확실히 데이터베이스를 정규화하는 데 도움이 되지만 필요한 정보를 얻기 위해 50개의 테이블을 함께 조인해야 하는 경우에는 그다지 유용하지 않을 수 있습니다.

내 대답은 최선의 판단을 사용하는 것입니다.

여기에는 여러 가지 측면이 있지만 애플리케이션 효율성 관점에서 볼 때 모트 테이블이 때때로 더 효율적일 수 있습니다.DB가 작업을 수행할 때마다 여러 개의 열이 포함된 몇 개의 테이블이 있는 경우 잠금이 발생할 수 있으며 잠금 기간 동안 더 많은 데이터를 사용할 수 없게 됩니다.잠금이 페이지와 테이블(테이블은 아니길 바랍니다 :))로 에스컬레이션되면 시스템 속도가 어떻게 느려질 수 있는지 알 수 있습니다.

흠.

나는 그것이 워시라고 생각하며 특정 디자인 모델에 따라 다릅니다.몇 개 이상의 필드가 있는 엔터티를 자체 테이블로 확실히 제외하거나 응용 프로그램의 요구 사항이 변경됨에 따라 구성이 변경될 수 있는 엔터티를 확실히 제외합니다. 예를 들어 필드가 너무 많기 때문에 어쨌든 주소를 제외하겠습니다. '디 특히 다른 형식일 수 있는 외국 주소를 처리해야 할 가능성이 있다고 생각되면 그렇게 하십시오.전화번호도 마찬가지입니다.)

즉, 작동하게 되면 성능에 주의를 기울이십시오.크고 비용이 많이 드는 조인을 수행해야 하는 엔터티를 분리한 경우 해당 테이블을 원본으로 다시 회전시키는 것이 더 나은 설계 결정이 될 수 있습니다.

엄청난 이점이 있습니다 쿼리 가능한 한 적은 수의 열을 사용합니다.그러나 테이블 자체는 많은 수를 가질 수 있습니다. 제프 이것에 대해서도 뭔가를 말합니다.

기본적으로 쿼리를 수행할 때 필요한 것보다 더 많은 것을 요구하지 않도록 하십시오. 쿼리 성능은 요청하는 열 수와 직접적인 관련이 있습니다.

결정을 내리기 전에 저장하고 있는 데이터의 종류를 살펴봐야 한다고 생각합니다.주소 테이블을 갖는 것은 좋지만 여러 사람이 동일한 주소를 공유할 가능성이 높은 경우에만 가능합니다.모든 사람이 서로 다른 주소를 갖고 있는 경우 해당 데이터를 다른 테이블에 보관하면 불필요한 조인이 발생합니다.

도시 자체가 응용 프로그램에서 관심을 갖는 엔터티가 아닌 한 도시 테이블을 갖는 이점을 볼 수 없습니다.또는 사용자가 사용할 수 있는 도시 수를 제한하려는 경우.

결론은 효율성을 위해 촬영을 시작하기 전에 애플리케이션 자체를 고려해야 한다는 결정입니다.IMO.

데이터베이스를 디자인할 때 애플리케이션 요구 사항이 아닌 데이터의 의미에 최대한 가까워야 합니다!

좋은 데이터베이스 디자인은 20년 이상 변경 없이 유지되어야 합니다.

고객은 여러 주소를 가질 수 있으며 이것이 현실입니다.첫 번째 릴리스에서 애플리케이션이 하나의 주소로 제한된다고 결정했다면 중요한 것은 데이터가 아니라 애플리케이션의 디자인입니다!

쿼리를 단순화하려면 여러 열 대신 여러 테이블을 갖고 보기를 사용하는 것이 좋습니다.

대부분의 경우 데이터베이스 성능 문제는 쿼리의 복잡성이 아니라 네트워크 성능(한 행 결과가 포함된 체인 쿼리, 필요하지 않은 열 가져오기 등)에 관한 것입니다.

먼저, 테이블을 정규화하세요.이렇게 하면 중복된 데이터를 방지하고 검색할 데이터 행이 줄어들어 쿼리가 향상됩니다.그런 다음 조인 중인 정규화된 테이블로 인해 쿼리를 처리하는 데 시간이 오래 걸리는 지점(비용이 많이 드는 조인 절)이 발생하면 더 적절한 곳에서 비정규화하세요.

영감을 주고 기반이 탄탄한 답변을 많이 볼 수 있어 기쁩니다.

내 대답은 (불행히도) 다음과 같습니다.때에 따라 다르지.

두 가지 경우:* 수년 동안 사용되어 향후 많은 변경 사항에 적응해야 하는 데이터 모델을 생성하는 경우:더 많은 테이블과 더 적은 행, 매우 엄격한 정규화를 선택하세요.* 다른 경우에는 테이블이 없는 행이 많거나 테이블이 없고 행이 많은 중에서 선택할 수 있습니다.특히 이 주제를 비교적 처음 접하는 사람들에게는 이 마지막 접근 방식이 더 직관적이고 이해하기 쉬울 수 있습니다.

객체 지향 접근 방식과 다른 옵션 중에서 선택할 때도 마찬가지입니다.

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