Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 附加字段实体的最优数据库结构_Sql_Database_Postgresql_Entity Attribute Value - Fatal编程技术网

Sql 附加字段实体的最优数据库结构

Sql 附加字段实体的最优数据库结构,sql,database,postgresql,entity-attribute-value,Sql,Database,Postgresql,Entity Attribute Value,我在DB中有一个表(基于Postgres),它的作用类似于面向对象编程中的超类。它有一个列“type”,用于确定表中应该存在哪些其他列(子类属性)。但我不希望该表包含所有可能的列(所有可能类型的所有属性) 因此我决定创建一个表,包含“key”和“value”列(即“filename”='/file”或“some_value'='5'),其中包含对象的任何可能属性,而不包括在超类表中。并且还制作了一个相关的表来包含可用的“键”值 但是这种体系结构存在一个问题——“value”列在默认情况下应该是字

我在DB中有一个表(基于Postgres),它的作用类似于面向对象编程中的超类。它有一个列“type”,用于确定表中应该存在哪些其他列(子类属性)。但我不希望该表包含所有可能的列(所有可能类型的所有属性)

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

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

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

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

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

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


只需知道,您正在用可查询性和性能换取一个不需要更改的数据库模式。您也可以考虑ORM映射或对象数据库。< /P> < P> >如何替代这个?每个子类型都有自己的DB表。而base/super表只有一个varchar列,它保存子类型DB表的名称。然后你可以有这样的东西

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


Dog
---
VetName
VetNumber
etc

如果不希望(子)表名在基表中是varchar值,也可以使用主键在基表中的子类型表。

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

然而,对于基于行的关系数据库来说,这似乎是一种效率极低的体系结构


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

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

更好的解决方案是fallen888所描述的:为每个子类型创建一个“subtype”表。如果你有有限数量的子类型,这是可以的,这听起来像你所拥有的。然后,特定于子类型的属性可以有数据类型,如果合适,还可以有
notnull
约束,如果使用EAV设计,这是不可能的

子类型表设计的另一个弱点是不能强制子类型表中存在行,因为超类表中的主行表示应该存在行。但这是一个比EAV设计引入的更温和的弱点


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

谢谢你的回答。我会更具体地解释我需要什么。 有必要规划一个博客+论坛网站,我一直在看

强烈需要能够对任何类型的“对象”进行评论,比如博客条目或视频文件附件。上面的DB结构非常容易扩展,能够满足我们的所有需求,这就是它选择的原因


但改变它并不晚,因为这是在早期工程阶段。此外,我们的模型现在闻起来像一个完全基于树层次结构的数据库。现在我接受,但可能我的方向完全错了?

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

我钦佩所有这些发表评论的人

几年前我对这类事情很感兴趣,但最近我写了一些代码(除了一点PHP和MYSQL)

我认为如果你想继续下去就好了——你可能会得到一些新的东西

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

我在这个领域已经没有动力了,因为我没有工作。如果没有一份简单的工作来支付账单,在那里我可以尝试这些想法,那么我就很难专注于这个领域


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

对不起,我在上面写了19079,我指的是1979年。甲骨文公司获得了为中情局编写数据库的第一份合同