Czy widok zagnieżdżony to dobry projekt bazy danych?


42

Czytałem gdzieś dawno temu. Książka stwierdza, że ​​nie powinniśmy pozwalać na widok zagnieżdżony w SQL Server. Nie jestem pewien powodu, dla którego nie możemy tego zrobić, lub pamiętam nieprawidłowe stwierdzenie.

Studenci

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

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

Nauczyciele

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

Szkoły

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

W moim miejscu pracy zbadałem jedną z naszych wewnętrznych aplikacji bazodanowych. Sprawdziłem przez obiekty, aby stwierdzić, że są dwie lub trzy warstwy widoku stosu. To przypomniało mi o tym, co czytałem w przeszłości. Czy ktoś może pomóc w wyjaśnieniu tego?

Jeśli nie jest to w porządku, chcę wiedzieć, że ogranicza się tylko do SQL Servera lub ogólnie do projektowania baz danych.

Informacje dodatkowe: Zaktualizowałem przykład z mojej firmy. Zmieniam trochę, aby był bardziej ogólny, bez zbyt wielu technicznych (zbyt wielu kolumn w tym przykładzie). Najczęściej używany widok zagnieżdżony opiera się na widoku abstrakcyjnym lub zagregowanym. Na przykład mamy duży stół studencki ze sto kolumnami. Powiedzmy, Eligible Student Viewopiera się na studentach, którzy zapisają się w tym roku. Widok uprawniony do studenta można wykorzystać w innych miejscach, takich jak procedura składowana.


3
Chciałbym stwierdzić, że te same zalety i wady byłyby w przybliżeniu równe niezależnie od konkretnej platformy.
Aaron Bertrand

Odpowiedzi:


47

Niezależnie od platformy obowiązują następujące uwagi.

(-) Zagnieżdżone widoki:

  • są trudniejsze do zrozumienia i debugowania

    np. do jakiej kolumny tabeli odnosi się ta kolumna widoku? Zapamiętaj 4 poziomy definicji widoku ...

  • utrudnić optymalizatorowi zapytań opracowanie najbardziej wydajnego planu zapytań

    Zobacz to , to , to i to jako niepotwierdzone dowody. Porównaj to , co pokazuje, że optymalizator jest często wystarczająco inteligentny, aby poprawnie rozpakować zagnieżdżone widoki i wybrać optymalny plan, ale nie bez kosztów kompilacji.

    Możesz zmierzyć koszt wydajności, porównując zapytanie widoku z równoważnym zapytaniem zapisanym w tabelach podstawowych.

(+) Z drugiej strony widoki zagnieżdżone umożliwiają:

  • scentralizować i ponownie wykorzystać agregacje lub reguły biznesowe
  • oderwij swoją podstawową strukturę (powiedzmy od innych programistów baz danych)

Przekonałem się, że rzadko są potrzebne.


W twoim przykładzie używasz widoków zagnieżdżonych do scentralizowania i ponownego wykorzystania niektórych definicji biznesowych (np. „Kim jest uprawniony uczeń?”). Jest to prawidłowe zastosowanie dla widoków zagnieżdżonych. Jeśli utrzymujesz lub dostrajasz tę bazę danych, porównaj koszty jej utrzymania z kosztami ich usunięcia.

  • Zachowaj: Utrzymując zagnieżdżone widoki, ponosisz zalety i wady wymienione powyżej.

  • Usuń: aby usunąć zagnieżdżone widoki:

    1. Musisz zastąpić wszystkie wystąpienia widoków podstawowymi zapytaniami.

    2. Musisz pamiętać o aktualizacji wszystkich odpowiednich zapytań, jeśli zmieni się twoja definicja kwalifikującego się ucznia / nauczyciela / szkoły, a nie tylko aktualizacja odpowiedniej definicji widoku.


1
+1, z wyjątkiem tego, że zamiast „trudniejszego” dla optymalizatora zapytań, „prawie niemożliwe”. :)
Jason

1
@Jason - Zgadzam się i chciałbym zamieścić linki do konkretnych przykładów. Czy znasz jakieś referencje, które wyjaśniają lub pokazują, dlaczego tak jest?
Nick Chammas,

1
Jedyne, co mogę znaleźć, to niepotwierdzone dowody, że kiedy używane są widoki zagnieżdżone, mają problemy z wydajnością w porównaniu do „spłaszczonego” SQL. sqlservercentral.com/blogs/2cents/archive/2010/04/05/… Problem wydaje się sprowadzać się do faktu, że DB (w tym przypadku SQL Server) nie zastosuje pewnych filtrów przed dołączeniem do tabel i dlatego spraw, aby zapytanie trwało dłużej niż powinno.
Jason

