我们正计划重组一个现有的数据库,该数据库以一种不那么合乎逻辑的方式增长。我的数据库应该模拟以下情况:
- 我们有许多不同类型的硬件。对于某些类型,一些通用字段就足够了;对于其他类型,我们需要很多特定字段;
- 我们在世界各地有几个最终产品的“安装”;
- 安装是通过将硬件组合在一起来完成的,
起初,我认为Postgres继承是这个任务的理想解决方案。假设:
-- hardware is for generic hardware
CREATE TABLE hardware
(
id_hardware serial NOT NULL,
id_hardware_model integer not null, -- points to a table with hardware models
description character varying(255) not null,
-- etc
-- primary key, foreign keys, etc
);
-- let's suppose we need many additional fields for solar panels;
-- solar_panel inherits from hardware
CREATE TABLE solar_panel
(
max_power_production_w integer,
panel_area_cm2 double precision,
-- etc
) INHERITS (hardware);
-- our installations
CREATE TABLE installation
(
id_installation serial NOT NULL,
id_nation integer,
id_owner integer,
-- latitude, longitude, etc
-- primary key, foreign key, etc
);
-- the link between hardware and installations (time-dependent)
CREATE TABLE installation_hardware
(
id_installation int NOT NULL,
id_hardware int not null,
start_date date not null,
end_date date,
-- primary key
-- two foregn keys:
CONSTRAINT ih_installation_fk FOREIGN KEY (id_installation) references installation(id_installation),
CONSTRAINT ih_hardware_fk FOREIGN KEY (id_hardware) references hardware(id_hardware)
);
字符串
然后我发现Postgres中的继承有一些严重的局限性。引用文档here(它使用了一个例子,“cities”作为父表,“capitals”作为子表):
如果我们将www.example.com声明cities.name为UNIQUE或PRIMARY KEY,这将不会阻止capitalists表中具有与cities中的行重复的名称的行。并且这些重复的行将默认显示在来自cities的查询中。实际上,默认情况下capitalists根本没有唯一约束,因此可以包含多个同名的行。您可以为capitalists添加唯一约束,但这并不能防止与城市相比的重复。[.]请注意另一个表的列REFERENCES cities(name)将允许另一个表包含城市名称,但不包含首都名称。这种情况没有很好的解决方法。
与其放弃继承,我想也许我可以用这种方式处理这种情况:
1.在installation_hardware中,我没有创建指向硬件的外键;相反,通过在installation_hardware上使用触发器来强制引用完整性;
1.通过使用触发器强制“hardware”和所有子表中id_hardware的唯一性(当然,id_hardware通常由序列生成,但只是为了安全起见...);
我想强调的是,这些表上的插入/更新/删除操作将非常轻量级(最坏的情况下,每天只有几个操作),所以我认为触发器没有性能问题。
这一切都有意义吗?你能提出一些改进或替代方案吗?谢谢。
1条答案
按热度按时间ha5z0ras1#
对于那些可能感兴趣的人,我发现了这两个关于继承和数据库的很好的讨论:
How can you represent inheritance in a database?
https://typedb.com/blog/inheritance-and-polymorphism-where-the-cracks-in-sql-begin-to-show的
他们用标准SQL解决了这个问题。