A exibição aninhada é um bom design de banco de dados?


42

Eu li em algum lugar há muito tempo. O livro afirma que não devemos permitir ter uma exibição aninhada no SQL Server. Não tenho certeza do motivo pelo qual não podemos fazer isso ou posso me lembrar de uma declaração incorreta.

Alunos

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

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

Professores

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

Escolas

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

No meu local de trabalho, investiguei um de nossos aplicativos de banco de dados internos. Eu verifiquei os objetos e descobri que há duas ou três camadas da vista. Então isso me lembrou o que li no passado. Alguém pode ajudar a explicar isso?

Se não for possível fazê-lo, quero saber que ele se limita apenas ao SQL Server ou se destina ao design de banco de dados em geral.

Informações adicionais: atualizei um exemplo da minha empresa. Eu mudo um pouco para ser mais geral sem muitas técnicas (muitas colunas neste exemplo). Principalmente a visão aninhada que usamos é baseada em visão abstrata ou agregada. Por exemplo, temos uma grande tabela de alunos com centenas de colunas. Digamos, Eligible Student Viewé baseado em estudantes que se matriculam este ano. E a visão elegível do aluno pode ser usada em outros locais, como no procedimento armazenado.


3
Eu afirmaria que os mesmos prós e contras seriam praticamente iguais, independentemente da plataforma específica.
Aaron Bertrand

Respostas:


47

Independentemente da plataforma, as seguintes observações se aplicam.

(-) Visualizações aninhadas:

  • são mais difíceis de entender e depurar

    Por exemplo, a qual coluna da tabela essa coluna de exibição se refere? Deixe-me vasculhar 4 níveis de definições de visualização ...

  • dificulta o otimizador de consultas para apresentar o plano de consulta mais eficiente

    Veja isto , isto , isto e isto para evidência anedótica. Compare com isso , que mostra que o otimizador geralmente é inteligente o suficiente para descompactar corretamente as visualizações aninhadas e selecionar um plano ideal, mas não sem um custo de compilação.

    Você pode medir o custo de desempenho comparando a consulta de exibição com uma consulta equivalente escrita nas tabelas base.

(+) Por outro lado, as visualizações aninhadas permitem:

  • centralizar e reutilizar agregações ou regras de negócios
  • abstraia sua estrutura subjacente (por exemplo, de outros desenvolvedores de banco de dados)

Eu descobri que eles raramente são necessários.


No seu exemplo, você está usando visualizações aninhadas para centralizar e reutilizar determinadas definições de negócios (por exemplo, "O que é um aluno qualificado?"). Este é um uso válido para visualizações aninhadas. Se você estiver mantendo ou ajustando esse banco de dados, considere o custo de mantê-los e o de removê-los.

  • Manter: ao manter as visualizações aninhadas, você incorre nas vantagens e desvantagens enumeradas acima.

  • Remover: para remover as visualizações aninhadas:

    1. Você precisa substituir todas as ocorrências das visualizações por suas consultas básicas.

    2. Você deve se lembrar de atualizar todas as consultas relevantes se sua definição de aluno / professor / escola elegível mudar, em vez de apenas atualizar a definição de visualização relevante.


1
+1, exceto que eu substituiria "mais difícil" pelo otimizador de consulta por "quase impossível". :)
Jason

1
@ Jason - Eu concordo, e gostaria de poder vincular a alguns exemplos concretos. Você conhece alguma referência que explique ou demonstre por que isso acontece?
Nick Chammas

1
Tudo o que consigo encontrar é uma evidência anedótica de que, quando visualizações aninhadas são usadas, elas sofrem problemas de desempenho em comparação com o SQL "nivelado". sqlservercentral.com/blogs/2cents/archive/2010/04/05/… O problema parece se dever ao fato de que o banco de dados (neste caso, o SQL Server) não aplicará determinados filtros antes de ingressar nas tabelas e, portanto, faça com que a consulta demore mais do que deveria.
Jason

7
Não concordo com o problema do otimizador de consultas, pois a consulta resultante após a resolução de todas as visualizações será a mesma, independentemente de quantas transformações de visualização elas tenham passado (exceto algumas colunas extras nos conjuntos de resultados intermediários, que o otimizador pode eliminar muito bem). Isso deixa a depuração; Na IMO, facilita a depuração de visualizações aninhadas, pois eu posso ver resultados intermediários para ver onde deu errado.
Simon Richter

1
Eu escrevi um servidor de banco de dados incorporado e, para mim, resolver as visualizações primeiro e depois otimizar a consulta resultante era a rota óbvia, pois é realmente improvável que todas as consultas nas visualizações retornem todas as colunas. Não consigo nem pensar em uma razão pela qual a realização de dados de exibição no meio de uma consulta ganharia alguma coisa, de modo que isso foi um acéfalo para mim.
Simon Richter

26

Às vezes, visualizações aninhadas são usadas para impedir a agregação repetida. Digamos que você tenha uma visão que conte as mensagens e agrupe-as por userid, você pode ter uma visão que conte o número de usuários que têm> 100 mensagens, esse tipo de coisa. Isso é mais eficaz quando a visualização base é uma visualização indexada - você não deseja necessariamente criar outra visualização indexada para representar os dados com um agrupamento ligeiramente diferente, porque agora você está pagando pela manutenção do índice duas vezes, onde o desempenho provavelmente está adequado contra a visão original.

Se essas são apenas exibições aninhadas nas quais você seleciona *, mas altera a ordem ou a parte superior, parece que isso seria melhor encapsulado como um procedimento armazenado com parâmetros (ou funções com valor de tabela embutido) do que várias exibições aninhadas. NA MINHA HUMILDE OPINIÃO.


