2009-05-29 101 views
5

我們已經在Postgres中有了一個架構,並且我們希望建立一個應用架構修補程序的好方法。架構修補程序實踐

目前,我們有一系列創建模式,表格,序列,函數等的DDL文件。我們還有一個用於測試環境的人口腳本。這些文件全部用於重新創建我們的數據庫環境,用於開發,測試等。

我們還有許多與我們的系統版本相對應的「補丁」文件。即。 patch/1.0.0.sql,patches/1.0.1.sql等。這些文件用於更新我們的分段和生產數據庫。

這個過程對我們來說目前爲止還是有效的,但是在內部已經有一些辯論如何最好地修補模式。

我很好奇,作爲一個過程,其他人已經有了補丁分段和生產模式以及如何管理數據庫版本的過程。

謝謝!

回答

3

在工作中,對於SQL Server,我們編寫了模式更改腳本,它們首先回滾所做的更改(idempotently,因此即使尚未應用模式更改,回滾段也可以正常運行),然後一節應用更改。在TSQL中,查看系統目錄或其他表很容易查看錶/列/索引/行是否已經存在,如果不存在則不執行任何操作。

在PostgreSQL中,用戶可以簡單地發送到服務器的命令會受到一些限制 - 但另一方面,DDL是事務性的,因此不應發生半應用的模式更改。我已經適應了我習慣於在自己的小項目上使用的方案(矯枉過正,但即使在這裏,我也有一個開發/測試數據庫和一個「真實」分貝),例如:

\echo Rolling back schema change #35 

BEGIN; 

DELETE FROM schema_version WHERE schema_id = 35; 

DROP TABLE IF EXISTS location_coordinates; 
DROP FUNCTION IF EXISTS location_coordinates_populate(); 

END; 

\echo Applying schema change #35 

BEGIN; 

INSERT INTO schema_version(schema_id, description) VALUES(35, 'Add location_coordinates table'); 

CREATE TABLE location_coordinates(
location_id INT PRIMARY KEY REFERENCES location(location_id), 
latitude FLOAT NOT NULL, 
longitude FLOAT NOT NULL, 
earth_coordinates earth NOT NULL, 
box_10miles cube NOT NULL 
); 

GRANT SELECT, INSERT, UPDATE, DELETE ON location_coordinates TO ui; 

CREATE FUNCTION location_coordinates_populate() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$ 
BEGIN 
    new.earth_coordinates := ll_to_earth(new.latitude, new.longitude); 
    new.box_10miles := earth_box(new.earth_coordinates, 10 * 1609.344); 
    RETURN new; 
END 
$$; 

CREATE TRIGGER location_coordinates_populate BEFORE INSERT OR UPDATE ON location_coordinates 
FOR EACH ROW EXECUTE PROCEDURE location_coordinates_populate(); 

INSERT INTO location_coordinates(location_id, latitude, longitude) 
SELECT location_id, latitude, longitude FROM location WHERE latitude IS NOT NULL AND longitude IS NOT NULL; 

CREATE INDEX location_coordinates_10miles ON location_coordinates USING gist (box_10miles); 

END; 

\echo Done 

只需使用「psql -f schema-changes/35.sql」就可以在數據庫上運行此腳本。通過切斷「應用...」消息,我可以得到命令將其回滾。正如您所看到的,更改維護了一個元數據表「schema_version」,以便我可以看到應用了哪些更改。整個變更都是以交易,數據遷移等方式完成的。在這裏,我使用了DROP命令的「IF EXISTS」功能,即使未應用更改時,也可以使回滾部分快樂。 Istr我們在爲Oracle工作時所做的一件事就是將模式更改編寫爲PL/SQL--您可能在plpgsql中有一些功能來幫助進行更改?請注意,在上述變化中,我將「緯度」和「經度」列(可爲空)從「位置」移出到單獨的「location_coordinates」關係(並添加了earthdistance內容) ,我沒有放棄舊的專欄。我們必須小心的一件事是儘可能使模式更改向後兼容。所以我可以在之前應用此架構更改更新應用程序以使用新表。我需要進行第二次更改,以在更新應用後刪除舊列以應用。在工作中,這些將在兩個不同的發佈週期中完成,因此在發行版X期間,我們仍然可以選擇回滾應用程序以發佈X-1,而無需首先回滾所有架構更改;以及能夠在應用程序之前的單獨窗口中部署模式更改。 (從技術上說,我應該寫一個觸發器,以便更新到舊錶同步到新表,但我沒有因爲這太像工作:))

我們也有類似的應用程序蜘蛛所有我們數據庫以查看schema_version表中的內容,並跟蹤更改,以便人們甚至可以查看未進行連接時所做的更改,並瞭解每次更改的歷史記錄(我們跟蹤「在開發中回滾」,「應用於dev「等)。在工作中,我們的schema_version表格還包含作者信息等等。從版本控制中應用版本信息的一種神奇方式將會很酷 - 我們的一個問題是,如果SC在QA中應用,那麼在Perforce中更改,可能不會一個通知。因此,追蹤該模式更改的方法35修訂版#4應用將會很好。

有一點需要注意 - 我們的模式更改是獨立於應用程序版本編號的。顯然他們是相關的 - 這是蜘蛛程序允許人們進入的另一件事情---但我們嘗試進行很多小變化而不是巨人「這裏是X版的所有內容」補丁。模式更改也用於添加新索引等內容,因此可能根本無法使用應用程序。一般而言,模式更改由開發人員「擁有」,而不是DBA--儘管在上面的「創建索引」示例中,DBA基本上扮演開發人員角色並擁有模式更改。是的,我們堅持從開發人員那裏獲得高水平的SQL能力 - 儘管公司中的其他團隊工作方式有所不同,併爲數據庫團隊提供了更多的工作。

+0

謝謝aragnid。在我們公司,開發人員的角色也包括創建適當的模式補丁。一個進程用於實際處理補丁。 我喜歡schema_version表的想法,我們已經在我的工作場所討論過,並且看到你使用了一個,並驗證了這一點。 – chadl 2009-05-30 17:21:34