Коллеги, хотел бы предложить вам описание решений, которые помогли в проекте миграции большого приложения с SQL Server на MariaDB/MySQL. Возможно, это поможет кому-то в подобном проекте.
Что мы не сделали
Функционал MariaDb/MySQL, скажем так.меньше, чем у SQL Server, но в этом проекте мне не пришлось сталкиваться с такими аспектами, как:
- миграция аналитики, построенной на базе SSAS;
- или процессы ETL с использованием SSIS;
- Полнотекстовый поиск уже реализован на Apache SOLR (как и должно быть сделано).
Что мы сделали
- Была схема на 150 таблиц и ~20 представлений;
- > 900 процедур;
- рекурсивный CTE (рекурсивные общие табличные выражения);
- работа с XML;
- табличные параметры;
- динамический SQL;
- аналитические функции (например — ROW_NUMBER() OVER()), которых нет в MariaDb, но иногда всё же можно что-то сделать.
;
- и, конечно же, UNIQIDENTIFIER в качестве кластерного индекса для значительной части таблиц (и почему некоторые разработчики так любят этот тип данных?
А также модифицируем DAC (уровень доступа к данным), чтобы приложение работало с SQL Server и MariaDb.
Основные проблемы
Самой большой проблемой было преобразование процедур просто потому, что их было очень много.Никто всерьез не рассматривал возможность перехода на NHybernate или другой ORM; процедуры были полны логики и переносить ее на бизнес-уровень никто не собирался (вы уже правильно догадались, что приложение на .
NET).
Что было хорошо
Принципиальная осуществимость проекта заключалась в том, что синтаксис T-SQL и синтаксис процедур MariaDb/MySQL аналогичны и существовала теоретическая возможность автоматизации процедур преобразования.По крайней мере, для тривиальных случаев CRUD. Мне особенно понравилось то, что из процедур в MariaDb/MySQL можно возвращать несколько наборов результатов, как и в T-SQL. Мне всегда было интересно, почему разработчики Oracle или PostgreSQL не предоставили такую простую функцию.
То есть простой оператор SELECT * FROMusers в конце процедуры приводит к чтению ее результата в DAC на стороне клиента.
Причём это может быть любое количество операторов SELECT, не перенаправленных в таблицу (INSERT INTO.SELECT) или в переменную (SELECT.INTO.) и даже не обязательно в конце процедуры.
И конечно, помогли написанные ранее интеграционные тесты.
Если у вас их нет, есть повод подумать о том, чтобы записать их по мере продвижения проекта.
Чем больше охват тестов функциональности ЦАП, тем больше вероятность того, что проект будет успешным.
Кстати, MySQL и MariaDb можно установить и на Windows, но лучше начинать разработку непосредственно на Linux. В Linux есть более качественная инструментальная среда (вроде того же Percona Toolkit) и вы сразу столкнетесь с проблемой корректной сортировки идентификаторов, а точнее имен таблиц.
Например, в Linux запрос SELECT * FROM users и SELECT * FROM Users — это совсем не одно и то же.
Поскольку данные таблицы находятся в файлах, а в Unix/Linux файловая система чувствительна к регистру.
И, что неудивительно, MariaDb работает быстрее внутри виртуальной машины Linux, чем на хосте Windows в качестве «родной» службы Windows. Судя по всему, MySQL не имеет ничего общего с этой замечательной настольной операционной системой.
Начнем с самого простого — что делать с XML?
Приложение использовало XML следующим образом:- Передается как параметры процедуры и возвращается в наборах результатов.
Решение простое: мы используем тип данных LONGTEXT вместо XML, с Oracle MySQL NET Connector все работает нормально.
- Извлечено из параметров сбора данных XML. Это был подход в коде, и он использовался вместе со списками, разделенными запятыми, и параметрами с табличными значениями ( https://msdn.microsoft.com/en-us/library/bb510489.aspx ) где и как, история продукта была долгая.
- Использовались конструкции вида SELECT .
FOR XML.
- XML в полях таблицы был изменен непосредственно в процедуре.
Конструкции типа –UPDATE table1 SET field1.modify(.
)
Сбор данных в параметрах XML
Вообще в MariaDb/MySQL есть функция ExtractValue, которая может выполнять XPath для XML-документа, переданного в параметрах как BLOB, и возвращает результат в виде текста.
SELECT ExtractValue('<a><b>Brown Seal</b></a>', '/a/b/text()')Другой вопрос, а что, если вам дали XML-документ, содержащий некий набор значений и размеров, вы об этом не знаете? Как определить, сколько элементов в коллекции? А как удалить конкретный элемент коллекции? Для подсчета элементов в XPath существует функция count(), которая может возвращать количество элементов XML, соответствующих определенному выражению XPath. ( http://www.w3schools.com/xpath/xpath_functions.asp )
SELECT ExtractValue('<a><b>Brown</b><b>Seal</b></a>', 'count(/a/b)')После того, как мы определили количество элементов в коллекции, мы можем написать XPath для получения определенного элемента.
SELECT ExtractValue('<a><b>Brown</b><b>Seal</b></a>', '/a/b[1]/text()')и цикл для получения всех элементов коллекции.
CREATE PROCEDURE `sproc1` (Теги: #.
NET #mariadb #sql-сервер #MySQL #MySQL #.
NET
-
10 Советов По Рекламе С Оплатой За Клик
19 Oct, 24 -
Вышла Первая Бета-Версия Клиента Adium 1.4
19 Oct, 24 -
Бюджетный Летний Интернет
19 Oct, 24 -
Инструкции — Odin Thunderbird На Двух Ос
19 Oct, 24 -
Что Нового В Intelij Idea 2016.3 Eap
19 Oct, 24