2012-02-08 47 views
11

我們有一個基於雲的SaaS應用程序,我們的許多客戶(學校系統)都要求他們的數據備份存儲在現場。SaaS應用程序需要將數據導出/備份到單個客戶站點

我們所有的應用程序數據都存儲在一個MS SQL數據庫中。在「層次結構」的最頂端,我們有一個「組織」。該組織代表我們系統中的單個客戶。每個組織都有許多子表/對象/數據。每個都有FK關係,最終以「組織」結束。

我們需要一種方法從數據庫中提取客戶的數據並將其以某種方式打包,以便將其下載到客戶站點。最好在SQL Express,SQLite或訪問數據庫中。

例如:Organization -> Skill Area -> Program -> Target -> Target Data是系統中的所有表。每個人都通過FK鏈接回父母。我需要獲得每個組織的所有目標數據,目標,計劃和技能範圍並導出該數據。

有沒有人有任何關於如何在SQL Server,C#服務或第三方工具中執行此操作的建議?

我需要這個解決方案很容易複製,誰想要這個功能每一位客戶「開啓」

想法?

+1

這是僅用於嚴格備份還是恢復? – 2012-02-08 18:05:10

+4

爲什麼不能使用ssis爲每個組織創建備份? – Phil 2012-02-08 18:06:59

+0

@KrisIvanov如果我們公司或我們的數據發生了變化,他們只需要恢復它。它只是爲了讓他們感覺數據安全。 – 2012-02-08 18:09:39

回答

4

我用短信的那一刻以傳輸數據的大風扇,所以這裏是一個基於消息的解決方案,將允許外部客戶保留本地,同步複製您在網絡上提供的數據。

基本架構將是一個在線密碼保護和用戶特定的系統中發生的變化列表。 在服務器端,此列表將隨任何時候對與特定客戶相關的實體發生更改而被追加。 客戶端將運行一個應用程序,該應用程序檢查尚未收到的更改列表,然後將其應用於其本地數據庫(按照它們發生的順序)。

有很多不同的方式來做基於列表的系統組件,但我的直覺是你最好使用像RSS這樣的東西來做到這一點。

下面是如何這可能是工作實際情況下:

  1. 一項新技術領域爲組織「我的組織」
  2. 技能被添加到中央數據庫中創建和與之相關聯的「我的組織」 reccord
  3. 一個SkillAreaExists事件也同時加入到‘以JSON或XML數據指定新的技能領域的屬性我的組織’RSS
  4. 一個新的程序添加到那是技能領域剛剛創建
  5. 程序將被添加到中央數據庫,並與技能領域,同時也被添加到「我的組織」 RSS
  6. 一個ProgramExists事件與JSON或XML數據指定新程序的屬性相關
  7. SkillAreaHasProgram事件也同時添加到具有JSON或XML數據的「my org」RSS中,該數據指定了技能區和程序的標識符
  8. 客戶端代理檢查RSS提要並查看新消息並處理它們
  9. 當處理SkillAreaExists事件時,將新的技能區域添加到本地數據庫中
  10. 當處理一個新的程序添加到本地數據庫
  11. 當SkillAreaHasProgram事件處理程序鏈接到技能領域

這種方法的好處比傳統的點一大堆的ProgramExists事件及時複製。

  • 它的網絡,如果需要的話
  • 相合是爲了維持,在事件流中的任何時間點,如果你停止接收事件,你有一個本地數據庫,其accuratly反映了這個消費者可以得到實時更新中央數據庫在某個時間點。
  • 它的差異化基礎上,你只需要接收變化
  • 它的可審計,你可以看到實際發生的不只是當前的狀態。
  • 它很容易恢復,如果有數據一致性問題,您可以通過重放事件流來恢復整個數據庫。
  • 它允許多個消費者,許多客戶端信息的單獨副本可以存在並自主運行。

我們在這些技術之間複製數據的技術非常成功,尤其是當它們僅在有時在線時。

0

據我所知,你有一個大數據庫的所有客戶端,你使用關係導致表組織知道哪些數據爲哪個客戶端,並且你想要備份基於客戶端=>組織的數據。

要備份您可以使用下列方法之一的數據:

0

當我不得不應付過去關係型數據的備份(在MySQL中是不是超級不同,從你正在運行MSSQL能力方面)是創建一個備份「包」文件,它基本上是一個帶有不同文件擴展名的zip文件,這樣windows就不會讓用戶打開它。

如果您確實想要看到它,請在壓縮文件後對其進行加密並更改擴展名。我認爲你正在爲你的SaaS使用ASP,並且因爲我是一個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語句和類似的東西來只抽取與個人用戶有關的部分。將每個表的insert/replace語句的內容轉儲到一個以該表命名的文件中。創建一個名爲manifest.xml的文件或類似的東西,並使用您的SaaS應用程序的當前版本,名稱/信息,唯一ID等導出數據。

將所有這些文件打包到一個ZIP文件中,將擴展名更改爲任何你想要的,如果你想加密它,等等。讓他們下載該備份文件,然後設置好。

