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

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

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

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

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

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

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

Идеи?

Ответ 1

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

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

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

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

  • Создана новая область навыков для организации "моя организация".
  • Умение добавляется в центральную базу данных и связано с репликой "my org"
  • Событие SkillAreaExists также добавляется одновременно к RSS-коду "my org" с данными JSON или XML, определяющими свойства новой области навыков
  • Добавлена ​​новая программа в только что созданную область навыков.
  • Программа добавляется в центральную базу данных и связана с областью навыков
  • Событие ProgramExists также добавляется одновременно к RSS-коду "my org" с данными JSON или XML, определяющими свойства новой программы.
  • Событие SkillAreaHasProgram также добавляется одновременно к RSS-коду "my org" с данными JSON или XML, указывающими идентификатор области навыков и программы
  • Агент клиента проверяет канал RSS и видит новые сообщения и обрабатывает их в порядке
  • Когда событие SkillAreaExists обрабатывается, новая область умения добавляется в локальную БД
  • Когда событие ProgramExists обрабатывается, новая программа добавляется в локальную БД
  • Когда обрабатывается событие SkillAreaHasProgram, программа связана с областью навыков

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

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

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

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

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

Ответ 5

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

Если вы действительно хотите получить фантазию, зашифруйте файл после его замены и измените расширение. Я предполагаю, что вы используете ASP для своего SaaS, и поскольку я PHP-geek, я не могу сильно помочь с кодовым аспектом, но способ, которым я занимался раньше, был для script, который упакует весь сайт 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, которая объединяет структуру базы данных и сохраняет рекреационный script в $result, который затем может быть выведен в файл.

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

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

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

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

Надеюсь, что это поможет;)

Ответ 6

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

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

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

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

Ответ 7

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

Ответ 8

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

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

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

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

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

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

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

Ответ 9

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

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

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

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

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

Аравиндом