데이터베이스 디자인 : 새 테이블과 새 열


38

(이것은 StackOverflow에서 다시 게시되도록 제안되었습니다)

현재 테이블이 있습니다. .. 새 데이터 열을 추가해야합니다. 모든 레코드 (새 데이터 열을 추가 한 후 새 데이터로 진행되는 경우에도)에 데이터가있는 것은 아닙니다. 그래서 이것이 실제로 일부 데이터 행의 확장이며 모든 행에 적용되지 않기 때문에 이것이 새로운 테이블에 더 적합한 지 궁금합니다.

다시 말해, 새로운 데이터 요소에 대해 사용되지 않는 열이 많이 있기 때문에 이것이 새로운 테이블에 더 적합한 것 같습니다.

첫 번째 테이블은 페이지 조회 레코드입니다 (현재 2 백만 레코드).

-아이디
- IP 주소
-조회수
-created_at 타임 스탬프
- 데이트

모든 IP 주소에 대해 매일 레코드가 작성되고 연속 페이지 뷰가 하루의 시간 조회수에 추가됩니다.

추가 필드는 원점 추적 (예 : Google 웹 로그 분석 소스 / 매체 / 캠페인)을위한 것입니다.

모든 방문에 해당 정보가있는 것은 아닙니다. Im은 행의 약 10 %가 데이터를 가지고 있다고 가정합니다 (일반적으로 첫 번째 방문에서만 계산 됨)

데이터의 주된 용도는 사람들이 어디에서 왔는가를 나타내는 것입니다. 이것은 더 자주 사용되는 경향이 있습니다 (그러면 단일 테이블에 빌려주는 것처럼 보입니다)

피드백 감사-필요한 경우 더 추가 할 수 있습니다

답변:


29

당신이 씨름하는 것은 수직 분할입니다. 이것은 성능을 향상시키기위한 실제 데이터베이스 설계 기술입니다. 실제 데이터베이스 디자인 기술과 마찬가지로 적용 가능성은 최적화하려는 특정 쿼리와이 기술로 최적화 할 것인지에 따라 다릅니다. 논리적 관점에서 볼 때, 이러한 새로운 필드가 엔티티의 후보 키에 의존하는 경우 해당 필드가 속한 필드에 대한 사실입니다. 먼저 후보 키에 대한 이러한 새로운 필드의 기능 의존성을 완전히 이해하여 이들이 매일 페이지 뷰에 대한 사실인지 확인해야합니다. 이 경우 다른 테이블로 분할하기로 결정하면 성능 목표가 달성 된 경우에만 수행해야하는 성능 최적화입니다.

일반적으로 수직 분할은 이러한 새 열을 원본 테이블의 다른 열과 자주 그리고 다르게 쿼리하는 경우에 유용합니다. 기존 테이블과 동일한 PK를 공유하는 다른 테이블에 해당 열을 배치하면 새 열을 원할 때 직접 쿼리 할 수 ​​있으며이 새 테이블의 디스크에 페이지 당 더 많은 행이 있으므로 처리량이 훨씬 늘어납니다. 원래 테이블의 모든 열이 해당 행에 앉아 있지 않기 때문입니다. 그러나 항상 원본 테이블의 열과 함께이 열을 쿼리하면 수직 분할은 항상 외부 조인을 수행해야하므로 의미가 없습니다. 디스크에있는 테이블의 페이지는 DBMS의 버퍼 풀에 독립적으로 제공되며 사전 결합되지 않습니다. 따라서 데이터가 버퍼 풀에 고정되어 있어도 모든 쿼리 실행시 조인이 발생해야합니다. 이 시나리오에서 원래 테이블에 널 (NULL) 가능 컬럼을 작성하면 널 (NULL) 일 때 DBMS 스토리지 엔진이 효율적으로 컬럼을 저장하고 검색시 결합 할 필요가 없습니다.