7
Nie zgadzam się w kwestii optymalizatora zapytań, ponieważ wynikowe zapytanie po rozwiązaniu wszystkich widoków będzie takie samo bez względu na to, ile przeszło transformacji widoku (z wyjątkiem niektórych dodatkowych kolumn w pośrednich zestawach wyników, które optymalizator może wyeliminować). To pozostawia debugowanie; IMO ułatwia debugowanie zagnieżdżonych widoków, ponieważ mogę spojrzeć na wyniki pośrednie, aby zobaczyć, gdzie poszło nie tak.
Simon Richter,

1
Napisałem wbudowany serwer bazy danych i dla mnie najpierw rozwiązywanie widoków, a następnie optymalizacja wynikowego zapytania była oczywistą drogą, ponieważ w rzeczywistości jest mało prawdopodobne, aby wszystkie zapytania w widokach zwróciły wszystkie kolumny. Nie mogę nawet wymyślić powodu, dla którego realizacja danych widoku w środku zapytania mogłaby coś zyskać, więc dla mnie nie było to żadnym problemem.
Simon Richter,

26

Czasami używane są widoki zagnieżdżone, aby zapobiec powtarzaniu się agregacji. Załóżmy, że masz widok, który liczy wiadomości i grupuje je według identyfikatora użytkownika, możesz mieć widok, który liczy liczbę użytkowników, którzy mają> 100 wiadomości, tego rodzaju rzeczy. Jest to najbardziej skuteczne, gdy widok podstawowy jest widokiem zindeksowanym - niekoniecznie chcesz utworzyć kolejny widok zindeksowany do reprezentowania danych z nieco innym grupowaniem, ponieważ teraz płacisz za utrzymanie indeksu dwa razy, gdzie wydajność jest prawdopodobnie adekwatne do oryginalnego widoku.

Jeśli są to tylko widoki zagnieżdżone, w których wykonujesz polecenie select *, ale zmieniając kolejność lub górę, wydaje się, że byłoby to lepiej zamknięte w postaci procedury składowanej z parametrami (lub wbudowanymi funkcjami o wartościach przechowywanych w tabeli) niż kilka zagnieżdżonych widoków. MOIM ZDANIEM.


4
„Jest to najbardziej skuteczne, gdy widok podstawowy jest widokiem indeksowanym”. Ważny punkt.
Nick Chammas,

7

Późniejsze wersje SQL (2005+) wydają się lepiej optymalizować wykorzystanie widoków. Widoki najlepiej nadają się do konsolidacji reguł biznesowych. EG: tam, gdzie pracuję, mamy bazę danych produktów telekomunikacyjnych. Każdy produkt jest przypisany do planu stawek, który może zostać zamieniony, a stawki na planie stawek mogą zostać aktywowane / dezaktywowane w miarę zwiększania lub modyfikowania stawek.

Aby to ułatwić, możemy tworzyć zagnieżdżone widoki. Pierwszy widok po prostu łączy plany taryfowe z ich stawkami przy użyciu dowolnych potrzebnych tabel, a zwracając wszelkie niezbędne dane, potrzebne będą kolejne poziomy widoków. 2. widok (y) może izolować tylko aktywne plany stawek i ich aktywne stawki. Lub tylko stawki klientów. Lub stawki pracownicze (dla rabatu pracowniczego). Lub stawki dla klientów biznesowych i indywidualnych. (plany taryfowe mogą się komplikować). Chodzi o to, że widok fundamentu zapewnia naszą logikę biznesową planów taryfowych, a stawki są odpowiednio łączone w jednym miejscu. Kolejna warstwa widoków pozwala nam bardziej skupić się na konkretnych planach stawek (typy, aktywne / nieaktywne itp.).

Zgadzam się, że widoki mogą sprawiać, że debugowanie będzie nieporządne, jeśli jednocześnie budujesz zapytania i widoki. Ale jeśli używasz sprawdzonego widoku, ułatwia to debugowanie. Wiesz, że widok przeszedł już przez dzwonek, więc wiesz, że najprawdopodobniej nie powoduje problemu.

