Известно, что многие администраторы упорно отказываются использовать среду CLR в своих базах данных. Они не признают никаких ее достоинств и не прислушиваются к доводам группы разработчиков относительно возможности более эффективной работы в компилированном CLR-коде, а просто повторяют одно слово: НЕТ. До появления версии v12 такой же была позиция компании Microsoft в отношении базы данных SQL Azure. Теперь она изменилась.
В длинном списке достоинств T-SQL (https://msdn.microsoft.com/library/azure/ee336281.aspx) есть одна важная фраза: cборки среды CLR с безопасным двоичным разрядом. Однако в не очень длинном списке неподдерживаемых компонентов T-SQL есть другая фраза: сборки среды CLR. Так что же? Сборки поддерживаются или нет?
Прежде чем продолжить, позволю себе небольшое отступление. Почему вы не используете CLR? Вероятно, я нетипичный администратор баз данных: в прошлом я был разработчиком. Я смотрю на них как на друзей и коллег, а не как на врагов (хотя мои друзья и коллеги иногда бывают излишне упрямы и недостаточно компетентны). Я не только верю в их благие намерения, но давно понял, что они отлично знают свое дело. Кроме того, если учесть, что поведение определенных типов программного кода SQL Server, и в частности T-SQL, может быть весьма неоднозначным, я вполне готов признать, что CLR — приемлемый вариант. Мне лишь однажды довелось увидеть CLR в производственной среде, и результат был превосходным. Возможность применения CLR следует всерьез обдумать при решении уникальных задач, с которыми трудно справиться с помощью T-SQL, таких как списки соседства (adjacency list) для моделирования иерархий. Я предоставлю объяснить это Адаму Михнику (http://sqlblog.com/blogs/adam_machanic/archive/2015/04/07/re-inventing-the-recursive-cte.aspx).
А теперь вернемся к Azure. Вы можете добавить CLR к базе данных SQL Azure, если работаете с версией v12. Но при этом необходимо обеспечить как безопасность, так и двоичность. Никакие другие типы сборок не поддерживаются. Помните, вы работаете с базой данных на платформе SQL Server, а не с экземпляром сервера. Просто база данных. Что означает «безопасность» для CLR? Существует три уровня ограничений (https://msdn.microsoft.com/library/ms403273.aspx) в коде CLR: UNSAFE, EXTERNAL_ACCESS, SAFE. Я не собираюсь подробно рассказывать обо всех особенностях каждого типа. Достаточно сказать, что правила SAFE — самые строгие. Код запускается внутри сборки CLR, но не может вызвать внешний процесс любого типа и выполняется только внутри вашей базы данных. Совершенно здравый подход, учитывающий принципы работы базы данных SQL Azure.
Следующий вопрос — двоичность. Суть в том, что вы не можете передать файл, у вас нет доступа к серверу. Таким образом, чтобы создать сборку, нужно преобразовать библиотеку DLL, созданную для обработки CLR, в двоичный файл. Сделать это можно с помощью различных способов, документированных в нескольких источниках. По адресу: benschwehn.wordpress.com/2007/10/07/generate-create-assembly-from-binary-bits-script/приведен способ для PowerShell. А по адресу: azure.microsoft.com/en-us/documentation/articles/sql-database-create-assembly-on-azure-with-csharp/ — для T-SQL.
Далее все просто. Необходимо создать сборку:
CREATE ASSEMBLY MyAssemblyName AUTHORIZATION dbo FROM 0x0 WITH PERMISSION_SET = SAFE; GO
В этом примере двоичный файл является просто представителем.
Затем нужно создать функцию, которая будет использовать сборку. Вот пример из сценариев упомянутого выше Адама Михника:
CREATE FUNCTION [dbo].[hierarchy_enqueue_inner] ( @id [int], @payload [nvarchar](4000) ) RETURNS [int] AS EXTERNAL NAME [hierarchy_navigator]. [UserDefinedFunctions].[hierarchy_enqueue_inner] GO
После этого можно начинать использовать T-SQL для вызовов, направляемых к CLR-коду. И не забудьте, что работа ведется в базе данных SQL Azure.
Вернемся к сценарию Адама. С его разрешения я загрузил копию программного кода и запустил его в своей базе данных версии 12. Код функционировал почти безупречно. В отличие от Адама, я не получил в итоге параллельный план. Вероятно, различия объясняются особенностями работы оптимизатора запросов в Azure. Вы можете уточнить свойства плана (см. экран).
Экран. Свойства плана |
Значение EstimatedDOPIsOne содержится в NonParallelPlanReason, что вызывает удивление, если заметить, что предполагаемая стоимость поддерева (Estimated Subtree Cost) равна 987 789. Исследование параллелизма и его поведения внутри базы данных SQL Azure — еще одна увлекательная задача на будущее.
Многие администраторы не работают со средой CLR внутри SQL Server, но некоторые признали наличие в ней полезных функций, превосходящих возможности SQL Server. Вам потребуется код CLR. Если его удастся запустить в режиме SAFE, то можно создать сборку в базе данных SQL Azure, которая будет работать точно так же, как программный код Адама работал у меня. Таким образом, платформа как услуга будет дополнена еще одним уровнем функциональности для организации реляционного хранилища внутри Azure.