在工作中,對於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能力 - 儘管公司中的其他團隊工作方式有所不同,併爲數據庫團隊提供了更多的工作。
謝謝aragnid。在我們公司,開發人員的角色也包括創建適當的模式補丁。一個進程用於實際處理補丁。 我喜歡schema_version表的想法,我們已經在我的工作場所討論過,並且看到你使用了一個,並驗證了這一點。 – chadl 2009-05-30 17:21:34