중첩 뷰가 좋은 데이터베이스 디자인입니까?


42

나는 오래 전에 어딘가에서 읽었습니다. 이 책에서는 SQL Server에서 중첩 된 뷰를 가질 수 없어야합니다. 우리가 그렇게 할 수없는 이유를 잘 모르겠거나 틀린 진술을 기억할 수도 있습니다.

재학생

SELECT studentID, first_name, last_name, SchoolID, ... FROM students

CREATE VIEW vw_eligible_student
AS 
SELECT * FROM students
WHERE enroll_this_year = 1

교사

SELECT TeacherID, first_name, last_name, SchoolID, ... FROM teachers

CREATE VIEW vw_eligible_teacher
AS 
SELECT * FROM teachers
WHERE HasCert = 1 AND enroll_this_year = 1

학교

CREATE VIEW vw_eligible_school
AS 
SELECT TOP 100 PERCENT SchoolID, school_name 

FROM schools sh 
JOIN
     vw_eligible_student s 
     ON s.SchoolID = sh.SchoolID
JOIN 
     vw_eligible_teacher t
     ON s.SchoolID = t.SchoolID

직장에서 사내 데이터베이스 응용 프로그램 중 하나를 조사했습니다. 객체를 통해 두 개 또는 세 개의 뷰 스택 레이어가 서로 있다는 것을 알았습니다. 그래서 그것은 내가 과거에 읽은 것에 대해 생각 나게했습니다. 그것을 설명하는 데 도움이 될 수 있습니까?

그렇게해도 괜찮지 않으면 SQL Server로만 제한되거나 일반적으로 데이터베이스 디자인을위한 것임을 알고 싶습니다.

추가 정보 : 회사에서 예제를 업데이트했습니다. 너무 많은 기술 (이 예에서는 너무 많은 열)없이 좀 더 일반적으로 변경합니다. 우리가 사용하는 대부분의 중첩 뷰는 추상 또는 집계 뷰를 기반으로합니다. 예를 들어, 수백 개의 열이있는 큰 학생 테이블이 있습니다. 예, Eligible Student View올해 등록한 학생을 기준으로합니다. 학생 자격보기는 저장 프로 시저와 같은 다른 장소에서 사용할 수 있습니다.


3
특정 플랫폼에 관계없이 동일한 장단점이 동일하다고 주장합니다.
Aaron Bertrand

답변:


47

플랫폼에 관계없이 다음과 같은 말이 적용됩니다.

(-) 중첩 된 뷰 :

  • 이해하고 디버그하기가 더 어렵다

    예를 들어이 뷰 열은 어떤 테이블 열을 참조합니까? Lemme는 4 가지 수준의 뷰 정의를 파헤칩니다 .

  • 쿼리 최적화 프로그램이 가장 효율적인 쿼리 계획을 세우기가 더 어려워 짐

    참조 , , , 그리고 일화적인 증거를. 옵티마이 저가 종종 중첩 된 뷰를 올바르게 압축 해제하고 최적의 계획을 선택할 수 있지만 컴파일 비용이없는 경우가 많다는 것을 보여주는 와 비교하십시오 .

    뷰 쿼리를 기본 테이블에 대해 작성된 해당 쿼리와 비교하여 성능 비용을 측정 할 수 있습니다.

반면에, 중첩 된 뷰를 사용하면 다음을 수행 할 수 있습니다.

  • 집계 또는 비즈니스 규칙의 중앙 집중화 및 재사용
  • 기본 구조를 추상화하십시오 (예 : 다른 데이터베이스 개발자로부터)

나는 그들이 거의 필요하지 않다는 것을 알았습니다.


귀하의 예에서는 중첩 된 뷰를 사용하여 특정 비즈니스 정의를 중앙 집중화하고 재사용합니다 (예 : "적격 학생이란 무엇입니까?"). 중첩 된 뷰에 유효합니다. 이 데이터베이스를 유지 관리하거나 조정하는 경우 데이터베이스를 제거하는 비용과 비교하여 유지하는 비용을 측정하십시오.

  • 유지 : 중첩 된 뷰를 유지하면 위에 열거 된 장단점이 발생합니다.

  • 제거 : 중첩 된보기를 제거하려면 다음을 수행하십시오.

    1. 모든 발생하는보기를 기본 조회로 바꿔야합니다.

    2. 관련보기 정의를 업데이트하는 대신 적격 학생 / 교사 / 학교 정의가 변경되면 모든 관련 쿼리를 업데이트해야합니다.


1
+1. 쿼리 최적화 프로그램의 "하드"를 "거의 불가능"으로 바꾸는 것을 제외하고 :)
Jason

