2011-08-22 12 views
2

我不是MySQL的专业人士,但想要做一些像关系型MySQL表格之上的对象层。更好的方法来做MySQL对象层

我想有很多“结构”,只有7个表中存储了类型为“bigint”,“longtext”,“datetime”,“double”的字段。

entity_types(et_id,et_name) - “structures”的列表;

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) - 双数据性能

什么,从这些数据层做选择的最佳方式?

让我有e_id(实体的id)列表,每个实体可以有任何类型。我想获得预定义的属性列表。如果有些实体没有这样的属性,我想让它等于NULL。

你有关于如何做的一些信息?可能是你有一些链接或已经处理这样的事情。

谢谢!

回答

0

您是reinventing the wheel通过在关系数据库之上实现整个元数据系统。许多开发人员have tried to do what you're doing然后使用SQL来查询它,就好像它是关系数据一样。但是,在SQL中实现非关系数据和元数据系统比您期望的要难。

我已将您的问题的relational标签更改为eav,因为您的设计是Entity-Attribute-Value设计的变体。 Stack Overflow中有5个标签的限制。但是你应该知道你的设计不是关系型的。

关系设计对实体的所有实例必然具有一组固定的属性。在关系数据库中表示这一点的正确方法是使用表的列。这允许您为每个属性分配名称数据类型,并确保相同的一组名称及其数据类型适用于表的每一行。

什么是从这样的数据层做选择的最佳方法?

查询您设计的唯一可扩展方式是将属性数据和元数据作为行读取,并在应用程序代码中重建对象。

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) 

在上面的查询中,每个实体字段最多应匹配一个属性,其他数据列将为空。如果所有四个数据列都为空,则实体字段丢失。


重新发表您的评论,好吧,现在我明白你正在努力做的更好。您在树中具有实体实例的集合,但每个实例可能是不同的类型。

这是我会怎么设计呢:

  • 商店,你的所有实体亚型共同具有一种超型表的任何属性。

    实体(E_ID,ENTITY_TYPE,名称,DATE_CREATED,创造者,SKU等)

  • 存储特定于实体子类型在自己的表中的任何属性,如Martin Fowler的Class Table Inheritance设计。

    entity_books(E_ID,ISBN,页面,出版商,体积等)

    entity_videos(E_ID,格式,区域,光盘等)

    entity_socks(E_ID,织物,大小,颜色,等等)

  • 使用Closure Table设计来建模对象的层次结构。

    entity_paths(ancestor_e_id,descendant_e_id,PATH_LENGTH)

有关类表继承和关闭表的更多信息,请参见我的演讲Practical Object-Oriented Models in SQLModels for Hierarchical Data in SQL,或我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming,或Martin Fowler的书Patterns of Enterprise Application Architecture

+0

我应该解释一下。 – Epsiloncool

+0

我应该解释一下。以一种常见的方式,我必须为任何类型的实体提取数据。例如,我有一组可以组合到树中的实体。每个实体都有“parent_id”属性和“title”属性,但是不同的类型。所以它不能被放置在同一个关系结构中(例如普通的MySQL表)。你明白吗 ? 当我需要一个相关类型实体的“关系”表时,我需要只获取一个实体和任务。但是我想要对所描述的模型有一定的灵活性。 – Epsiloncool

+0

**查询设计的唯一可扩展方式是将属性数据和元数据作为行获取,并在应用程序代码中重建对象。**是的,我认为是这样。但我无法为其构建适当的查询。 – Epsiloncool

相关问题