我不是MySQL的专业人士,但想在关系型MySQL表之上做一些类似对象层的事情。
我希望拥有非常多的“结构”,其中包含“bigint”,“longtext”,“datetime”,“double”类型的字段,只存储在7个表格中。
entity_types(et_id,et_name) - “结构”列表;
entity_types_fields(etf_id,parent_et_id,.....,etf_ident,etf_type) - 存储在一个表中的所有结构的结构属性列表; etf_type包含int值(0,1,2,3),它引用了下面描述的4个表之一。
实体(e_id,et_id) - 所有可用实体的列表(实体的ID和类型ID)
和4个数据表(包含实体的所有数据) -
entities_props_bigint(parent_e_id,parent_etf_id,ep_data) - 用于BIGINT数据属性 entities_props_longtext(parent_e_id,parent_etf_id,ep_data) - 用于LONGTEXT数据属性 entities_props_datetime(parent_e_id,parent_etf_id,ep_data) - 用于DATETIME数据属性 entities_props_double(parent_e_id,parent_etf_id,ep_data) - 用于DOUBLE数据属性
从这样的数据层进行选择的最佳方法是什么?
让我有e_id(实体的id)列表,每个实体可以有任何类型。我想获得预定义的属性列表。如果某些实体没有这样的属性,我希望它等于NULL。
你有关于如何做的一些信息吗?可能是你有一些联系或已经处理过这类事情。
谢谢!
答案 0 :(得分:0)
通过在关系数据库之上实现整个元数据系统,您是reinventing the wheel。许多开发人员have tried to do what you're doing然后使用SQL来查询它,就好像它是关系数据一样。但是在SQL中实现非关系数据和元数据系统比你预期的要困难。
我已将问题的relational
标记更改为eav
,因为您的设计是Entity-Attribute-Value设计的变体。 Stack Overflow中有五个标签的限制。但是你应该知道你的设计不是关系型的。
关系设计必须为实体的所有实例提供一组固定的属性。在关系数据库中表示它的正确方法是使用表的列。这允许您为每个属性提供名称和数据类型,并确保同一组名称及其数据类型适用于表的每一行。
从这样的数据层进行选择的最佳方法是什么?
查询设计的唯一可扩展方法是将属性数据和元数据作为行获取,然后在应用程序代码中重构对象。
SELECT e.e_id, f.etf_ident, f.etf_type,
p0.ep_data AS data0,
p1.ep_data AS data1,
p2.ep_data AS data2,
p3.ep_data AS data3
FROM entities AS e
INNER JOIN entity_type_fields AS f ON e.et_id = f.parent_et_id
LEFT OUTER JOIN entities_props_bigint AS p0 ON (p0.parent_e_id,p0.parent_etf_id) = (e.e_id,f.etf_id)
LEFT OUTER JOIN entities_props_longtext AS p1 ON (p1.parent_e_id,p1.parent_etf_id) = (e.e_id,f.etf_id)
LEFT OUTER JOIN entities_props_datetime AS p2 ON (p2.parent_e_id,p2.parent_etf_id) = (e.e_id,f.etf_id)
LEFT OUTER JOIN entities_props_double AS p3 ON (p3.parent_e_id,p3.parent_etf_id) = (e.e_id,f.etf_id)
在上面的查询中,每个实体字段最多应匹配一个属性,其他数据列将为null。如果所有四个数据列都为null,则缺少实体字段。
重新评论,好吧,现在我更了解你要做的事情。您在树中有一组实体实例,但每个实例可能是不同的类型。
以下是我的设计方法:
将所有实体子类型的所有属性存储在某种超类型表中。
实体(e_id,entity_type,name,date_created,creator,sku等)
将特定于实体子类型的任何属性存储在自己的表中,如Martin Fowler的Class Table Inheritance设计。
entity_books(e_id,isbn,pages,publisher,volumes等)
entity_videos(e_id,格式,地区,光盘等)
entity_socks(e_id,fabric,size,color等)
使用Closure Table设计来建模对象的层次结构。
entity_paths(ancestor_e_id,descendant_e_id,path_length)
有关类表继承和关闭表的更多信息,请参阅我的演示文稿Practical Object-Oriented Models in SQL和Models for Hierarchical Data in SQL,或我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming或Martin Fowler的书Patterns of Enterprise Application Architecture。