¿Crear función en la base de datos central o repetir en cada base de datos?

8

Uno de mis desarrolladores ha escrito una función SQL que funciona como la función VB.Net (LastIndexOf) y quiere publicarla. Mi pregunta es ¿cuál sería la razón para poner esto en una base de datos central en lugar de ponerlo en la base de datos de cada usuario?

El desarrollador estaba tratando de ponerlo en el esquema sys en su master db para no tener que calificar las llamadas desde las bases de datos de los usuarios ... suspiro

Pero no estaba seguro de cuál sería la excusa válida para centralizarla (obviamente, no la base de datos maestra) frente a la base de datos de cada usuario.

David George
fuente
1
Creo que la idea detrás de esto puede ser algo así como '¿Qué harías en el caso de una corrección de error hipotética? ¿Ir a cada base de datos y arreglar cada copia por separado?
dezso
1
La sobrecarga administrativa es irrelevante aquí porque puedo actualizar todas las bases de datos tan fácilmente como una sola base de datos
David George
¿Y su desarrollador lo sabe? :) Y probablemente él / ella siente que implementa una funcionalidad tan básica que debe estar en el núcleo.
dezso
Si. Esa es mi pregunta, ¿debería algo que podría considerarse núcleo ser parte de la base de datos del usuario o compartido entre todas las bases de datos desde una única base de datos común?
David George
Sí, traté de presentar dos argumentos más o menos válidos a favor de la centralización. Creo que puede ser más bien una cuestión de política o de su gusto personal: es claro por la redacción que no le gusta la idea.
dezso

Respuestas:

12

La forma en que prefiero hacer esto: poner la función en una base de datos de utilidades y crear un sinónimo en cada base de datos regular. De esta manera obtienes lo mejor de ambos mundos:

  1. solo hay una copia del objeto para mantener
  2. el desarrollador no tiene que proporcionar nombres de tres o cuatro partes

p.ej

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

Esto es especialmente poderoso para las funciones de CLR, ya que existe una sobrecarga administrativa adicional para cambiarlas / implementarlas.

Y esto es preferible a usar master (y marcar como un objeto del sistema, que no se garantiza que sea reenviable). Sin sysembargo, me encantaría saber cómo su desarrollador espera crear su función en el esquema.

Entiendo que mantener múltiples copias de una función en 500 bases de datos no es realmente más difícil que mantener una sola copia, pero tener múltiples copias es realmente solo un beneficio cuando hay excepciones (por ejemplo, el cliente A quiere que su función maneje NULL de manera diferente, o algo). En cuyo caso, dejaría el sinónimo en todas las demás bases de datos e introduciría una versión especial de la función solo en esa base de datos.

(Esto supone que la función no depende de ningún acceso a datos dentro de la base de datos de un cliente, por supuesto, lo que ciertamente puede complicar las cosas).

Aaron Bertrand
fuente
5

Voy a tener que estar en desacuerdo con Aaron (y la respuesta aceptada).

El enfoque de Aaron es la forma en que me gusta tratar con "cosas de DBA", por ejemplo, secuencias de comandos de mantenimiento. Nunca quisiera hacer esto con una función de biblioteca que sería llamada por una base de datos de usuario.

¿Por qué? Se dirigirá a la base de datos equivalente a DLL Hell .

Versiones incompatibles

... Antes de Windows 2000, Windows era vulnerable a esto porque la tabla de clase COM se compartía entre todos los usuarios y procesos. Solo se puede declarar que un objeto COM, en un archivo DLL / EXE, tiene un ID de clase COM global específico en un sistema. Si algún programa necesitaba crear una instancia de esa clase, obtuvo lo que fuera la implementación actual registrada centralmente. Como resultado, la instalación de un programa que instala una nueva versión de un objeto común puede inadvertidamente interrumpir otros programas que se instalaron previamente.

Instale .net 4.5 en un servidor que ejecute una aplicación .net 2.0 y ¿qué sucede? Nada, su aplicación continúa utilizando el marco 2.0. Actualice su función LastIndexOf en un servidor que aloja 3 bases de datos de aplicaciones (como parte de una actualización de una de ellas) y ¿qué sucede? Los tres ahora están usando la última versión.

La alternativa es el enfoque adoptado por SQL # . Esto se instala en un esquema en cada base de datos de usuario, por lo que puede actualizar de forma segura la base de datos para la Aplicación-X sin arriesgar la estabilidad de la Aplicación-Y.

Si está trabajando en un entorno de gestión de cambios estrictamente controlado, no tendrá otra opción, no puede actualizar un componente compartido sin probar a todos los consumidores del componente. Si está trabajando en un lugar un poco más "rápido y suelto", puede correr el riesgo de romper algo involuntariamente con un parche / actualización.

Mark Storey-Smith
fuente
Permítame presentarle una refutación, ya que parecía querer una y ahora tengo algunos momentos de sobra que no tenía antes. :-) (1) Supuse que el conjunto de bases de datos en cuestión estaban todas relacionadas y no son parte de aplicaciones completamente diferentes. (2) En este caso, no sospecho que exista mucho peligro para una función llamada LastIndexOfa cambiar, mucho menos de una manera que rompa solo algunas de las aplicaciones / bases de datos. Yo diría que es un problema mayor para CLR o funciones verdaderamente centrales / complejas que dan servicio a múltiples aplicaciones. (3) Mi preferencia real sería no utilizar una función para tareas simples.
Aaron Bertrand
1
Siempre da la bienvenida a tus pensamientos, por supuesto :)
Mark Storey-Smith
Hola. Como creador de SQL # , agradezco la mención positiva :-). Sin embargo, debo aclarar que el principal punto de decisión para usar un Esquema separado para todos los objetos SQL # fue crear un espacio de nombres para que no haya conflictos de nombres sin importar dónde se instaló SQL #. Aún así, mencionas un punto que debe tenerse en cuenta con respecto al control de versiones, dependiendo de cómo esté estructurada la aplicación. Personalmente, me gusta tener una base de Utilitydatos para material de biblioteca comúnmente llamado, pero aumenta un poco el riesgo y requiere pruebas exhaustivas.
Solomon Rutzky
0

La respuesta a esta pregunta depende de si estamos hablando de objetos T-SQL u objetos SQLCLR. Hay diferentes (y más) factores a considerar al tratar con objetos SQLCLR.

En términos de objetos T-SQL, ambas respuestas aquí traen puntos válidos. Como se describe en la respuesta de @ Aaron , la base de datos central puede ser bastante útil, y los sinónimos se pueden usar para facilitar que algunas bases de datos apunten al recurso compartido y otras utilicen un recurso local. Pero el punto mencionado en la respuesta de Mark con respecto al aumento del riesgo debido a la dependencia más fuerte no puede ser ignorado.

Sin embargo, si se trata de objetos SQLCLR, primero debe considerar todos los puntos que mencioné en la siguiente respuesta:

¿Cómo utilizar mejor la función CLR desde el punto de vista del rendimiento (repetir dentro de cada DB o tener una función general)?

Solomon Rutzky
fuente