6

我在数据库中有一个表(基于 Postgres),它就像面向对象编程中的超类。它有一个“类型”列,用于确定表中应存在哪些附加列(子类属性)。但我不希望该表包含所有可能的列(所有可能类型的所有属性)。

所以我决定制作一个表,包含“key”和“value”列(即“filename”=“/file”或“some_value”=“5”),其中包含对象的任何可能属性,不包括在内在超类表中。并且还制作了一个相关表来包含可用的“关键”值。

但是这种架构存在一个问题——默认情况下,“值”列应该是字符串数据类型,才能包含任何内容。但我不认为转换为字符串和从字符串转换是一个好的决定。绕过此限制的最佳方法是什么?

4

8 回答 8

10

您正在试验的设计是Entity-Attribute-Value的变体,它带来了很多问题和低效率。对于您正在做的事情,这不是一个好的解决方案,除非作为最后的手段。

fall888 描述的可能是一个更好的解决方案:为每个子类型创建一个“子类型”表。如果您有有限数量的子类型,这没关系,这听起来像您所拥有的。然后,您的子类型特定属性可以具有数据类型,并且NOT NULL如果合适,还可以具有约束,如果您使用 EAV 设计,这是不可能的。

子类型表设计的一个剩余弱点是,您不能仅仅因为超类表中的主行表明它应该存在,就强制子类型表中存在一行。但这比 EAV 设计引入的弱点要温和一些。

编辑:关于您对任何实体的评论的附加信息,是的,这是一种非常常见的模式。当心被称为“多态关联”的损坏解决方案,这是许多人在这种情况下使用的一种技术。

于 2008-12-08T23:45:57.470 回答
2

这个怎么样...每个子类型都有自己的数据库表。基础/超级表只有一个 varchar 列,其中包含子类型 DB 表的名称。然后你可以有这样的东西......

Entity
------
ID
Name
Type
SubTypeName   (value of this column will be 'Dog')


Dog
---
VetName
VetNumber
etc

如果您不希望您的(子)表名称是基表中的 varchar 值,您也可以只拥有一个 SubType 表,其主键将在基表中。

于 2008-12-08T22:45:09.730 回答
0

唯一的解决方法(同时保留你的结构)是有单独的表:

create table IntProps(...);
create table StringProps(...);
create table CurrencyProps(...);

但我不认为这是一个好主意......

于 2008-12-08T22:44:13.273 回答
0

一种常见的方法是让键值表包含多个列,每个数据类型一个列,即 StringValue、DecimalValue 等。

只需知道您正在为不需要更改的数据库模式交易可查询性和性能。您还可以考虑 ORM 映射或对象数据库。

于 2008-12-08T22:45:07.267 回答
0

您可以拥有每个类型的键/值表。可用表需要对特定键/类型对的可用性进行编码,以指向正确键入的键/值表。

然而,对于基于行的关系数据库来说,这似乎是一种非常低效的架构。

也许您应该看一下面向列的关系数据库?

于 2008-12-08T22:47:53.983 回答
0

感谢您的回答。我会更具体地解释一下我需要什么。需要编写一个博客+论坛网站,我一直在研究WordPress DB 结构

强烈需要能够对任何类型的“对象”(例如博客条目或视频文件附件)进行评论。上述数据库结构非常易于扩展并满足我们所有的需求,这是选择它的原因。

但是现在改变它还为时不晚,因为它处于早期工程阶段。此外,我们的模型现在闻起来像一个完全基于树层次结构的数据库。现在我会接受Bill Karwin 和 fall888 的答案,但也许我走错了方向?

于 2008-12-09T11:07:44.177 回答
0

关于用户能够向表中添加新字段:

我钦佩所有发表评论的人。

几年前我曾经对这种东西很感兴趣,但最近写的代码很少(除了一点点PHP和MYSQL)。

如果你想继续前进,我认为这很好——你最终可能会得到一些新的东西。

很抱歉给这个计划泼冷水——我很佩服你的努力。我个人的信念是,如果你在这个方向上走得足够远,你最终会得到一个比 SQL 解释更多自然语言的系统。(大约在 1970 年,SQL 实际上拼写为 Sequel,它实际上代表“结构化英语查询语言”,但是在 1970 年代他们将其标准化之后——我想有人说 Oracle 是第一个商业实现,19079 年,“英语”得到了放弃了,因为我猜他们认为这只是英语的一小部分。

我在这方面已经筋疲力尽了,因为我没有找到工作。如果没有一份轻松的工作来支付账单,我可以尝试这些想法,那么专注于这个领域有点困难。

向所有人致以最良好的祝愿。

于 2009-01-31T14:34:51.983 回答
0

抱歉,我在上面写了 19079,我的意思是 1979 年。Oracle 获得了他们的第一份合同,为 CIA 编写数据库。

于 2009-01-31T14:35:55.057 回答