2017-06-01 31 views
0

免責聲明:這是一個有點「最佳做法」的問題,但我不知道怎麼回事,這樣的措辭更具體的或喚起一個更客觀的答案。如何更新與來自另一個數據庫中的數據MySQL數據庫?

我有一個小型Rails項目的兩個數據庫:一個dev數據庫和一個prod數據庫,位於同一臺服務器上。

會發生什麼事是,每隔幾個星期,我提出通過通過開發Rails環境的ActiveAdmin寶石dev的數據庫中的一些數據的變化(主要是插入)。我圍繞着Rails應用程序來確保新數據看起來不錯。當我準備好部署,我運行一個腳本:

  1. 轉儲dev分貝
  2. 刪除並重新創建prod分貝刪除所有數據
  3. 進口dev分貝轉儲到prod分貝

我的直覺告訴我,這不是一個很好的解決方法,它也有點慢,但我似乎無法找到從一個數據庫到另一個數據庫進行數據部署的標準方式。標準方式是什麼,如果有的話?

事情我已經考慮:

  • 設置附加數據庫是開發數據庫的副本;在部署中,以某種方式切換Rails應用程序以使用副本作爲「prod」,將舊的「prod」db更新爲副本等等。我幾乎無法將這個想法保留在我的腦海中,而且看起來像這樣一團糟。
  • 做直接督促,完全無效的dev的數據庫,需要數據的變化(感覺很總值)
  • 通過SQL腳本做數據的變化與開發事務,並把它們部署在督促(它會是真的,真的很煩人手工編寫這些腳本)

一些其他注意事項:那些做過都是我做

  • 架構更改完成

    • 唯一的數據變化通過Rails遷移
    • 的數據庫相對較小(最大的表是約1000行)
  • +0

    在相關問題上,您是否在「2.刪除並重新創建數據庫以刪除所有數據」之前備份生產數據庫?如果你不這樣做,那麼我認爲你的數據庫只是「只讀」的? ...您的Rails應用程序頁面沒有創建/更新記錄的表單? –

    +0

    @ Jay-ArPolidario是的,我在刪除/重新創建它之前做了prod db的備份,但是,數據庫是RO。沒有任何形式可以創建/更新記錄。 –

    回答

    2

    如果您在同一臺服務器上的兩個數據庫,你可以比較並插入到表中。首先,對於刪除的行:

    BEGIN TRAN; 
    DELETE FROM prod.tbl1 
    WHERE id IN (
    SELECT id FROM dev.tbl1 RIGHT JOIN prod.tbl1 ON dev.tbl1.id = prod.tbl1.id WHERE dev.tbl1.id IS NULL); 
    COMMIT; 
    

    其次,對於新行:

    BEGIN TRAN; 
    INSERT INTO prod.tbl1 
    SELECT * 
    FROM dev.tbl1 
    WHERE id IN (
    SELECT id FROM dev.tbl1 LEFT JOIN prod.tbl1 ON dev.tbl1.id = prod.tbl1.id WHERE prod.tbl1.id IS NULL); 
    COMMIT; 
    

    現在,在你的開發數據庫觸發器來管理更新:

    CREATE DEFINER=`root`@`localhost` TRIGGER `dev`.`tbl1_update` 
    AFTER UPDATE ON `dev`.`tbl1` 
    FOR EACH ROW 
    BEGIN 
        SET NEW.update = '1'; 
    END 
    

    你需要一個「更新「開發表上的字段。當更新查詢在表上運行時,「update」字段將自動更改爲1。然後,使用此查詢:

    BEGIN TRAN; 
    UPDATE prod.tbl1 
    LEFT JOIN dev.tbl1 
        ON prod.tbl1.id = dev.tbl1.id 
    SET prod.tbl1.fld1 = dev.tbl1.fld1, prod.tbl1.fld2 = dev.tbl1.fld2 
    WHERE prod.tbl1.id IN (SELECT id FROM dev.tbl1 WHERE update = '1'); 
    UPDATE dev.tbl1 SET update = '0'; 
    COMMIT; 
    

    您可以在所有表​​上運行這樣的查詢。您可以將它放在.sql文件中並使用cron作業運行(mysql -h -u -D < myscript.sql)。

    此查詢比較表並獲取dev上不存在的ID。然後,對完整的表格執行選擇(僅限這些ID),並將其插入到prod上。

    (用每個表的唯一標識符替換id字段)。

    +0

    數據更新或刪除操作如何? –

    +0

    對於刪除,您可以使用反向查詢進行刪除。我會用那個更新答案。對於數據更新,如果沒有完整的比較來驗證它是不可能的。但是,你可以做到。另一種選擇是,它在數據庫上設置一個「標誌」行,當數據發生變化時,這些標誌將變爲「真」。你可以用觸發器來做到這一點。我也會發布它。 –

    2

    這似乎是一個很奇怪的方法。通常development中的數據被認爲是一次性的。您只需要足夠的數據,以便您可以進行造型和故障排除 - 通常使用僞隨機數據。在開發過程中構建「完成的」應用程序數據似乎很容易出錯,如果您不止一個開發人員,則需要同步工作。

    另外,如果數據集顯着大,由於缺少緩存,Rails開發速度會很慢。

    你想要的是一個分段環境,它與預期的生產相同的設置運行。關鍵在於它應該儘可能接近生產。這可以在遠程服務器或Intranet上的服務器上運行。

    您還可以使用登臺環境向客戶/利益相關者顯示新功能或進度,並讓他們預覽新功能或循環使用開發進度。

    您可以通過複製config/environments/production.rb -> staging.rb並在目標登臺服務器上將RAILS_ENV env var設置爲staging來創建它。

    您還應該在config/database.yml中創建附加部分或使用ENV['DATABASE_URL']

    根據項目的不同,可以每天使用生產中的鏡像數據刷新分區或進行完全同步。

    +0

    這是一個奇怪的方法,但我絕對希望數據能夠「慢慢」生產。這是因爲數據輸入是手動的(不改變這一點)並且容易出錯,所以我想在將數據推到生產之前驗證Rails應用程序中的數據看起來不錯。儘管我很欣賞你的意見,但是分期環境是一個好主意。 –

    +0

    然後,我會明確地使用臨時環境 - 如果可能的話,您希望分離數據輸入和實際代碼開發的概念。 – max

    相關問題