Twoje poglądy mogą jednak powodować problemy. „co jeśli produkt jest powiązany tylko z nieaktywnym planem stawek?” lub „co jeśli plan taryfowy zawiera wyłącznie stawki nieaktywne?” Cóż, można to złapać na poziomie frontonu dzięki logice, która wyłapuje błędy użytkownika. „Błąd, produkt ma nieaktywny plan stawek ... proszę poprawić”. Możemy również przeprowadzać audyty zapytań, aby dokładnie je sprawdzić przed uruchomieniem rozliczeń. (wybierz wszystkie plany i pozostaw dołączenie do aktywnego widoku planu taryfowego, zwracaj tylko plany, które nie otrzymują aktywnego planu taryfowego, jako problemy wymagające rozwiązania).

Dobrą rzeczą jest to, że widoki pozwalają znacznie ograniczyć zapytania dotyczące raportów, fakturowania itp. Możesz mieć widok konta klienta, a następnie widok drugiego poziomu tylko aktywnych klientów. Połącz to z widokiem adresu klienta. Połącz to z widokiem produktu (produktów) (dołączyłem do tego, co klient ma). Połącz to, aby wyświetlić plan taryfowy produktu. Połącz to z widokiem funkcji produktu. Zobacz, zobacz, zobacz, każda próba-pomyłka dla zapewnienia integralności. Twoje zapytanie końcowe przy użyciu widoków jest bardzo zwarte.

edytować:

Jako przykład tego, jak widok byłby lepszy niż zwykłe zapytanie o tabele ... mieliśmy tymczasowego wykonawcę, który wprowadził pewne zmiany. Powiedzieli mu, że istnieją poglądy na różne rzeczy, ale postanowił spłaszczyć wszystkie swoje zapytania. Billing odpalał niektóre z jego zapytań. Ciągle otrzymywali wiele planów taryfowych i stawki na rzeczy. Okazało się, że w jego zapytaniach brakowało kryteriów pozwalających na naliczanie stawek tylko wtedy, gdy były one między datą początkową i końcową, w której plan taryfowy miał stosować te / te stawki podczas. Ups Gdyby skorzystał z tego widoku, uwzględniłby już tę logikę.

Zasadniczo musisz porównać wydajność z rozsądkiem. Być może możesz zrobić różne fantazyjne rzeczy, aby zwiększyć wydajność bazy danych. Ale jeśli oznacza to, że przejęcie / utrzymanie nowej osoby jest koszmarem, czy naprawdę jest tego warte? Czy naprawdę warto, aby nowy facet grał w walenie w kret i znajdował wszystkie pytania, które muszą zmienić ich logikę (i ryzykować, że je zapomni / przekręci palcami) b / c ktoś uznał, że poglądy są „złe” i nie skonsolidowałeś logiki biznesowej w jedną, która mogłaby zostać wykorzystana w setkach innych zapytań? To naprawdę zależy od Twojej firmy i zespołu IT / IS / DB. Wolę jednak przejrzystość i konsolidację z jednego źródła niż wydajność.


4

Prawdziwym problemem nie są same zagnieżdżone widoki. Prawdziwym problemem jest mnożenie widoków zagnieżdżonych, gdy programiści nakładają dodatkowe poprawki w istniejących widokach. Znalazłem zapytania z zagnieżdżonym widokiem 4 warstwy, które faktycznie łączyły się z jednym z widoków w jego definicji. Nasza skłonność do wybierania łatwego wyjścia zamiast analizowania i rozwiązywania problemu jest źródłem problemu.


0

W moim środowisku replikujemy wiele tabel z serwera produkcyjnego do serwera raportów. Na serwerze raportów mamy wiele widoków opartych na replikowanych tabelach produkcyjnych ORAZ zagnieżdżonych. Przed rozpoczęciem replikacji musimy usunąć wszystkie widoki, aby umożliwić replikację (używamy upuszczania i tworzenia, ponieważ struktura tabel często zmienia się w produkcji). Po zakończeniu replikacji musimy odbudować wszystkie widoki.

Oto zabawna część: ponieważ wiele widoków jest zagnieżdżonych, musimy je odbudować w określonej kolejności. Wprowadzając wszelkie zmiany w definicji widoków, musimy zwrócić uwagę, aby zachować prawidłową kolejność odbudowywania. To totalny bałagan. Zdecydowanie odradzam używanie widoków zagnieżdżonych, jeśli używasz replikacji lub po prostu upuszczasz i odbudowujesz tabele, które są źródłem widoków.

Wydajność to kolejna rzecz. Widoki oparte na innych widokach to nic innego jak wykonanie wielu zapytań. Łatwiej jest połączyć większe zapytanie, stworzyć zadanie i zrobić z niego tabelę. Łatwiej i poprawia wydajność.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.