유스 케이스가 후자 인 것처럼 들리고 원래 테이블에 NULLABLE로 추가하는 것이 좋습니다. 그러나 데이터베이스 디자인의 다른 모든 항목과 마찬가지로, 올바른 결정을 내리려면 예상 작업량과 올바른 선택이 무엇인지 알아야합니다. 수직 파티셔닝에 대한 적절한 사용 사례의 좋은 예는 사람 검색 패널인데, 여기에는 응용 프로그램에 누군가가 검색하고 싶지만 거의 수행하지 않는 사람에 대한 정보가 거의 채워지지 않습니다. 해당 정보를 다른 테이블에 넣으면 성능에 대한 몇 가지 좋은 옵션이 있습니다. 검색어를 작성하여 항상 검색된 기본 정보를 사용하여 성 (이름 또는 ssn과 같은), 그리고 검색 요청이있을 때만 외부에서 매우 자주 채워지는 정보를 조인합니다. 또는 외부 조인이 필요하지 않고 수행하지 않을 주어진 호스트 변수 세트에 대해 충분히 똑똑한 경우 DBMS 옵티 마이저를 활용할 수 있으므로 쿼리를 하나만 작성하면됩니다.

어떤 DBMS 플랫폼을 사용하고 있습니까? 플랫폼에서 NULL 열 저장소를 처리하고 쿼리를 최적화하는 방법과 스파 스 열 지원 (SQL Server의 경우)이 결정에 영향을줍니다. 궁극적으로 프로덕션 크기의 데이터와 워크로드가있는 테스트 환경에서 두 가지 디자인을 모두 시험해보고 어느 것이 성능 목표를 더 잘 달성하는지 확인하는 것이 좋습니다.


"원래 테이블의 열과 함께이 열을 항상 쿼리하는 경우 수직 분할은 항상 외부 조인을 수행해야하므로 의미가 없습니다." , 보조 열을 사용할 수 있는지 여부에 관계없이 기본 열을 원할 때 외부 조인 만하면됩니다. 그렇지 않으면 INNER JOIN을 사용하면 대부분의 경우 유익합니다 (보낸 행 수 감소) ).
jmoreno

여기에 모든 도움을 주셔서 감사합니다 .. 나는 실제로 필드를 추가하는 것을 시도했지만, 이것을 통해 생각한 후에 모든 것을 더 잘 식별하기 위해 몇 개의 다른 테이블이 있어야한다는 것을 알았습니다. 마지막으로 방문한 방문자는 visitor_visits (방문자 _id가 있고 소스가 포함되어 있음) page_views (vistor_id 및 visitor_visit_id가 있음)가 방문에 어떤 page_view가 정확한지 알고 싶기 때문에 그 링크를 추가했습니다. 나는 그것과 조금 씨름했지만, 그것이 올바른 결정이라고 생각합니다
cgmckeever

10

개인적으로 기존 테이블에 열을 추가하는 것을 선호합니다. 새로운 테이블은 실제로 아무것도 사지 않습니다.

  • 원래 테이블의 NULL 값은 공간을 차지하지 않으므로 새 테이블에는 절약을 상쇄하는 일종의 식별자가 필요하므로 실제로 많은 공간을 절약하지 않습니다.
  • 쿼리가 더 복잡해지고 ... where newcolumn is not nulla가됩니다left outer join

단일 테이블에서는 행 크기가 페이지마다 다를 수 있음을 의미하지만 특히 클러스터형 인덱스가 단조 증가하는 열 (정체성 또는 날짜 / 시간)에있는 경우 기존 페이지의 많은 수에는 영향을 미치지 않습니다.


표가 현재 넓지 않고 (설명에 따라)이 데이터가 너무 넓지 않기 때문에 동의합니다.
HLGEM

4

당신이 제공 한 정보와 일반적인 정규화가 목표라면, 아마도 nullable 열을 추가 할 것입니다. 그러나 데이터를 모델링하는 가장 좋은 방법을 알기 위해 데이터를 어떻게 사용할 지에 대한 충분한 정보를 제공하지 못했습니다. 입니다.

이 데이터를 실제로 사용하는 방법에 따라 다른 데이터 모델을 고려할 수 있습니다. 이 데이터를보고 용으로 사용하는 경우 특정 유형의보고에 더 효율적일 수있는 차원 모델을보고 싶을 수 있습니다. 예를 들어, 시간 분석은 날짜 및 시간 차원이 분리되어 잘 작동합니다.

"X와 같은 캠페인에서 가장 많이 방문한 시간은 몇 시간입니까?"또는 "시간당 가장 많이 방문한 캠페인은 몇 일입니까?"와 같은 분석 질문에 대한 단일 데이터 시간 열이 작동하지 않습니다. 아주 잘 (그러나 이것은 관계형 모델로 나눌 수도 있음) IP 주소를 차원으로 취급 할 수있는 경우가 많이 있습니다 (어쩌면 눈송이에 어떤 종류의 지리 데이터가있을 수도 있습니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.