SaaS-приложение должно экспортировать / резервировать данные на сайты отдельных клиентов - PullRequest
11 голосов
/ 08 февраля 2012

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

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

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

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

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

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

Идеи?

Ответы [ 9 ]

4 голосов
/ 19 февраля 2012

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

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

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

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

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

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

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

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

1 голос
/ 19 февраля 2012

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

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

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

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

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

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

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

0 голосов
/ 05 марта 2012

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

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

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

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

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

Аравиндом

0 голосов
/ 18 февраля 2012

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

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

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

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

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

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

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

0 голосов
/ 17 февраля 2012

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

0 голосов
/ 17 февраля 2012

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

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

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

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

0 голосов
/ 17 февраля 2012

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

Если вы действительно хотите стать модным, зашифруйте файл после его архивирования и измените расширение. Я предполагаю, что вы используете 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, который подвержен возможным изменениям структуры данных, которые вы должны учитывать. Мое предложение будет следующим:

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

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

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

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

0 голосов
/ 16 февраля 2012
0 голосов
/ 14 февраля 2012

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

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

...