我目前正在尝试为可能拥有或遗漏某些属性的动态数据对象建模(属性名称已知当前要求)。目前尚不清楚是否会在以后添加新属性(但几乎可以肯定)。建模对象就是这样的:
int id PRIMARY KEY NOT NULL;
int owner FOREIGN KEY NOT NULL;
Date date NOT NULL;
Time time NOT NULL;
Map<String,String> properties;
属性可以是任何类型(int,bool,string,...)
我不确定如何在SQL数据库中对此对象进行建模。有两种方法我可以想到这样做,我希望有一些输入,这将是开发人员工作&#34;(维护),内存消耗和性能方面的更好选择。作为旁边信息:属性几乎总是NULL(不存在)
(1)我会有一个大表,其中包含id,owner,date,time和每个属性作为列,而行的缺少属性被建模为NULL。 e.g。
TABLE_X
id|owner|date|time|prop_1|prop_2|prop_3|...
这个表有很多NULL值。
如果要添加新属性,那么我会做一个ALTER TABLE并为每个新属性插入一个新列
在这里,我会做一个&#34;通常&#34;
SELECT * FROM TABLE_X ...
(2)我将有一个包含所有NOT NULL数据的主表:
TABLE_X
id|owner|date|time
然后为每个属性设置一个单独的表格,如下所示:
TABLE_X_PROP_N
foreign_key(TABLE_X(id))|value
这里根本就没有NULL值。属性具有值并且在其对应的表中,或者它是NULL,然后不会出现在其表中。
要添加新属性,我只需添加另一个表。
这是做一个
SELECT * FROM TABLE_X LEFT JOIN TABLE_X_PROP_1 ON ... LEFT JOIN TABLE_X_PROP_2 ON ...
重复这个问题(所以你不必向上滚动): 处理问题的两种方法中哪一种在维护(开发人员工作),内存消耗(磁盘上)和性能(每秒更多查询)方面更好?也许你对如何处理这个也有更好的想法。提前致谢
答案 0 :(得分:1)
解决方案2.但为什么没有每个属性的单独表。把所有东西放在一张桌子里:
properties(
foreign_key(TABLE_X(id))
property_name,
value);
答案 1 :(得分:1)
如果你使用选项2,我认为你需要3个表:
TABLE_HEADER
ID |所有者|日期|时间
TABLE_PROPERTY
ID |名称
TABLE_PROPERTYVALUE
ID | headerID(FK)|属性ID(FK)|值
轻松添加新属性可以提高灵活性并更快地迭代。属性的数量也会产生影响(例如,如果您有500个属性,则不需要具有500列的表!)。主要的缺点是,如果您需要使用属性附加复杂的业务逻辑作为一个更复杂的导航结构,并且您不能强制执行数据完整性(如非特定字段的null),那么它将变得丑陋。如果您真的想要一个像您在对象结构中建模的属性包那么这很容易映射。 与所有事情一样,取决于您最适合的情况。
答案 2 :(得分:1)
听起来你正试图在这里实现一个Entity-Attribute-Value(经常被视为反对)模式。你对他们熟悉吗?以下是一些参考文献:
https://softwareengineering.stackexchange.com/questions/93124/eav-is-it-really-bad-in-all-scenarios
http://www.dbforums.com/showthread.php?1619660-OTLT-EAV-design-why-do-people-hate-it
https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model
我个人非常担心RDBMS中的这种类型的设置。我倾向于认为NoSQL文档样式数据库更适合这些类型的动态结构,尽管我自己对NoSQL的实际经验相对较少。