1
@Jason-동의합니다. 구체적인 예에 ​​연결할 수 있기를 바랍니다. 왜 그런지 설명하거나 설명하는 참조 자료를 알고 있습니까?
Nick Chammas

1
내가 찾을 수있는 것은 중첩 뷰가 사용될 때 "평평한"SQL과 비교할 때 성능 문제가 발생한다는 일화적인 증거입니다. sqlservercentral.com/blogs/2cents/archive/2010/04/05/… 문제는 DB (이 경우 SQL Server)가 테이블을 조인하기 전에 특정 필터를 적용하지 않기 때문에 발생하는 것으로 보입니다. 쿼리가 예상보다 오래 걸리도록합니다.
Jason

7
쿼리 최적화 프로그램 문제에 동의하지 않습니다. 모든 뷰를 해결 한 후의 결과 쿼리는 얼마나 많은 뷰 변환을 수행했는지에 관계없이 동일합니다 (중간 결과 집합의 일부 추가 열은 제외하고 최적화 프로그램은 잘 제거 할 수 있습니다). 이것은 디버깅을 떠난다. IMO는 중간 결과를보고 어디에서 잘못되었는지 알 수 있으므로 중첩 된 뷰를 쉽게 디버깅 할 수 있습니다.
Simon Richter

1
임베디드 데이터베이스 서버를 작성했으며 뷰를 먼저 해결 한 다음 결과 쿼리를 최적화하는 것이 확실한 경로였습니다. 실제로 뷰의 모든 쿼리가 모든 열을 반환하지는 않습니다. 쿼리 중간에 뷰 데이터를 실현하는 것이 무언가를 얻는 이유를 생각조차 할 수 없으므로 그렇게 쉬운 것은 아닙니다.
Simon Richter

26

때때로 중첩 뷰는 집계 반복을 방지하기 위해 사용됩니다. 메시지를 세고 사용자 ID로 그룹화하는 뷰가 있다고 가정 해 봅시다. 메시지가 100 개를 초과하는 사용자 수를 계산하는 뷰가있을 수 있습니다. 이것은 기본보기가 인덱싱 된보기 일 때 가장 효과적입니다. 그룹화가 약간 다른 데이터를 나타 내기 위해 또 다른 인덱싱 된보기를 만들 필요는 없습니다. 이제 성능이 아마 2 배인 인덱스 유지 관리 비용을 지불하기 때문에 원래 견해에 맞습니다.

이것들이 모두 select *를하고 있지만 순서 또는 상단을 변경하는 중첩 된 뷰 인 경우 중첩 된 뷰보다 매개 변수 (또는 인라인 테이블 반환 함수)가있는 저장 프로 시저로 캡슐화하는 것이 좋습니다. 이모.


4
"이것은 기본보기가 색인 된보기 일 때 가장 효과적입니다." 중요한 점.
Nick Chammas

7

최신 버전의 SQL (2005+)은 뷰 사용을 최적화하는 데 더 좋습니다. 비즈니스 규칙을 통합하는 데보기가 가장 좋습니다. EG : 제가 일하는 곳에 통신 제품 데이터베이스가 있습니다. 각 제품은 요율 계획에 할당되며 요율 계획이 스왑 아웃 될 수 있으며 요율이 증가 또는 수정 될 때 요율 계획의 요율이 활성화 / 유도 될 수 있습니다.

쉽게하기 위해 중첩 된 뷰를 만들 수 있습니다. 첫 번째보기는 필요한 테이블을 사용하여 요율 계획을 요율에 조인하고 다음 수준의보기에 필요한 데이터를 반환합니다. 두 번째보기는 활성 요금제와 활성 요금 만 분리 할 수 ​​있습니다. 또는 고객 요금. 또는 직원 요율 (직원 할인). 또는 비즈니스 대 거주 고객 요율. (요금제는 복잡해질 수 있습니다). 요컨대, 기본 뷰는 요율 계획 및 요율에 대한 전체 비즈니스 논리가 한 위치에서 올바르게 결합되도록합니다. 다음보기 계층은 특정 요율 계획 (유형, 활성 / 비활성 등)에 더 초점을 맞 춥니 다.

쿼리와 뷰를 동시에 작성하는 경우 뷰가 디버깅을 복잡하게 만들 수 있다는 데 동의합니다. 그러나 신뢰할 수있는보기를 사용하는 경우 디버깅이 더 쉬워집니다. 뷰가 이미 벨소리 장치를 통과 했으므로 문제가 발생하지 않았을 가능성이 높습니다.

