2008-08-27 62 views
32

這似乎是一個可以真正使用一些見解的被忽略的區域。什麼是您的最佳做法:如何管理對生產數據庫的模式升級?

  • 使升級過程
  • 在錯誤
  • 同步代碼和數據庫的情況下打了退堂鼓變化
  • 部署之前測試修改表
  • 力學

etc ...

+0

我很驚訝沒有更多的答案在這裏 - 也許需要特定的oracle或sqlserver標籤? – 2009-11-11 13:10:24

+0

不錯的主意,謝謝! – 2009-11-11 23:22:04

回答

3

這是一個很好的問題。 (這很有可能會導致規範化與非規範化的數據庫爭論......我不會開始......現在可以進行一些輸入。)

有些脫離我頭腦的東西我(當我有更多的時間或需要休息時將增加更多)

客戶端設計 - 這是內聯sql的VB方法(甚至準備好語句)讓你陷入困境。您可以花AGES找到這些陳述。如果你使用像Hibernate這樣的東西,並將儘可能多的SQL放入命名查詢中,那麼對於大多數sql來說,只有一個位置(沒有比試圖測試某些IF語句內部的sql更糟糕的事情,而且你不會觸及「觸發器」您對該IF語句進行測試的標準)。當我直接在JDBC或ODBC中執行SQL時,在使用hibernate(或其他orms')之前,我會將所有的sql語句作爲對象的公共字段(使用命名約定)或屬性文件中(也使用命名約定的值爲PREP_STMT_xxxx。使用反射或在啓動時迭代a)測試用例b)啓動應用程序(某些rdbms允許您在執行前用預準備語句進行預編譯,所以在啓動後登錄I將在啓動時預編譯準備工作,以使應用程序自我測試,即使是在一個好的rdbms上只有幾秒鐘,也只有一次的100個語句,並且它已經節省了很多。在一個項目中,DBA不會溝通(一個不同的團隊,在不同的國家),模式似乎沒有理由改變。每天早上,我們都會在啓動時收到一份清單,說明它打破了應用程序的位置。

如果你需要adhoc功能,把它放在一個很好命名的類(即一個命名約定有助於自動配對測試),作爲某種工廠供你查詢(即建立查詢)。無論如何,你將不得不編寫相應的代碼,只需放在一個可以測試的地方。你甚至可以在同一個對象上或者在一個單獨的類中編寫一些基本的測試方法。

如果可以,還嘗試使用存儲過程。他們有點難以像上面那樣測試。有些db也不會在運行時在編譯時根據模式預先驗證存儲過程中的sql。它通常涉及說取一個模式結構的副本(沒有數據),然後創建所有存儲的特效對這個副本(如果數據庫團隊進行更改DID不正確驗證)。因此可以檢查結構。但作爲一個變化點管理存儲過程是偉大的。在變化都得到它。特別是當數據庫更改是業務流程更改的結果時。並且所有的語言(java,vb等都會得到這個改變)

我通常還會設置一個我使用的名爲system_setting的表格等。在這個表格中我們保留一個VERSION標識符。這樣,客戶端庫可以連接並驗證它們是否適用於此版本的模式。根據對模式的更改,如果客戶端可能會損壞模式(例如,數據庫中沒有大量的參照規則,但在客戶端上),則不希望允許客戶端進行連接。這取決於你是否也有多個客戶端版本(這在非網絡應用中發生,即它們運行錯誤的二進制文件)。你也可以有批處理工具等。我也做過的另一種方法是在某種屬性文件中或在system_info表中再定義一組操作版本的操作版本。這個表在登錄時加載,然後由每個「管理器」(我通常有某種客戶端API做大多數數據庫的東西)來驗證該操作,如果它是正確的版本。因此大多數操作都可以成功,但是你也可能會失敗(拋出一些例外)過時的方法,並告訴你爲什麼。

管理對模式的更改 - >你更新表或添加1-1關係到新表嗎?出於這個原因,我看到很多商店總是通過視圖訪問數據。這允許表名改變,列等。我玩過的觀點實際上像COM中的接口一樣處理。即。您爲新功能/版本添加了新的VIEW。通常情況下,您在這裏得到的是您可以擁有許多假設表格格式的報告(特別是最終用戶自定義報告)。視圖允許您部署新的表格格式,但支持現有的客戶端應用程序(請記住所有討厭的特別報告)。

另外,需要編寫更新和回滾腳本。並再次測試,測試,測試...

------------ OKAY - 這是一個位有限的討論時間--------------

實際上有一個大型商業項目(即軟件商店),我們遇到了同樣的問題。該架構是一個2層,他們使用的產品有點像PHP,但在pre-php。一樣。不同的名字。無論如何,我進來版本2 ....

這是花了很多錢做升級。很多。即。現場免費提供數週的諮詢時間。

而它正在想要添加新功能或優化代碼。一些現有的代碼使用了存儲過程,所以我們有共同點來管理代碼。但其他地區是這個嵌入式的標記在HTML中。這對於迅速進入市場很有好處,但每次新功能的交互都會使成本至少增加一倍以便測試和維護。因此,當我們考慮將php類型代碼拉出來時,將數據層(2001-2002,任何ORM等)放入數據層並添加大量新功能(客戶反饋)來查看如何設計UPGRADES進入系統。這是一件大事,因爲升級需要花費大量金錢才能正確執行。現在,大多數模式和所有其他人都在討論一定程度的能量處理OO代碼,但是你的數據必須與這個邏輯相結合,b)意義和結構數據會隨着時間而改變,而且通常由於數據的工作方式,最終會在客戶組織中產生大量需要該數據的子流程/應用程序 - >即席報告或任何複雜的自定義報告以及批處理作業已經完成了自定義數據饋送等。

