Приложение SaaS должно экспортировать / резервировать данные на отдельные сайты клиентов

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

все наши данные приложения хранятся в одной базе данных MS SQL. На самом верху " иерархии "мы имеем"организация". Эта организация представляет единственного клиента в нашей системе. Каждая организация имеет много дочерних таблиц/объектов/данных. Каждый имеющий ФК отношения, которые, в конечном счете, в "Организация."

нам нужен способ, чтобы извлечь один данные клиента из базы данных и связать его каким-то образом, так что он может быть загружен на сайт клиентов. Предпочтительно в SQL Express, SQLite или базе данных access.

например: Organization -> Skill Area -> Program -> Target -> Target Data все таблицы в системе. Каждый возвращаясь к родителя в ФК. Мне нужно получить все целевые данные, цели, программы и области навыков для каждой организации и экспортировать эти данные.

тут у кого-нибудь есть предложения о том, как это сделать в SQL Server, службе C# или инструменте 3-й партии?

Мне нужно, чтобы это решение было легко реплицировать для каждого клиента, который хочет, чтобы эта функция "включена"

идеи?

9 ответов


Я большой поклонник использования обмена сообщениями для распространения данных на данный момент, поэтому вот решение на основе сообщений, которое позволит внешним клиентам сохранять локальную, синхронизированную копию данных, которые вы предоставляете в интернете.

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

есть куча различных способов сделать компонент на основе списка системы, но моя интуиция чувствует, что вам лучше всего использовать что-то вроде RSS для этого.

Ниже приведен практический сценарий того, как это может работать:

  1. создается новая область навыков для организации "моя организация"
  2. навык добавляется в центральную базу данных и ассоциируется с" my org " reccord
  3. событие SkillAreaExists также добавляется одновременно в RSS "моя организация" с данными JSON или XML, указывающими свойства новой области навыков
  4. в только что созданную область навыков добавляется новая программа
  5. программа добавляется в центральную базу данных и ассоциируется с областью навыков
  6. В ProgramExists событие также добавляется одновременно в RSS "моя организация" с данными JSON или XML, указывающими свойства новой программы
  7. событие SkillAreaHasProgram также добавляется одновременно в RSS "моя организация" с данными JSON или XML, указывающими идентификатор области навыков и программы
  8. агент клиента проверяет RSS-канал и видит новые сообщения и обрабатывает их в порядке
  9. при обработке события SkillAreaExists добавляется новая область навыков локальный DB
  10. при обработке события ProgramExists в локальную БД добавляется новая программа
  11. при обработке события SkillAreaHasProgram программа связана с областью навыков

этот подход имеет целую кучу преимуществ по сравнению с традиционной точкой репликации времени.

  • его онлайн, потребитель этого может получить обновления в реальном времени, если требуется
  • Consistancy поддержано заказом, в любой момент внутри время в потоке событий если вы перестаете получать события, у вас есть локальная БД, которая точно отражает центральную БД как в какой-то момент времени.
  • его разница основана, вам нужно только получить изменения
  • его прослушиваемый, вы можете видеть, что на самом деле произошло не только текущее состояние.
  • его легко восстановить, если есть проблема согласованности данных, вы можете вернуть всю БД, повторив поток событий.
  • оно учитывает множественных потребителей, серии отдельные копии информации о клиентах могут существовать и функционировать автономно.

У нас был большой успех с этими методами для репликации данных между сайтами, особенно когда они только иногда в интернете.


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

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

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

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

другие параметры могут заключаться в копировании данных в базу данных scratch, а затем просто создании резервной копии SQL этой базы данных.

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

в облачной среде это особенно важно, потому что вы хотите иметь возможность развертывания как можно быстрее. Если есть много конфигурации, которая должна быть сделана, вы, вероятно, сделаете ошибки или просто будьте непоследовательны. При создании развертывания nuke-and-repave у вас есть одна точка, которую вы можете изменить установку и конфигурацию, зная, что изменение будет согласованным в любом развертывании.


насколько я понимаю, у вас есть одна большая база данных для всех клиентов, вы используете отношения, которые приводят к организации таблицы, чтобы узнать, какие данные для какого клиента, и вы хотите создать резервную копию данных на основе client => organization.

для резервного копирования данных можно использовать один из следующих методов:



когда мне приходилось иметь дело с резервными копиями реляционных данных в прошлом (в MySQL, который не очень отличается с точки зрения возможностей от MSSQL, который вы используете), это создать резервный файл "пакета", который по существу является zip-файлом с другим расширением файла, чтобы windows не позволяла пользователям открывать его.

Если вы действительно хотите получить фантазии, зашифровать файл после сжать его и изменить расширение. Я предполагаю, что вы используете ASP для своих SaaS, и поскольку я PHP-выродок, я не могу помогите слишком много с кодовой стороной вещей, но то, как я справлялся с этим раньше, было для скрипта, который упаковал бы весь сайт Joomla и базу данных для миграции на новый сервер.

//open the MySQL connection
$dbc = mysql_connect($cfg->host,$cfg->user,$cfg->password);
//select the database
mysql_select_db($cfg->db,$dbc);