그래도 문제는 당신의 견해와 함께 올 수 있습니다. "제품이 비활성 요금제에만 연결된 경우 어떻게됩니까?" 또는 "요율표에 비활성 요금 만있는 경우 어떻게합니까?" 글쎄, 그것은 사용자 오류를 잡는 논리로 프론트 엔드 수준에서 잡힐 수 있습니다. "오류, 제품이 비활성 요금제에 있습니다 ... 수정하십시오". 또한 청구 실행 전에 쿼리 감사를 실행하여이를 다시 확인할 수 있습니다. (모든 요금제를 선택하고 활성 요금제보기에 왼쪽으로 참여하면 해결해야 할 문제로 현재 요금제를받지 않는 요금제 만 반환).

이에 대한 좋은 점은보고, 청구 등에 대한 쿼리를 크게 정리할 수있는보기입니다. 고객 계정보기를 사용하고 활성 고객에 대한 2 단계보기를 사용할 수 있습니다. 고객 주소를 볼 수 있도록 팀을 구성하십시오. 제품을 볼 수 있도록 팀을 구성하십시오 (고객이 보유한 제품에 참여). 제품 요율 계획을 볼 수 있도록 팀을 구성하십시오. 제품 기능을 볼 수 있도록 팀을 구성하십시오. 무결성을 보장하기 위해 각 시행 착오를보고,보고,보고 뷰를 사용한 최종 쿼리는 매우 간결합니다.

편집하다:

단순한 테이블 쿼리보다 뷰가 더 나은 방법의 한 예로 ... 임시 계약자가 변경을 요청했습니다. 그들은 그에게 사물에 대한 견해가 있다고 말했지만 그의 모든 질문을 평평하게하기로 결정했습니다. Billing은 일부 쿼리에서 문제를 해결했습니다. 그들은 계속해서 여러 가지 요금제와 요금을 받고 있습니다. 요율 계획에서 해당 요율 / 사용 요율을 사용해야하는 시작 날짜와 종료 날짜 사이의 요율 만 청구 할 수 있도록 쿼리에 기준이 누락 된 것으로 나타났습니다. 죄송합니다. 그가이 견해를 사용했다면 이미 그 논리를 고려했을 것입니다.

기본적으로 성능과 정신의 무게를 측정해야합니다. 데이터베이스의 성능을 높이기 위해 모든 종류의 멋진 작업을 수행 할 수 있습니다. 그러나 새로운 사람이 인계 / 유지하는 것이 악몽이라는 것을 의미한다면 실제로 가치가 있습니까? 새로운 사람이 자신의 논리를 변경 해야하는 모든 쿼리를 찾아야하고 (잊어 버릴 수 있습니다.) 핵심 비즈니스 로직을 100의 다른 쿼리에 사용될 수있는 로직으로 통합하지 않았습니까? 비즈니스와 IT / IS / DB 팀의 책임입니다. 그러나 성능보다 명확성과 단일 소스 통합을 선호합니다.


4

실제 문제는 그 자체로 중첩 된 뷰가 아닙니다. 실제 문제는 개발자가 기존 뷰에 추가 조정을 추가 할 때 중첩 된 뷰가 확산되는 것입니다. 중첩 된보기 4 레이어가 실제로 정의에있는보기 중 하나에 결합 된 쿼리를 발견했습니다. 문제를 분석하고 해결하는 것보다 쉬운 방법을 찾는 경향이 문제의 근원입니다.


0

내 환경에서는 프로덕션 서버에서 보고서 서버로 많은 테이블을 복제합니다. 보고서 서버에는 복제 된 프로덕션 테이블을 기반으로하며 중첩 된 뷰가 많이 있습니다. 복제가 시작되기 전에 복제를 가능하게하기 위해 모든 뷰를 제거해야합니다 (테이블 구조가 프로덕션 환경에서 자주 변경되므로 삭제 및 작성을 사용합니다). 복제가 끝나면 모든 뷰를 다시 작성해야합니다.

이제 재미있는 부분이 있습니다. 많은 뷰가 중첩되어 있기 때문에 특정 순서로 다시 작성해야합니다. 뷰 정의를 변경하는 동안 올바른 재구성 순서를 유지하기 위해주의를 기울여야합니다. 완전히 혼란 스러워요. 복제를 사용하거나 단순히 뷰의 소스 인 테이블을 삭제 및 재 구축하는 경우 중첩 뷰를 사용하지 않는 것이 좋습니다.

성능은 또 다른 것입니다. 다른 뷰를 기반으로하는 뷰는 실행할 쿼리가 여러 개일뿐입니다. 더 큰 쿼리를 작성하고 작업을 작성하고 테이블을 작성하는 것이 더 쉽습니다. 성능을보다 쉽고 향상시킵니다.

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