在您的導入腳本中,您需要讀取導出數據的版本號,並將其與某些算法進行比較,該算法可以根據稍後修訂的數據重新處理數據。這樣,如果您稍後需要重新導入其中一個備份,則可以正確處理將數據從將備份拉到當前表中數據的當前結構時進行轉換。

希望幫助;)

0

因爲你一直在短短一個數據庫中的所有數據,它總是會很難出口客戶的基礎上/備份數據。

即使您現在實現了這樣的場景,每次更改數據庫模式(修復錯誤,添加新功能,優化等)時,最終都需要維護/更改/測試兩個不同的位置。

我建議你通過使用每個組織的數據庫對數據進行分區。然後,您只需更改一次應用程序(主要是爲指定組織創建連接字符串),然後您可以按照您希望的方式單獨安全地導出/備份每個數據庫。

它還爲您提供了許多免費的額外好處,例如可擴展性和爲每個組織基礎(無論將來是否需要)貢獻資源的能力。 假設您從一個小型和低優先級(從業務角度)組織,並且是一個高優先級的組織。因此,您將能夠在一臺服務器上保留一組小型低優先級數據庫,但爲該特定的重要數據庫專用另一臺。 或者如果你當前的數據庫服務器過載(也許你有很多的數據和大量的數據庫請求),你可以簡單地獲得另一個便宜的服務器,並移動一半的負載,而無需對系統進行任何更改... 你仍然需要編寫一些東西來將現有的大型數據庫拆分成幾個小型數據庫,但是你只需要做一次,在完成這個「遷移工具」後就可以拋棄,所以你不需要再支持它了。 。

0

你試過SyncFramework? 看看this文章! 它解釋瞭如何使用Sync Framework在數據庫之間同步過濾的數據。 您可以同步到客戶數據庫或同步到您自己的空白數據庫,然後將其導出爲文件。

0

您是否想過使用ORM? (對象關係映射)

我知道和使用,LLBLGEN臨(所以我只能對這個特定的ORM的功能交談)
無論如何,與LLBLGEN你可以反向工程數據庫,並創建類的層次結構映射您的數據庫的表和關係。

現在,如果客戶的所有數據都可以通過關係到達,那麼我可以告訴我的ORM框架加載一個costumers(1行特定表),然後加載相關表中的所有相關數據。

如果數據不太複雜,應該是可以的。
如果您有數百個自引用表或奇怪關係,它可能是可撤銷的,它取決於您的數據。

如果單個客戶的所有數據都是100個表中的10000行,那麼它可能會工作。
如果1000個表中的所有數據都是100000行,那麼如果你有一些時間和大量的內存,它可能會工作。
如果所有數據都是10'000'000,那麼您可能無法一次加載全部數據,您需要更有效的方法。

無論如何,如果你可以一次加載所有的數據,那麼你將擁有一個很好的「內存」圖表和一個客戶的所有數據,然後你可以序列化這些數據,或者將它投影到數據集(獲取一組數據表/關係),然後序列化數據集。

如上所述,使用ORM加載和導出單個客戶的所有數據可能不是最有效的做事方式,但是當可行時,這是一種簡單而廉價的方式。
當然,有或沒有的ORM,你可以找到數百種不同的方式將此數據導出:-)

1

雖然有已經提出了一些非常有趣的企業解決方案,我覺得我的做法是開發簡單地導出數據,每個組織有一個存儲過程或只是一個數字select語句的平面原來的定期備份解決方案。

誠然,你必須保持這個最新的數據庫模式的變化,但如果這是一個生產應用程序我不能想象這種情況發生非常顯着。

有任何數量的可用做這個技術,無論是SSIS,自定義窗口服務,甚至一些基本的如作爲命令行揭開序幕存儲過程的計劃任務。

選擇導出到格式完全取決於你或許應該由備份打算如何使用驅動。我可能會考慮將數據寫入多個CSV文件並壓縮結果,以便在需要時將其導入其他平臺。

其他選項可能是將數據複製到臨時數據庫,然後只需創建該數據庫的SQL備份。

但是你選擇去這件事,我會鼓勵你,以確保過程是有據可查的,並儘可能多的自動化安裝和設置成爲可能。具有鬆散耦合依賴性的系統(如常見文件位置或計劃任務)容易隨着時間的推移而進行調整和更改。如果沒有記錄這些調整和更改,您可以創建一個可以工作但無法複製的系統。很快沒有人想要觸摸它,也沒有人記得它是如何工作的。當它最終需要改變時,或者更糟糕時,它必須開始逆向工程,然後才能修復它。

在基於雲的環境中,這尤其重要,因爲您希望能夠儘快進行部署。如果需要完成很多配置,你可能會犯錯或者只是不一致。通過創建一個nuke-and-repave部署,您可以單點更改安裝和配置,因爲知道這些更改在任何部署中都是一致的。

0

對於您的設計,您應該爲客戶分解數據庫。

但是,因爲你已經開發了數據庫設計,我建議你創建一個臨時數據庫,並在創建使用FK關係這個臨時數據庫中的新表。

爲此,您需要根據FK關係對錶格進行排序並在臨時數據庫中創建它們。

然後,從源數據庫中選擇表格數據並將它們插入到臨時數據庫中。

您也可以使用此技術來分割數據庫並修改數據庫設計。

Aravind

相關問題