Чи є вкладений перегляд хорошим дизайном бази даних?


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
Я стверджую, що ті самі плюси і мінуси будуть приблизно зрівнятися незалежно від конкретної платформи.
Аарон Бертран

Відповіді:


47

Незалежно від платформи, застосовуються наступні зауваження.

(-) Вкладені перегляди:

  • важче зрозуміти і налагодити

    наприклад, до якого стовпця таблиці посилається цей стовпець перегляду? Перекопаємо лему через 4 рівні визначення перегляду ...

  • ускладнюйте оптимізатору запитів придумати найбільш ефективний план запитів

    Дивіться це , це , це та це для анекдотичних доказів. Порівняйте це , що показує, що оптимізатор часто досить розумний, щоб правильно розпакувати вкладені представлення та вибрати оптимальний план, але не без витрат на компіляцію.

    Ви можете виміряти вартість ефективності, порівнявши запит перегляду з еквівалентним записом, написаним проти базових таблиць.

(+) З іншого боку, вкладені подання дозволяють вам:

  • централізувати та повторно використовувати агрегати або правила ведення бізнесу
  • абстрагуйте свою базову структуру (скажімо, від інших розробників баз даних)

Я виявив, що вони рідко потрібні.


У вашому прикладі ви використовуєте вкладені представлення для централізації та повторного використання певних визначень бізнесу (наприклад, "Що таке студент, який має право?"). Це дійсне використання для вкладених представлень. Якщо ви підтримуєте або налаштовуєте цю базу даних, зважте витрати на їх збереження проти витрат на їх видалення.

  • Зберігайте: зберігаючи вкладені представлення, ви несете переваги та недоліки, перелічені вище.

  • Видалити: Щоб видалити вкладені представлення:

    1. Потрібно замінити всі випадки перегляду на їх базові запити.

    2. Ви повинні пам’ятати, щоб оновити всі відповідні запити, якщо ваше визначення придатного учня / вчителя / школи змінюється, на відміну від простого оновлення відповідного визначення подання.


1
+1, окрім того, я б замінив "важче" для оптимізатора запитів на "майже неможливо". :)
Джейсон

1
@Jason - Я згоден, і хотілося б, щоб я міг посилання на деякі конкретні приклади. Чи знаєте ви якісь посилання, які пояснюють або демонструють, чому це так?
Nick Chammas

1
Все, що я можу знайти, - це анекдотичні докази того, що при вживанні вкладених представлень вони відчувають проблеми з продуктивністю порівняно з "сплющеним" SQL. sqlservercentral.com/blogs/2cents/archive/2010/04/05/… Схоже, проблема зводиться до того, що БД (SQL Server у цьому випадку) не застосовуватиме певні фільтри до того, як приєднається до таблиць, і тому змусити запит тривати довше, ніж слід.
Джейсон

7
Я не погоджуюся з питанням оптимізатора запитів, оскільки отриманий запит після вирішення всіх переглядів буде однаковим, незалежно від того, скільки перетворень перегляду воно пройшло (за винятком деяких додаткових стовпців у проміжних наборах результатів, які оптимізатор може усунути просто чудово). Це залишає налагодження; IMO, це дозволяє налагоджувати простіше мати вкладені представлення, оскільки я можу переглянути проміжні результати, щоб побачити, куди пішло не так.
Саймон Ріхтер

1
Я написав вбудований сервер баз даних, і для мене спочатку вирішення поглядів, а потім оптимізація отриманого запиту був очевидним маршрутом, оскільки насправді цілком малоймовірно, що всі запити у видах повернуть усі стовпці. Я навіть не можу придумати причину, чому реалізація даних перегляду в середині запиту щось отримає, тож це було для мене невідомим.
Саймон Ріхтер

26

Іноді вкладені представлення використовуються для запобігання повторення сукупностей. Скажімо, у вас є перегляд, який підраховує повідомлення та групує їх за користувачем userid, ви можете мати уявлення про те, що підраховує кількість користувачів, які мають> 100 повідомлень, таку річ. Це найефективніше, коли базовим видом є індексований вигляд - вам не обов'язково хочеться створити ще один індексований вигляд, щоб представити дані з дещо іншою групуванням, тому що тепер ви платите за підтримку індексу вдвічі, де ефективність, ймовірно, є адекватний проти оригінального виду.

Якщо це все просто вкладені подання, де ви робите вибір *, але змінюєте впорядкування або верх, схоже, це було б краще інкапсульовано як збережена процедура з параметрами (або вбудованими функціями, що оцінюються в таблиці), ніж купа вкладених представлень. ІМХО.


4
"Це найбільш ефективно, коли базовий вигляд - це індексований вигляд." Важливий момент.
Nick Chammas

7

Пізніші версії SQL (2005+) здаються кращими для оптимізації використання поглядів. Перегляди найкращі для консолідації бізнес-правил. EG: там, де я працюю, ми маємо базу даних про телекомунікаційні продукти. Кожен продукт призначений до тарифного плану, і цей тарифний план може бути замінений, і ставки на тарифному плані можуть активізуватися / вимкнутись із збільшенням або зміною ставок.

