2011-11-17 145 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

您不需要应用程序目录。只需将应用程序名称添加到表格的键。这当然假定所有的表都具有相同的结构。如果不是,请使用应用程序名称作为表名称,或者像其他人所建议的那样:作为模式名称(这也可以允许每个应用程序使用多个表)。

编辑: 但真正的问题当然是,你应该先模型您的数据,并构建应用程序来操作它的。 数据不应该用于代码;代码应该为数据提供服务。

相关问题