output( 'Getting database tables

');

//get all the tables in the database
$tables = array();
$result = mysql_query('SHOW TABLES',$dbc);
while($row = mysql_fetch_row($result)) {
    $tables[] = $row[0];
}

output( 'Found '.count($tables).' tables to be migrated.
Exporting tables:
');

$return = "";

//cycle through the tables and get their create statements and data
foreach($tables as $table) {
    $result = mysql_query('SELECT * FROM '.$table);
    $num_fields = mysql_num_fields($result);

    $return.= 'DROP TABLE IF EXISTS '.$table.";\n";
    $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
    $return.= $row2[1].";\n";

    while($row = mysql_fetch_row($result)) {
        $return.= 'INSERT INTO '.$table.' VALUES(';
        for($j=0; $j<$num_fields; $j++) {
            $row[$j] = mysql_escape_string($row[$j]);
            $row[$j] = ereg_replace("\n","\n",$row[$j]);
            if (!empty($row[$j])) {
                $return.= "'".$row[$j]."'" ;
            } else {
                $return.= "NULL";
            }
            if ($j<($num_fields-1)) {
                $return.= ',';
            }
        }
        $return.= ");\n";
    }
}

это соответствующая часть кода в PHP, которая петляет структуру базы данных и сохраняет сценарий восстановления в $result, который затем может быть выведен в файл.

в вашем случае, вы не хотите, чтобы воссоздать базы данных, а сами данные. Вы усугубили проблема немного, так как у вас есть SaaS, который склонен к возможным изменениям структуры данных, которые вам нужно будет учитывать. Тогда я предложил бы следующее:--2-->

используйте аналогичную систему для сброса соответствующих данных из отдельных таблиц. Я просто вытаскиваю все данные, но вы можете вытащить только те части, которые относятся к отдельному пользователю, используя операторы JOIN и еще много чего. Сбросьте содержимое инструкций insert/replace каждой таблицы в файл с именем таблица. Создайте файл с именем manifest.XML или что-то в этом роде и заполнить его с текущей версией вашего приложения SaaS, наименование/информация, уникальный идентификатор и т. д. клиента экспорта данных.

упакуйте все эти файлы в ZIP-файл, измените расширение на все, что хотите, зашифруйте его, если хотите, и т. д. Пусть они скачают этот файл резервной копии, и все готово.

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

надеюсь, что это помогает ;)


поскольку вы храните все данные только в одной базе данных, всегда будет трудно экспортировать / резервное копирование данных на основе клиента.

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

Я бы рекомендовал вам разделить данные, скажем, с помощью базы данных для каждой организации. Затем измените приложение только один раз (в основном вокруг создания строки подключения для указанной организации), а затем вы можете безопасно экспортировать/резервное копирование каждой базы данных отдельно так, как вы хотите.

Это также дает вам много дополнительных преимуществ "бесплатно", таких как масштабируемость и возможность выделять ресурсы на базе каждой организации (если это необходимо в будущем). Скажем, у вас есть набор малых и низкоприоритетных (с точки зрения бизнеса) организаций, а также большой и высокоприоритетный. Так вы будет иметь возможность сохранить набор небольших баз данных с низким приоритетом на одном сервере, но посвятить другой для этого конкретного важного большого. Или если ваш текущий сервер БД перегружен (возможно, у вас много данных и много запросов к базе данных), вы можете просто получить еще один дешевый сервер и перенести половину груза без каких-либо изменений в вашей системе... Вам все равно нужно что-то написать, чтобы разделить существующую большую базу данных на несколько маленьких, но вы делаете это только один раз, и после этого сделанный этот "инструмент миграции" может быть выброшен, поэтому вам больше не нужно его поддерживать.


вы пробовали SyncFramework? Взгляните на этой статьи! В нем объясняется, как синхронизировать отфильтрованные данные между базами данных с помощью Sync Framework. Вы можете синхронизировать с базой данных клиента или синхронизировать с собственной пустой БД, а затем экспортировать ее в файл.


вы думали об использовании ORM? (Объектно-Реляционный Картограф)

Я знаю и использую LLBLGen Pro (поэтому я могу говорить только об особенностях этого конкретного ORM)
В любом случае, с LLBLGen вы можете реверсивно спроектировать БД и создать иерархию классов, которые отображают таблицы и отношения вашей БД.

теперь, если все данные клиента доступны через отношения, я могу сказать моей ORM framework, чтобы загрузить одного клиента (1 строка определенной таблицы) , а затем загрузите все связанные данные в связанную таблицу.

Если данные не слишком сложны, это должно быть возможно.
Если у вас есть сотни таблиц с собственными ссылками или странные отношения, это может быть невозможно, это зависит от ваших данных.

Если все данные одного клиента, скажем, 10 000 строк в 100 таблицах, это, вероятно, будет работать.
Если все данные составляют 100 '000 строк в 1000 таблицах, это "может" работать, если у вас есть несколько раз и много памяти.
Если все данные это 10 ' 000 ' 000 вы, вероятно, не можете загрузить все это сразу, и вам понадобится более эффективный способ.

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

использование ORM для загрузки и экспорта всех данных одного клиента, как объясняется, вероятно, не самое эффективный способ делать вещи, но когда реально это простой и дешевый способ.
Естественно, с ORM или без него, вы можете найти сотни различных способов экспорта этих данных: -)


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

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

для этого вам нужно отсортировать таблицы на основе отношения FK и создать их в базе данных temp.

затем выберите данные таблицы из исходной базы данных и вставьте их в temp база данных.

вы также можете использовать этот метод, чтобы разбить базу данных и обновить дизайн базы данных.

Аравинд