2011-11-17 101 views
1

我剛剛開始使用PostgreSQL,並且我是數據庫設計的新手。在PostgreSQL中創建「表格表」或實現類似的功能?

我在寫軟件,其中有更新數據庫的各種插件。每個插件都定期更新自己在數據庫中的指定表。所以名爲'KeyboardPlugin'的插件將更新'KeyboardTable','MousePlugin'將更新'MouseTable'。我希望我的數據庫能夠存儲這些'插件表'關係,同時強制引用完整性。所以,理想情況下,我想用下面列的配置表:

  1. 插件名稱(類型「文本」)
  2. 表名(β型)

我的軟件會讀取從此配置表中幫助插件確定要更新哪個表。最初,我的想法是讓第二列(表名)爲'text'類型。但是,如果有人錯誤地輸入了表名,或者現有的關係由於某人刪除表而變得無效,我們就會遇到問題。我希望'表名'列作爲另一個表的引用,同時強制引用完整性。

在PostgreSQL中這樣做的最好方法是什麼?隨意建議一種全新的方式來設置我的數據庫,這與我目前正在探索的不同。另外,如果它可以幫助你回答我的問題,我正在使用pgAdmin工具來設置我的數據庫。

我感謝您的幫助。

+1

請不要爲每個單獨的插件使用表格。標準化功能,儘可能少地使用表格。 [EAV](http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model)是靈活性的常見解決方案 –

+0

有趣!這可能很方便。在我深入研究之前,我想知道在這個模型下是否會有一種方法來獲得TYPES屬性。從我對該文章的簡要介紹中,我瞭解我的問題是我將創建一個Attribute表,第一列提及此屬性適用的插件(鏈接到插件表),第二列是'value '的屬性。這意味着每個屬性都將具有相同的數據類型,我會將其設置爲「文本」,然後進行投射。那麼沒有類型呢? – Dalal

+0

其實我困惑自己。第一列將是屬性名稱,第二列將是它所屬的插件。我會更多地瞭解它,看看我能否解決這個問題。 – Dalal

回答

1

我會與您原來的計劃去存儲名稱爲文本。通過附加地存儲所述架構名稱可能增強:

addin text 
,sch text 
,tbl text 

表系統中的目錄(pg_catalog.pg_class)具有OID。你可以得到那些有nifty special cast

SELECT 'myschema.mytable'::regclass 

OID可以通過改變轉儲/恢復。所以只需將名稱存儲爲文本,並通過在應用程序時演示它來驗證表格是否存在。

當然,如果你使用多個加載項的每個表可能付出做一個單獨的表

CREATE TABLE tbl (
,tbl_id serial PRIMARY KEY 
,sch text 
,name text 
); 

,並引用它...

CREATE TABLE addin (
,addin_id serial PRIMARY KEY 
,addin text 
,tbl_id integer REFERENCES tbl(tbl_id) ON UPDATE CASCADE ON DELETE CASCADE 
); 

,甚至使它正:m關係如果插件有多個表。但請注意,正如@OMG_Ponies所評論的那樣,像這樣的設置將需要您執行大量動態SQL,因爲您事先不知道標識符。

+0

存儲表名可確保使用動態SQL。 –

+0

這看起來很整齊。但有了這個,我還不是依靠我的軟件來驗證表格是否存在?沒有辦法將約束綁定到數據庫本身,以便嘗試將表引用存儲到不存在的表將自動失敗?我的系統將處理許多插件,我不希望它開始變得sl。。 – Dalal

1

我猜所有插件都有一組基本屬性,然後每個插件都會有一組插件特有的屬性。如果出現這種情況,可以將單個表與hstore數據類型(僅需要安裝的標準擴展)一起使用。

事情是這樣的:

CREATE TABLE plugins 
(
    plugin_name    text not null primary key, 
    common_int_attribute  integer not null, 
    common_text_attribute text not null, 
    plugin_atttributes  hstore 
) 

然後,你可以做這樣的事情:

INSERT INTO plugins 
(plugin_name, common_int_attribute, common_text_attribute, hstore) 
VALUES 
('plugin_1', 42, 'foobar', 'some_key => "the fish", other_key => 24'), 
('plugin_2', 100, 'foobar', 'weird_key => 12345, more_info => "10.2.4"'); 

這將創建一個名爲plugin_1兩個插件和plugin_2

Plugin_1有附加屬性 「some_key」和「other_key」,而plugin_2存儲關鍵字「weird_key」和「more_info」。

您可以索引這些hstore列並非常有效地查詢它們。
以下將選擇所有定義了「weird_key」鍵的插件。

SELECT * 
FROM plugins 
WHERE plugin_attributes ? 'weird_key' 


下面的語句將選擇具有一鍵some_key與價值the fish所有插件:

SELECT * 
FROM plugins 
WHERE plugin_attributes @> ('some_key => "the fish"') 

比在我看來,使用EAV模型(最可能很多方便多了也更快)。

唯一的缺點是你用這種方法失去了類型安全性(但是通常你會因爲EAV概念而失去它)。

1

您不需要應用程序目錄。只需將應用程序名稱添加到表格的鍵。這當然假定所有的表都具有相同的結構。如果不是,請使用應用程序名稱作爲表名稱,或者像其他人所建議的那樣:作爲模式名稱(這也可以允許每個應用程序使用多個表)。

編輯: 但真正的問題當然是,你應該先模型您的數據,並構建應用程序來操作它的。 數據不應該用於代碼;代碼應該爲數據提供服務。

相關問題