Щоб зробити це легше, ми можемо зробити вкладені подання. Перший вигляд просто приєднує тарифні плани до своїх тарифів, використовуючи необхідні таблиці, і повертає будь-які необхідні дані для наступних рівнів переглядів. Другий вид (и) може ізолювати лише активні тарифні плани та їх активні швидкості. Або просто ставки клієнтів. Або ставки працівників (за знижкою працівника). Або бізнес та ставки клієнтів. (тарифні плани можуть ускладнитися). Справа в тому, що представлення фундаменту забезпечує нашу загальну логіку бізнесу для тарифних планів і тарифів, які належним чином поєднуються в одному місці. Наступний рівень поглядів надає нам більше уваги на конкретних тарифних планах (типи, активні / неактивні тощо).

Я погоджуюся, що представлення даних може зробити налагодження безладним, якщо ви одночасно створюєте запити та перегляди. Але якщо ви використовуєте перевірений n-довірений вигляд, це робить налагодження простішим. Ви знаєте, що погляд вже пройшов через дзвінок, тож ви знаєте, що це, швидше за все, не викликає проблеми.

Проблеми, однак, можуть підійти до ваших поглядів. "що робити, якщо продукт асоціюється лише з неактивним планом тарифу?" або "що робити, якщо тарифний план має лише неактивні тарифи?" Ну, це може потрапити на передній рівень за допомогою логіки, яка виявляє помилки користувачів. "Помилка, продукт перебуває у неактивному плані тарифу ... будь ласка, виправте". Також ми можемо запустити аудит запитів, щоб подвійно перевірити його перед запуском рахунків. (виберіть усі плани та залиште приєднатися до перегляду активних тарифних планів; поверніть лише плани, які не отримують активний план тарифів, як проблеми, які потрібно вирішити)

Хороша справа в тому, що перегляди дозволяють значно скоротити запити щодо звітування, виставлення рахунків тощо. Ви можете мати перегляд облікового запису клієнта, а потім перегляд другого рівня лише активних клієнтів. Команда, яка враховує адресу клієнта. Команда, яка переглядає товар (и) (приєднався до того, який товар (и) має клієнт). Команда, яка переглядає тарифний план продукту. Команда, яка враховує особливості продукту. Переглядайте, переглядайте, переглядайте кожну пробну помилку n-n, для забезпечення цілісності. Ваш кінцевий запит із використанням представлень дуже компактний.

редагувати:

Як приклад того, як перегляд був би кращим, ніж просто плоский запит таблиць ... у нас був підрядник із тимчасових тем, щоб внести деякі зміни. Вони сказали йому, що є погляди на речі, але він вирішив згладити всі свої запити. Біллінг запускав речі з деяких його запитів. Вони продовжували отримувати кілька тарифних планів і ставок на речі. Виявляється, у його запитах не було критеріїв, щоб дозволити нарахування тарифів лише у тому випадку, коли вони знаходилися між початковою та кінцевою датами. На жаль Якби він використав погляд, він би вже врахував цю логіку.

В основному, ви повинні зважувати продуктивність проти розумності. Можливо, ви можете робити всілякі химерні речі для підвищення продуктивності бази даних. Але якщо це означає, що це новий кошмар, який повинен перейняти / утримати нову людину, чи справді це варто? Чи справді варто, щоб новому хлопцеві довелося грати в грубий моль, знаходячись на всі запити, які потребують змінити їх логіку (і ризикувати, що він їх забуде / товстує) б / с хтось вирішив, що погляди "погані" і не консолідували якусь основну логіку бізнесу в ту, яку можна було б використати в 100-х інших запитах? Це справді залежить від вашого бізнесу та вашої команди IT / IS / DB. Але я вважаю за краще чіткість і консолідація одного джерела над продуктивністю.


4

Справжнє питання - це не вкладені в них погляди. Справжньою проблемою є поширення вкладених поглядів, оскільки розробники накладають додаткові зміни на існуючі представлення даних. Я знайшов запити з вкладеним видом 4 шарів, які фактично приєдналися до одного з представлень у його визначенні. Наша тенденція скористатися простим виходом, а не аналізувати та вирішувати проблему, є основою проблеми.


0

У моєму середовищі ми копіюємо багато таблиць з виробничого сервера на сервер звітів. На сервері звітів у нас є маса переглядів, які базуються на реплікуваних виробничих таблицях AND і вкладені. Перед тим, як розпочнеться реплікація, ми повинні видалити всі представлення даних, щоб зробити можливою реплікацію (ми використовуємо drop і create, оскільки структура таблиць часто змінюється у виробництві). Після закінчення реплікації ми повинні відновити всі погляди.

Тепер ось найцікавіша частина: Оскільки багато поглядів вкладені, ми повинні перебудувати їх у визначеному порядку. Вносячи будь-які зміни у визначення переглядів, ми повинні звернути увагу на правильний порядок відновлення. Це тотальний безлад. Я настійно перешкоджаю використанню вкладених представлень, якщо ви використовуєте реплікацію або просто опускаєте та відновлюєте свої таблиці, які є джерелом для переглядів.

Продуктивність - інша річ. Перегляди, що базуються на інших переглядах, - це не що інше, як кілька запитів для виконання. Простіше скласти більший запит разом, створити роботу та скласти з нього таблицю. Легше і покращує продуктивність.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.