Создать функцию в центральной базе данных или повторить в каждой базе данных?

8

Один из моих разработчиков написал функцию SQL, которая работает как функция VB.Net (LastIndexOf), и хочет опубликовать ее. Мой вопрос заключается в том, что может быть причиной для помещения этого в центральную базу данных, а не в базу данных каждого пользователя?

Разработчик пытался поместить его в схему sys на своей главной базе данных, чтобы ему не пришлось проверять вызовы к нему из пользовательских баз данных ... вздох

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

Дэвид Джордж
источник
1
Я думаю, что идея может быть чем-то вроде «Что бы вы сделали в случае гипотетического исправления? Перейти к каждой базе данных и исправить каждую копию отдельно?
Дезсо
1
Затраты на администрирование здесь неактуальны, потому что я могу обновлять все базы данных так же легко, как одну базу данных
Дэвид Джордж
А ваш разработчик знает об этом? :) И, вероятно, он / она чувствует, что он реализует такую ​​базовую функциональность, что он должен быть в самом ядре.
Дезсо
Да. Это мой вопрос, должно ли что-то, что может считаться основным, быть частью пользовательской базы данных или совместно использоваться всеми базами данных из единой общей базы данных?
Дэвид Джордж
Да, я попытался представить два более или менее обоснованных аргумента в пользу централизации. Я думаю, что это скорее вопрос политики или вашего личного вкуса - из формулировок ясно, что вам не нравится эта идея.
Dezso

Ответы:

12

Способ, которым я предпочитаю делать это: поместить функцию в базу данных утилит и создать синоним к ней в каждой обычной базе данных. Таким образом, вы получаете лучшее из обоих миров:

  1. существует только одна копия объекта для поддержки
  2. разработчик не должен предоставлять имена из трех или четырех частей

например

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

Это особенно полезно для функций CLR, поскольку для их изменения / развертывания требуются дополнительные административные издержки.

И это намного предпочтительнее, чем использование master (и маркировка как системный объект, который не всегда переносится вперед). Хотелось бы узнать, как ваш разработчик рассчитывает создать свою функцию в sysсхеме.

Я понимаю, что поддерживать несколько копий функции в 500 базах данных на самом деле не сложнее, чем поддерживать одну копию, но наличие нескольких копий действительно выгодно, когда у вас есть исключения (например, клиент A хочет, чтобы его функция по-разному обрабатывала NULL, или что-то). В этом случае я бы оставил синоним во всех других базах данных и ввел специальную версию функции только в этой базе данных.

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

Аарон Бертран
источник
5

Я собираюсь не согласиться с Аароном (и принятым ответом).

Подход Аарона - это то, как мне нравится иметь дело с «вещами DBA», например, сценариями обслуживания. Я никогда не хотел бы делать это с библиотечной функцией, которая будет вызываться пользовательской базой данных.

Почему? Вы отправитесь в базу данных, эквивалентную DLL Hell .

Несовместимые версии

... До Windows 2000 Windows была уязвима для этого, потому что таблица классов COM была общей для всех пользователей и процессов. Только один объект COM в одной DLL / EXE может быть объявлен как имеющий определенный глобальный идентификатор класса COM в системе. Если какой-либо программе требовалось создать экземпляр этого класса, она получала любую централизованно зарегистрированную реализацию. В результате установка программы, устанавливающей новую версию общего объекта, может непреднамеренно нарушить работу ранее установленных программ.

Установите .net 4.5 на сервер, на котором работает приложение .net 2.0, и что происходит? Ничего, ваше приложение продолжает использовать фреймворк 2.0. Обновите функцию LastIndexOf на сервере, где размещены 3 базы данных приложений (в рамках обновления до одной из них), и что происходит? Все трое сейчас используют последнюю версию.

Альтернативой является подход, принятый в SQL # . Он устанавливается в схему в каждой пользовательской базе данных, поэтому вы можете безопасно обновить базу данных для Application-X, не рискуя стабильностью Application-Y.

Если вы работаете в жестко контролируемой среде управления изменениями, у вас не будет выбора, вы не сможете обновить общий компонент без тестирования всех потребителей этого компонента. Если вы работаете где-то немного более «быстро и свободно», вы можете рискнуть непреднамеренно сломать что-то с помощью патча / обновления.

Марк Стори-Смит
источник
Позвольте мне представить опровержение, так как вы, казалось, хотели, и теперь у меня есть несколько свободных моментов, которых у меня не было раньше. :-) (1) Я предположил, что набор рассматриваемых баз данных был связан и не является частью совершенно разных приложений. (2) В этом случае я не подозреваю, что существует большая опасность для функции, вызываемой LastIndexOfк изменению, и тем более, что она нарушает только некоторые приложения / базы данных. Я бы сказал, что это большая проблема для CLR или действительно центральных / сложных функций, которые обслуживают несколько приложений. (3) Я бы предпочел вообще не использовать функцию для простых задач.
Аарон Бертран
1
Всегда приветствую ваши мысли, конечно :)
Марк Стори-Смит
Привет всем. Как создатель SQL # я ценю положительное упоминание :-). Тем не менее, я должен уточнить, что основной точкой решения для использования отдельной схемы для всех объектов SQL # было создание пространства имен, чтобы не было конфликтов имен независимо от того, где установлен SQL #. Тем не менее, вы поднимаете вопрос, который необходимо учитывать при управлении версиями, в зависимости от структуры приложения. Лично мне нравится иметь UtilityБД для обычно называемых библиотечных вещей, но это немного увеличивает риск и требует тщательного тестирования.
Соломон Руцкий
0

Ответ на этот вопрос зависит от того, говорим ли мы об объектах T-SQL или объектах SQLCLR. Существуют различные (и более) факторы, которые следует учитывать при работе с объектами SQLCLR.

Что касается объектов T-SQL, оба ответа здесь дают действительные баллы. Как описано в ответе @ Aaron , центральная БД может быть очень удобной, и можно использовать синонимы, чтобы упростить для некоторых БД указание на общий ресурс, а для некоторых - на локальный ресурс. Но вопрос, поднятый в ответе Марка относительно повышенного риска из-за более сильной зависимости, нельзя игнорировать.

Однако, если вы имеете дело с объектами SQLCLR, то сначала вам нужно рассмотреть все моменты, о которых я говорил в следующем ответе:

Как лучше использовать функцию CLR с точки зрения производительности (повторять внутри каждой БД или иметь общую функцию)?

Соломон Руцкий
источник