考慮到這一點,我開始玩點左邊的東西。它也有一些假設。 a)數據嚴重超出了寫入的範圍。 b)更新確實發生,但不在銀行級別,即。一秒鐘或二秒鐘說。

這個想法是將一個COM /接口視圖應用於客戶端通過一組CONCRETE表訪問數據的方式(隨架構變化而變化)。您可以爲每個類型操作創建一個單獨的視圖 - 更新,刪除,插入和讀取。這個很重要。這些視圖可以直接映射到一個表格,也可以讓你觸發一個真正的更新或插入的虛擬表格等。我真正想要的是某種可以被水晶報告等使用的可捕獲級別間接方式。 - 對於插入,更新和刪除你也可以使用存儲的特效。你有一個版本的每個版本的產品。這樣你的1.0版本就有了它的模式版本,如果表格改變了,你仍然可以使用1.0版本的VIEWS,但是新的後端邏輯根據需要映射到新表格,但是你也有2.0版本的視圖支持新的領域等。這實際上只是爲了支持臨時報告,如果您的業務人員而不是編碼人員可能是您擁有產品的原因。 (您的產品可能是廢話,但如果您擁有世界上最好的報告,您仍然可以獲勝,但事實恰恰相反 - 您的產品可能是最好的功能,但如果報告更差,您可以輕鬆放棄)。

好的,希望其中的一些想法有所幫助。

+6

這是如何成爲公認的答案?它如何回答原始問題中的觀點? – 2009-11-11 13:04:31

4

一般而言,我的規則是:「應用程序應該管理它自己的模式。」

這意味着模式升級腳本是應用程序的任何升級包的一部分,並在應用程序啓動時自動運行。如果發生錯誤,應用程序無法啓動並且升級腳本事務未提交。這樣做的缺點是應用程序必須對模式進行完整的修改訪問(這讓數據庫管理員很煩惱)。

使用Hibernates SchemaUpdate功能來管理表結構,我取得了巨大的成功。讓升級腳本只處理實際的數據初始化和偶爾刪除列(SchemaUpdate不會這樣做)。

關於測試,由於升級是應用程序的一部分,因此測試它們成爲應用程序測試周期的一部分。事後思考:考慮到其他職位的一些批評,請注意規則說「它是自己的」。它只適用於應用程序擁有架構,通常與作爲產品銷售的軟件一樣。如果您的軟件與其他軟件共享數據庫,請使用其他方法。

4

我是Red Gate產品的粉絲,幫助創建SQL包來更新數據庫模式。可以將數據庫腳本添加到源代碼管理中,以幫助進行版本控制和回滾。

2

這些都是重要的主題,但這裏是我的更新建議。

您沒有指定您的平臺,但對於我使用的NANT構建環境Tarantino。對於準備提交的每個數據庫更新,您都可以創建更改腳本(使用RedGate或其他工具)。當你生產到生產時,Tarantino會檢查腳本是否已經在數據庫上運行(它向你的數據庫添加一個表來跟蹤)。如果沒有,腳本運行。它將所有手動工作(讀取:人爲錯誤)從管理數據庫版本中取出。

8

liquibase.org:

  1. 它理解冬眠的定義。
  2. 它會產生更好的架構更新SQL比冬眠
  3. 其升級已對數據庫
  4. 它處理兩個步驟的改變它的日誌(即刪除列「富」,然後重命名不同的列到「富「)
  5. 它處理條件升級的概念
  6. 開發人員實際上傾聽社區(如果您不在」人羣中「或新手 - 您基本上被忽略,則使用hibernate。)

http://www.liquibase.org

6

意見

應用程序應該從未處理架構更新。這是一場等待發生的災難。數據超過了應用程序,並且一旦多個應用程序嘗試使用相同的數據(例如生產應用程序+報告應用程序) - 他們可能會使用相同的基礎公司庫......然後,這兩個程序決定做自己的數據庫升級...與混亂。

0

正如帕特說,使用liquibase。特別是當您有幾個開發人員使用他們自己的開發數據庫 進行將成爲生產數據庫一部分的更改時。

如果只有一個開發工具,就像我現在在一個項目上一樣(ha),我只是將模式更改作爲SQL文本文件提交到一個CVS回購庫中,我在生產服務器上批量檢出代碼更改進入。

但是liquibase組織比這更好!