더 나은 데이터베이스 디자인은 무엇입니까 : 더 많은 테이블 또는 더 많은 열?
이전 동료는 각각 더 적은 수의 열이있는 더 많은 테이블이있는 데이터베이스가 각각 더 많은 열이있는 더 적은 수의 테이블이있는 데이터베이스보다 낫다고 주장했습니다. 예를 들어 이름, 주소, 도시, 주, 우편 번호 등의 열이있는 고객 테이블 대신 이름 테이블, 주소 테이블, 도시 테이블 등이 있습니다.
그는이 디자인이 더 효율적이고 유연하다고 주장했습니다. 아마도 더 유연 할 수도 있지만 효율성에 대해 언급 할 자격이 없습니다. 더 효율적이더라도 추가 된 복잡성이 이러한 이득을 능가 할 수 있다고 생각합니다.
그렇다면 더 적은 수의 열을 가진 적은 수의 테이블에 비해 적은 수의 열을 가진 더 많은 테이블에 큰 이점이 있습니까?
데이터베이스를 설계 할 때 따르는 매우 간단한 경험 법칙이 몇 가지 있는데, 이는 이와 같은 결정을 내리는 데 사용할 수 있다고 생각합니다 ....
- 정규화를 선호하십시오. 비정규 화는 모든 필수 트레이드 오프가있는 최적화의 한 형태이므로 YAGNI 태도 로 접근해야합니다 .
- 데이터베이스를 참조하는 클라이언트 코드가 스키마에서 충분히 분리되어 다시 작업 할 때 클라이언트를 대대적으로 재 설계 할 필요가 없는지 확인하십시오.
- 성능이나 쿼리 복잡성에 분명한 이점을 제공 할 때 비정규 화를 두려워하지 마십시오.
- 데이터 볼륨 및 사용 시나리오에서 허용하는 경우 스키마의 핵심을 비정규 화하는 대신 뷰 또는 다운 스트림 테이블을 사용하여 비정규 화를 구현 합니다 .
이러한 규칙의 일반적인 결과는 초기 디자인이 중복성을 제거하는 데 중점을두고 열보다 테이블을 선호한다는 것입니다. 프로젝트가 진행되고 비정규 화 지점이 식별됨에 따라 전체 구조는 다른 귀중한 이점을 제공하는 대가로 제한된 중복 및 컬럼 확산으로 타협하는 균형으로 발전 할 것입니다.
나는 더 많은 테이블을 선호하지만 특정 지점까지만 주장합니다. 예를 들어 사용자 정보를 USERS 및 ADDRESS와 같은 두 개의 테이블로 분리하면 사용자 당 여러 주소를 가질 수있는 유연성이 제공됩니다. 이것의 명백한 적용은 별도의 청구 및 배송 주소를 가진 사용자입니다.
별도의 CITY 테이블을 갖는 것에 찬성하는 주장은 각 도시의 이름을 한 번만 저장 한 다음 필요할 때 참조하면된다는 것입니다. 그것은 중복을 줄이지 만이 예에서는 과잉이라고 생각합니다. 더 공간 효율적일 수 있지만 데이터베이스에서 데이터를 선택할 때 조인 비용을 지불하게됩니다.
테이블 / 열에 대한 질문처럼 들리지 않지만 정규화에 관한 질문입니다. 일부 상황에서는 높은 수준의 정규화 (이 경우 "더 많은 테이블")가 좋고 깔끔하지만 일반적으로 관련 결과를 얻으려면 많은 수의 JOIN이 필요합니다. 데이터 세트가 충분히 크면 성능이 저하 될 수 있습니다.
Jeff는 StackOverflow의 디자인과 관련하여 그것에 대해 약간 썼습니다 . Dare Obasanjo의 Jeff 링크를 참조하십시오 .
완전히 정규화 된 디자인 (예 : "더 많은 테이블")은 더 유연하고 유지 관리가 쉬우 며 데이터 중복을 방지하므로 데이터 무결성을 훨씬 쉽게 적용 할 수 있습니다.
이것이 정상화해야하는 강력한 이유입니다. 먼저 정규화를 선택한 다음 성능이 문제가되는 것을 확인한 후에 만 특정 테이블 을 비정규 화 합니다 .
제 경험으로는 실제 세계에서는 매우 큰 데이터 세트를 사용하더라도 비정규 화가 필요한 지점에 도달하지 못할 것입니다.
데이터베이스 특성에 따라 다릅니다. 예를 들어 MS SQL Server는 더 좁은 테이블을 선호하는 경향이 있습니다. 그것은 또한 더 '정규화 된'접근 방식입니다. 다른 엔진은 다른 방식을 선호 할 수 있습니다. 메인 프레임은이 범주에 속하는 경향이 있습니다.
각 테이블에는 기본 키로 고유하게 식별되는 엔터티와 관련된 열만 포함되어야합니다. 데이터베이스의 모든 열이 모두 동일한 엔터티의 특성 인 경우 모든 열이있는 하나의 테이블 만 필요합니다.
그러나 열이 null 일 수있는 경우 정규화하려면 각 nullable 열을 기본 테이블에 대한 외래 키와 함께 자체 테이블에 넣어야합니다. 이것은 일반적인 시나리오이므로보다 깔끔한 디자인을 위해 기존 테이블에 열보다 더 많은 테이블을 추가하는 것이 좋습니다. 또한 이러한 선택적 속성을 자체 테이블에 추가하면 더 이상 null을 허용 할 필요가 없으며 수많은 NULL 관련 문제를 방지 할 수 있습니다.
다중 테이블 데이터베이스는 이러한 일대일 관계 중 하나가 미래에 일대 다 또는 다대 다가 될 수 있다면 훨씬 더 유연합니다. 예를 들어 일부 고객에 대해 여러 주소를 저장해야하는 경우 고객 테이블과 주소 테이블이 있으면 훨씬 쉽습니다. 주소의 일부를 복제해야하고 다른 부분은 복제하지 않아야하는 상황을 실제로 볼 수 없으므로 별도의 주소, 도시, 주 및 우편 번호 테이블이 약간 겹칠 수 있습니다.
다른 모든 것과 마찬가지로 상황에 따라 다릅니다.
열 수와 테이블 수에 관한 엄격하고 빠른 규칙은 없습니다.
고객이 여러 주소를 가져야하는 경우 별도의 테이블이 적합합니다. City 열을 자체 테이블로 정규화해야하는 정말 좋은 이유가 있다면 그것도 갈 수 있지만, (일반적으로) 자유 형식 필드이기 때문에 전에는 보지 못했습니다.
테이블이 무겁고 표준화 된 디자인은 공간 측면에서 효율적이고 "교과서처럼 좋아"보이지만 매우 복잡해질 수 있습니다. 고객의 이름과 주소를 얻기 위해 12 개의 조인을 수행해야 할 때까지 멋지게 보입니다. 이러한 디자인은 가장 중요한 성능, 즉 쿼리 측면에서 자동으로 환상적 이지는 않습니다 .
가능하면 복잡성을 피하십시오. 예를 들어 고객이 두 개의 주소 만 가질 수있는 경우 (임의로 많지 않음) 모든 주소를 단일 테이블 (CustomerID, Name, ShipToAddress, BillingAddress, ShipToCity, BillingCity 등)에 보관하는 것이 합리적 일 수 있습니다.
주제에 대한 Jeff의 게시물 입니다.
열 수가 적은 테이블을 사용하면 장점이 있지만 위의 시나리오를 살펴보고 다음 질문에 답해야합니다.
고객이 두 개 이상의 주소를 가질 수 있습니까? 그렇지 않은 경우 주소에 대한 별도의 테이블이 필요하지 않습니다. 그렇다면 별도의 테이블이 도움이됩니다. 필요한만큼 주소를 쉽게 추가 할 수 있기 때문에 테이블에 열을 더 추가하기가 더 어려워집니다.
정규화를 첫 번째 단계로 고려할 것이므로 도시, 카운티, 주, 국가가 별도의 열로 더 나을 것입니다 ... SQL 언어의 힘과 오늘날 DBMS-es를 사용하면 나중에 볼 필요가있을 때 데이터를 그룹화 할 수 있습니다. 다른 비정규 화 된 뷰에서.
시스템이 개발 될 때 개선 된 것으로 간주되면 일부 부분을 '비정규 화'하는 것을 고려할 수 있습니다.
이 경우 균형이 맞다고 생각합니다. 테이블에 열을 넣는 것이 합리적이라면 테이블에 넣습니다. 그렇지 않으면하지 마십시오. 동료의 접근 방식은 데이터베이스를 정규화하는 데 확실히 도움이되지만 필요한 정보를 얻기 위해 50 개의 테이블을 조인해야하는 경우에는 그다지 유용하지 않을 수 있습니다.
내 대답은 최선의 판단을 사용하는 것입니다.
여기에는 여러 측면이 있지만 애플리케이션 효율성 관점에서 보면 모트 테이블이 때때로 더 효율적일 수 있습니다. db가 작업을 수행 할 때마다 열이 많은 테이블이 몇 개있는 경우 잠금을 만들 가능성이 있으며 잠금 기간 동안 더 많은 데이터를 사용할 수 없게됩니다. 잠금이 페이지와 테이블로 에스컬레이션되면 (테이블이 아니라면) 시스템 속도를 늦출 수있는 방법을 알 수 있습니다.
흠.
나는 그것의 세척이라고 생각하고 특정 디자인 모델에 달려 있습니다. 몇 개 이상의 필드가있는 엔터티를 자체 테이블에 포함 시키거나 애플리케이션의 요구 사항이 변경됨에 따라 구성이 변경 될 가능성이있는 엔터티를 확실히 제거합니다 (예 : 필드가 너무 많기 때문에 주소를 제거 할 것입니다. 'D 특히 그것을 당신은 당신이 다른 형태가 될 수 외국 주소를 처리 할 필요가 줄 기회가 있었다 생각합니다. 전화 번호와 동일).
즉, 작동하면 성능을 주시하십시오. 크고 값 비싼 조인을 수행해야하는 엔터티를 분리 한 경우 해당 테이블을 원본으로 다시 회전하는 것이 더 나은 설계 결정이 될 수 있습니다.
가능한 한 적은 수의 열을 사용 하는 쿼리 에는 큰 이점이 있습니다. 그러나 테이블 자체는 많은 수를 가질 수 있습니다. Jeff 는 이것에 대해서도 뭔가를 말합니다.
기본적으로 쿼리를 수행 할 때 필요한 것보다 더 많이 요청하지 않도록하십시오. 쿼리 성능은 요청한 열 수와 직접 관련이 있습니다.
결정을 내리기 전에 저장하고있는 데이터의 종류를 살펴 봐야한다고 생각합니다. 주소 테이블을 갖는 것은 좋지만 여러 사람이 같은 주소를 공유 할 가능성이 높은 경우에만 가능합니다. 모든 사람이 다른 주소를 가지고있는 경우 해당 데이터를 다른 테이블에 보관하면 불필요한 조인이 발생합니다.
I don't see the benefit of having a city table unless cities in of themselves are entities you care about in your application. Or if you want to limit the number of cities available to your users.
Bottom line is decisions like this have to take the application itself into considering before you start shooting for efficiency. IMO.
When you design your database, you should be as close as possible from the meaning of data and NOT your application need !
A good database design should stand over 20 years without a change.
A customer could have multiple adresses, that's the reality. If you decided that's your application is limited to one adresse for the first release, it's concern the design of your application not the data !
It's better to have multiple table instead of multiple column and use view if you want to simplify your query.
Most of time you will have performance issue with a database it's about network performance (chain query with one row result, fetch column you don't need, etc) not about the complexity of your query.
First, normalize your tables. This ensures you avoid redundant data, giving you less rows of data to scan, which improves your queries. Then, if you run into a point where the normalized tables you are joining are causing the query to take to long to process (expensive join clause), denormalize where more appropriate.
Good to see so many inspiring and well based answers.
My answer would be (unfortunately): it depends.
Two cases: * If you create a datamodel that is to be used for many years and thus possibly has to adept many future changes: go for more tables and less rows and pretty strict normalization. * In other cases you can choose between more tables-less rows or less tables-more rows. Especially for people relatively new to the subject this last approach can be more intuitive and easy to comprehend.
The same is valid for the choosing between the object oriented approach and other options.
'developer tip' 카테고리의 다른 글
| Angular 2 테스트-비동기 함수 호출-사용시기 (0) | 2020.10.30 |
|---|---|
| Firefox가 잘못된 SSL 인증서를 무시하도록하는 방법이 있습니까? (0) | 2020.10.30 |
| iPhone 자동 테스트 (0) | 2020.10.30 |
| .NET에서 Maven이 필요하지 않은 이유는 무엇입니까? (0) | 2020.10.30 |
| 단일 테스트로 null / 빈 / 공백 값을 확인하는 방법은 무엇입니까? (0) | 2020.10.30 |