Criar função no banco de dados central ou repetir em cada banco de dados?

8

Um dos meus desenvolvedores escreveu uma função SQL que funciona como a função VB.Net (LastIndexOf) e deseja publicá-la. Minha pergunta é qual seria o motivo para colocar isso em um banco de dados central versus colocá-lo em cada banco de dados do usuário?

O desenvolvedor estava tentando colocá-lo no esquema sys em seu mestre db, para que ele não tivesse que qualificar chamadas a partir de bancos de dados de usuários ...

Mas não tinha certeza de qual seria a desculpa válida para centralizá-lo (obviamente, não o banco de dados mestre) versus cada banco de dados de usuários?

David George
fonte
11
Eu acho que a ideia por trás disso pode ser algo como 'O que você faria no caso de uma correção hipotética? Ir para cada banco de dados e corrigir todas as cópias separadamente?
Dezso
11
Administração sobrecarga é irrelevante aqui, porque eu posso atualizar todos os bancos de dados tão facilmente como um único banco de dados
David George
E seu desenvolvedor sabe sobre isso? :) E provavelmente ele / ela sente que implementa uma funcionalidade tão básica que deve estar no centro.
Dezso
Sim. Essa é minha pergunta: algo que possa ser considerado essencial deve fazer parte do banco de dados do usuário ou ser compartilhado entre todos os bancos de dados de um único banco de dados comum?
David George
Sim, tentei apresentar dois argumentos mais ou menos válidos em favor da centralização. Acho que pode ser uma questão de política ou de seu gosto pessoal - é claro pelas palavras que você não gosta da ideia.
Dezso

Respostas:

12

A maneira como prefiro fazer isso: coloque a função em um banco de dados utilitário e crie um sinônimo para ele em cada banco de dados regular. Dessa forma, você obtém o melhor dos dois mundos:

  1. existe apenas uma cópia do objeto para manter
  2. o desenvolvedor não precisa fornecer nomes de três ou quatro partes

por exemplo

USE UtilityDB;
GO
CREATE FUNCTION dbo.LastIndexOf(...) ...
GO
USE otherDB;
GO
CREATE SYNONYM dbo.LastIndexOf FOR UtilityDB.dbo.LastIndexOf;
GO

Isso é especialmente poderoso para as funções CLR, pois há uma sobrecarga administrativa extra para alterar / implantar essas funções.

E é preferível usar o mestre (e marcar como um objeto do sistema, que não é garantido para ser portátil para a frente). Eu adoraria saber como seu desenvolvedor espera criar sua função no sysesquema.

Entendo que manter várias cópias de uma função em 500 bancos de dados não é mais difícil do que manter uma única cópia, mas ter várias cópias é realmente apenas um benefício quando você tem exceções (por exemplo, o cliente A deseja que sua função manipule NULLs de maneira diferente, ou alguma coisa). Nesse caso, eu deixaria o sinônimo em todos os outros bancos de dados e apresentaria uma versão especial da função somente nesse banco de dados.

(Isso pressupõe que a função não depende de nenhum acesso a dados no banco de dados de um cliente, é claro - o que certamente pode complicar as coisas.)

Aaron Bertrand
fonte
5

Vou ter que discordar de Aaron (e a resposta aceita).

A abordagem de Aaron é a maneira como gosto de lidar com "coisas de DBA", por exemplo, scripts de manutenção. Eu nunca iria querer fazer isso com uma função de biblioteca que seria chamada por um banco de dados do usuário.

Por quê? Você estará indo para o equivalente de banco de dados da DLL Hell .

Versões incompatíveis

... Antes do Windows 2000, o Windows era vulnerável a isso porque a tabela de classes COM era compartilhada entre todos os usuários e processos. Somente um objeto COM, em uma DLL / EXE, pode ser declarado como tendo um ID de classe COM global específico em um sistema. Se algum programa precisasse criar uma instância dessa classe, obteria a implementação atual registrada centralmente. Como resultado, uma instalação de um programa que instala uma nova versão de um objeto comum pode inadvertidamente interromper outros programas que foram instalados anteriormente.

Instale o .net 4.5 em um servidor executando um aplicativo .net 2.0 e o que acontece? Nada, seu aplicativo continua usando a estrutura 2.0. Atualize sua função LastIndexOf em um servidor que hospeda 3 bancos de dados de aplicativos (como parte de uma atualização para um deles) e o que acontece? Todos os três agora estão usando a versão mais recente.

A alternativa é a abordagem adotada pelo SQL # . Isso é instalado em um esquema em cada banco de dados do usuário, para que você possa atualizar com segurança o banco de dados do Aplicativo-X sem arriscar a estabilidade do Aplicativo-Y.

Se você estiver trabalhando em um ambiente de gerenciamento de mudanças rigidamente controlado, não terá escolha, não poderá atualizar um componente compartilhado sem testar todos os consumidores do componente. Se você estiver trabalhando em algum lugar um pouco mais "rápido e solto", poderá correr o risco de quebrar algo sem querer com um patch / atualização.

Mark Storey-Smith
fonte
Deixe-me fazer uma refutação, já que você parecia querer uma e agora tenho alguns momentos de sobra que não tinha antes. :-) (1) Assumi que o conjunto de bancos de dados em questão era todo relacionado e não faz parte de aplicativos completamente diferentes. (2) Nesse caso, não suspeito que exista muito perigo para uma função chamada LastIndexOfmudar, muito menos de uma maneira que interrompa apenas alguns aplicativos / bancos de dados. Eu diria que é um problema maior para o CLR ou funções verdadeiramente centrais / complexas que atendem a vários aplicativos. (3) Minha preferência real seria não usar nenhuma função para tarefas simples.
Aaron Bertrand
11
Sempre bem-vindos os seus pensamentos, é claro :)
Mark Storey-Smith
Olá. Como criador do SQL # , agradeço a menção positiva :-). No entanto, devo esclarecer que o principal ponto de decisão para o uso de um esquema separado para todos os objetos do SQL # era criar um espaço de nome para que não houvesse conflitos de nomes, não importa onde o SQL # estivesse instalado. Ainda assim, você menciona um ponto que precisa ser considerado em relação à versão, dependendo de como o aplicativo está estruturado. Pessoalmente, eu gosto de ter um Utilitybanco de dados comumente chamado de material de biblioteca, mas aumenta um pouco o risco e requer testes completos.
Solomon Rutzky
0

A resposta para esta pergunta depende se estamos falando de objetos T-SQL ou objetos SQLCLR. Existem diferentes (e mais) fatores a serem considerados ao lidar com objetos SQLCLR.

Em termos de objetos T-SQL, as duas respostas aqui trazem pontos válidos. Conforme descrito na resposta do @ Aaron , o DB central pode ser bastante útil, e o Sinônimos pode ser usado para facilitar o fato de alguns DBs apontarem para o recurso compartilhado e outros usarem um recurso local. Mas o ponto levantado na resposta de Mark em relação ao aumento do risco devido à dependência mais forte não pode ser ignorado.

No entanto, se você estiver lidando com objetos SQLCLR, primeiro precisará considerar todos os pontos que levantei na resposta a seguir:

Como usar melhor a função CLR do ponto de vista do desempenho (repita dentro de cada banco de dados ou tenha função geral)?

Solomon Rutzky
fonte