Является ли Nested View хорошим дизайном базы данных?


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
@ Джейсон - я согласен и хотел бы дать ссылку на несколько конкретных примеров. Знаете ли вы какие-либо ссылки, которые объясняют или демонстрируют, почему это так?
Ник Чаммас

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

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

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

26

Иногда вложенные представления используются для предотвращения повторяющихся агрегатов. Допустим, у вас есть представление, которое подсчитывает сообщения и группирует их по идентификатору пользователя, у вас может быть представление, которое подсчитывает количество пользователей, у которых> 100 сообщений, и тому подобное. Это наиболее эффективно, когда базовое представление является индексированным представлением - вам не обязательно создавать еще одно индексированное представление для представления данных с немного другой группировкой, потому что теперь вы платите за обслуживание индекса в два раза там, где, вероятно, производительность адекватно первоначальному виду.

Если это просто вложенные представления, в которых вы делаете select *, но изменяете порядок или вершину, кажется, что это будет лучше инкапсулировать в виде хранимой процедуры с параметрами (или встроенными табличными функциями), чем набор вложенных представлений. ИМХО.


4
«Это наиболее эффективно, когда базовое представление является индексированным представлением». Важная точка.
Ник Чаммас

7

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

Чтобы было проще, мы можем создавать вложенные представления. 1-е представление просто соединяет тарифные планы с их тарифами с использованием любых необходимых таблиц и возвращает все необходимые данные, которые понадобятся следующим уровням просмотров. Во втором представлении можно выделить только активные тарифные планы и их активные тарифы. Или просто клиентские тарифы. Или ставки сотрудников (для сотрудников скидка). Или бизнес против частных клиентов. (тарифные планы могут быть сложными). Дело в том, что базовое представление гарантирует, что наша общая бизнес-логика для тарифных планов и тарифов правильно объединены в одном месте. Следующий уровень представлений дает нам больше внимания конкретным тарифным планам (типам, активным / неактивным и т. Д.).

Я согласен с тем, что представления могут затруднить отладку, если вы создаете запросы и представления одновременно. Но если вы используете проверенное представление, это облегчает отладку. Вы знаете, что представление уже прошло через звонок, поэтому вы знаете, что, скорее всего, это не вызывает проблемы.

Проблемы могут возникнуть с вашими взглядами, хотя. "что если продукт связан только с неактивным тарифным планом?" или "что если тарифный план имеет только неактивные тарифы?" Что ж, это можно поймать на уровне интерфейса с помощью логики, которая ловит ошибки пользователя. Msgstr "Ошибка, продукт на неактивном тарифном плане ... пожалуйста, исправьте". Мы также можем запустить аудит запросов, чтобы дважды проверить его перед выполнением биллинга. (выберите все планы и оставьте соединение с активным представлением тарифного плана, верните только планы, которые не получают активный тарифный план в качестве проблем, требующих решения).

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

редактировать:

В качестве примера того, как представление было бы лучше, чем простой запрос таблиц ... у нас был временный подрядчик, чтобы внести некоторые изменения. Они сказали ему, что есть взгляды на вещи, но он решил сгладить все свои запросы. Биллинг проверял некоторые из его запросов. Они продолжали получать несколько тарифных планов и ставок на вещи. Оказывается, в его запросах отсутствовали критерии, позволяющие ставкам выставлять счета только в том случае, если они находились между датами начала и окончания, в которые тарифный план должен был использовать эти / эти ставки во время. К сожалению. Если бы он использовал вид, он бы уже учел эту логику.

По сути, вы должны взвесить производительность против здравомыслия. Может быть, вы можете сделать все возможное, чтобы повысить производительность базы данных. Но, если это означает, что для нового человека это кошмарный переход, то стоит ли это того? Действительно ли стоит новому парню, который должен сыграть в заблуждение, чтобы найти все запросы, которые должны изменить их логику (и рискнуть, что он забудет / проглотит их), потому что кто-то решил, что взгляды "плохие" и разве не объединена какая-то основная бизнес-логика в такую, которая могла бы использоваться в сотнях других запросов? Это действительно зависит от вашего бизнеса и вашей команды IT / IS / DB. Но я бы предпочел ясность и консолидацию из одного источника, а не производительность.


4

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


0

В моей среде мы копируем множество таблиц с рабочего сервера на сервер отчетов. На сервере отчетов у нас есть множество представлений, основанных на реплицированных производственных таблицах и вложенных. Перед началом репликации мы должны удалить все представления, чтобы сделать возможной репликацию (мы используем отбрасывание и создание, потому что структура таблиц часто изменяется в рабочей среде). После окончания репликации мы должны перестроить все представления.

Теперь вот забавная часть: поскольку многие представления вложены, мы должны перестроить их в определенном порядке. При внесении любых изменений в определение представлений мы должны обратить внимание, чтобы сохранить правильный порядок перестроения. Это полный беспорядок. Я настоятельно не рекомендую использовать вложенные представления, если вы используете репликацию или просто удаляете и перестраиваете свои таблицы, которые являются источником для представлений.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.