动态属性的 OOP 和 SQL 查询


OOP and SQL Query for dynamic attributes

我有四个类:User,Attribute,Attribcategory,Attribvalue。

和四个表:数据库中的tbl_user、tbl_attribute、tbl_attribcategory tbl_attribvalue。

这些是表之间的关系:

tbl_user 1 --- n tbl_attribvalue n --- 1 attribute 

(tbl_attribvalue 是属性和用户之间的中间表

tbl_attribcategory 1 ---- n tbl_attribute

这是一个例子:

tbl_user
{id:1, name: Jack}

tbl_category {id:2,label: Career and Education}
tbl_attribute :
{id:1 ,category:2,label:employer , variable: employer}
{id:2 ,category:2,label: High school , variable: high_school}
{id:3 ,category:2,label:college , variable:college}

由于tbl_attribvalue是介于tbl_attribute和tbl_user之间的中间表,我们应该知道 用户 id 和属性 id...知道用户属性的值。

示例

tbl_attribvalue {id:1,iduser:1,idattrib:3,value: Harvard University}

当我们在应用程序中具有动态属性而不是静态标签时,使用此系统。

上课呢?

这四个类:User,Attribute,Attribvalue,Attribcategory分别包含getter和setter以及属性。

我想返回给定用户的所有这些属性、属性类别和属性值......但我不知道到底用什么方法,这是一个问题概念。

我的控制器中已经有这段代码(在MVC模型中):

$atcdata=array();
$attribcategory=new Attribcategory($atcdata);
$attribcategories=$manager->viewIt($attribcategory,' defined=0 AND ownertype=1');

$manager是一个DBManager,它包含一个函数viewIt($object,$criteria),然后它使用给定的条件返回一个数组,其中包含给定对象的结果。

因此,属性类别将包含所有类别。

但是如何使用这些类别信息来返回给定用户的属性和属性值呢?

换句话说:

知道如何返回它们,但是就性能而言,我不想使用两个以上的查询来获取所有数据。

对于给定用户,此数据示例将显示如下

[attrcategory]
    [attribute] : [attrvalue]
                  [attrvalue]
                  [attrvalue]
Work & Education 
    Employer : Oracle 
               Microsoft
    College : Harvard
    High school : harvard

等等。

提前谢谢你

你做错了MVC..但这不是问题。

您那里有一个"入口属性值"反模式。在 SQL 反模式(在具有相同标题的章节中)中对此进行了探讨。这就是导致您的问题的原因。

要在单个查询中获取所有结果,您能做的最好的事情就是以类似于以下响应结构的内容为目标:

[attrcategory] , [attribute] , [attrvalue]+[attrvalue]+[attrvalue]
[attrcategory] , [attribute] , [attrvalue]
[attrcategory] , [attribute] , [attrvalue]+[attrvalue]+[attrvalue]+[attrvalue]

能够生成此类结果的查询大致如下所示:

SELECT 
    AttributeCategories.title AS attrcategory, 
    Attributes.title AS attribute, 
    GROUP_CONCAT(DISTINCT AttribureValues.value
                 ORDER BY AttribureValues.value DESC SEPARATOR '+')
         AS list
FROM AttribureValues
    LEFT JOIN Attributes USING (attribute_id)
    LEFT JOIN AttributeCategories USING (category_id)
    LEFT JOIN Users USING (user_id)
WHERE 
    Users.name = 'John Smith'
GROUP BY Attributes.attribute_id

然后在PHP结束时,您必须在分隔符上explode()值。