我刚开始使用PostgreSQL,而且我是数据库设计的新手。
我正在编写软件,其中有各种插件可以更新数据库。每个插件定期更新数据库中自己指定的表。因此,名为“KeyboardPlugin”的插件将更新“KeyboardTable”,而“MousePlugin”将更新“MouseTable”。我希望我的数据库能够存储这些“插件表”关系,同时强制执行参照完整性。理想情况下,我想要一个包含以下列的配置表:
我的软件将从此配置表中读取,以帮助插件确定要更新的表。最初,我的想法是让第二列(Table-Name)为'text'类型。但是,如果某人错误输入了表名,或者由于某人删除了某个表而导致现有关系变得无效,那么我们就会遇到问题。我希望'Table-Name'列作为对另一个表的引用,同时强制引用完整性。
在PostgreSQL中执行此操作的最佳方法是什么?随意建议一种全新的方式来设置我的数据库,这与我目前正在探索的不同。此外,如果它可以帮助您回答我的问题,我正在使用pgAdmin工具来设置我的数据库。
感谢您的帮助。
答案 0 :(得分:1)
我会按原计划将名称存储为文本。通过另外存储架构名称可能会增强:
addin text
,sch text
,tbl text
表系统目录中有OID
(pg_catalog.pg_class
)。你可以得到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
);
如果addins有多个表,甚至可以使它成为n:m关系。但请注意,正如@OMG_Ponies评论的那样,这样的设置将要求您执行大量动态SQL,因为您事先并不知道标识符。
答案 1 :(得分: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概念而失去它)。
答案 2 :(得分:1)
您不需要应用程序目录。只需将应用程序名称添加到表的键中即可。这当然假设所有表都具有相同的结构。如果不是:使用应用程序名称作为表名,或者像其他人建议的那样:作为模式名称(也允许每个应用程序使用多个表)。
编辑: 但真正的问题当然是你应该首先为你的数据建模,而比构建应用程序来操纵它。 数据不应该为代码服务;代码应该提供数据。