4
"Isso é mais eficaz quando a visualização base é uma visualização indexada." Ponto importante.
Nick Chammas

7

Versões posteriores do SQL (2005+) parecem melhores em otimizar o uso de visualizações. As visualizações são melhores para consolidar regras de negócios. EG: onde trabalho, temos um banco de dados de produtos de telecomunicações. Cada produto é atribuído a um plano de taxa e esse plano de taxa pode ser trocado e as taxas no plano de taxa podem ser ativadas / desativadas à medida que as taxas são aumentadas ou modificadas.

Para facilitar, podemos criar visualizações aninhadas. A primeira visualização une os planos de taxa a suas taxas usando as tabelas necessárias e, retornando os dados necessários, os próximos níveis de visualizações precisariam. A segunda visualização pode isolar apenas os planos de taxas ativos e suas taxas ativas. Ou apenas taxas de clientes. Ou taxas de funcionários (para desconto de funcionários). Ou taxas de clientes comerciais vs. residenciais. (os planos de taxas podem ficar complicados). O ponto é que a visão básica garante que nossa lógica geral de negócios para planos de taxas e taxas sejam unidas adequadamente em um local. A próxima camada de visualizações nos concentra mais em planos de taxas específicos (tipos, ativo / inativo, etc.).

Concordo que as visualizações podem tornar a depuração confusa se você estiver criando consultas e visualizações ao mesmo tempo. Mas, se você estiver usando uma exibição tentou-n-confiável, isso facilita a depuração. Você sabe que a visualização já passou pela campainha e, portanto, provavelmente não está causando o problema.

Problemas podem surgir com seus pontos de vista. "e se um produto estiver associado apenas a um plano de taxas inativo?" ou "e se um plano de taxas tiver apenas taxas inativas?" Bem, isso pode ser pego no nível de front-end com uma lógica que captura erros do usuário. "Erro, o produto está em um plano de taxas inativo ... corrija". Também podemos executar auditorias de consulta para verificar novamente antes da execução do faturamento. (selecione todos os planos e junte-se à visualização da tabela de taxas ativa, retorne apenas os planos que não obtêm uma tabela de taxas ativa como problemas que precisam ser resolvidos).

O bom disso é que as visualizações permitem condensar bastante as consultas de relatórios, cobrança etc. Você pode ter uma visão da conta do cliente e, em seguida, uma visão do segundo nível apenas de clientes ativos. Equipe isso com uma visão do endereço do cliente. Equipe isso com uma visão do (s) produto (s) (associado ao (s) produto (s) que o cliente possui). Equipe isso para visualizar o plano de taxa de produtos. Equipe isso com visão dos recursos do produto. Visualize, visualize, visualize, cada tentativa e erro para garantir a integridade. Sua consulta final usando as visualizações é muito compacta.

editar:

Como um exemplo de como a visualização teria sido melhor do que apenas uma consulta simples de tabelas ... tivemos um contratado temporário para fazer algumas alterações. Eles disseram que havia pontos de vista sobre as coisas, mas ele decidiu aplanar todas as suas perguntas. O faturamento estava impedindo algumas de suas consultas. Eles continuavam recebendo vários planos de taxas e taxas. Acontece que suas consultas não apresentavam critérios para permitir a cobrança de taxas apenas se estivessem entre as datas de início e término em que o plano de taxas deveria usar essas taxas durante essas datas. Opa Se ele tivesse usado a visão, ela já teria levado essa lógica em consideração.

Basicamente, você deve avaliar o desempenho versus a sanidade. Talvez você possa fazer todos os tipos de coisas sofisticadas para aumentar o desempenho de um banco de dados. Mas, se isso significa que é um pesadelo para uma nova pessoa assumir / manter, vale a pena? Realmente vale a pena o cara novo ter que jogar whack-a-mole, ter que encontrar todas as perguntas que precisam para mudar sua lógica (e arriscar que ele as esqueça / mexa com elas) porque alguém decidiu que as vistas são "ruins" e não consolidou alguma lógica de negócios principal em uma que pudesse ser usada em centenas de outras consultas? Depende realmente do seu negócio e da sua equipe de TI / IS / DB. Mas prefiro clareza e consolidação de fonte única a desempenho.


4

O problema real não são visões aninhadas em si mesmas. O problema real é a proliferação de visualizações aninhadas à medida que os desenvolvedores colocam ajustes adicionais nas visualizações existentes. Encontrei consultas com uma vista aninhada 4 camadas que realmente se uniram a uma das vistas em sua definição. Nossa tendência a seguir o caminho mais fácil, em vez de analisar e resolver um problema, é a raiz do problema.


0

No meu ambiente, replicamos muitas tabelas do servidor de produção para o servidor de relatórios. No servidor de relatórios, temos várias visualizações baseadas em tabelas de produção replicadas E aninhadas. Antes do início da replicação, precisamos remover todas as visualizações para possibilitar a replicação (usamos o recurso de soltar e criar porque a estrutura das tabelas geralmente muda na produção). Após o término da replicação, precisamos reconstruir todas as visualizações.

Agora, aqui está a parte divertida: como muitas das visualizações são aninhadas, precisamos reconstruí-las em uma ordem específica. Ao fazer alterações na definição de visualizações, devemos prestar atenção para manter a ordem de reconstrução correta. É uma bagunça total. Eu desencorajo fortemente o uso de visualizações aninhadas se você usar a replicação ou simplesmente eliminar e reconstruir suas tabelas, que são a fonte das visualizações.

Desempenho é outra coisa. As visualizações baseadas em outras visualizações nada mais são do que várias consultas a serem executadas. É mais fácil reunir a consulta maior, criar um trabalho e criar uma tabela com ele. Mais fácil e melhora o desempenho.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.