如何在Modx / xPDO模型中正确定义索引别名?

时间:2014-12-28 21:57:33

标签: mysql modx xpdo

在我的模型中,我有几个表格以两种不同的方式相互关联,一个基金请求表,它们都会引用客户端和雇主的实体表 - 所以它需要2个索引,设置XML模型架构的正确方法是什么?

这些表格[大大缩短了!]:

<object class="FundRequest" table="fund_request" extends="xPDOSimpleObject">
    <field key="token" dbtype="varchar" precision="50" phptype="string" null="true" />
    <field key="unixtime" dbtype="varchar" precision="50" phptype="string" null="true" />

    <field ... a bunch of fields not related to the question... />

    <field key="payee_uid" dbtype="int" precision="8" phptype="integer" null="true" />
    <field key="client_uid" dbtype="int" precision="8" phptype="integer" null="false" />

    <aggregate alias="Entities" class="Entities" local="payee_uid" foreign="id" cardinality="one" owner="foreign" />
    <aggregate alias="Entities" class="Entities" local="client_uid" foreign="id" cardinality="one" owner="foreign" />
</object>

<object class="Entities" table="entities" extends="xPDOSimpleObject">
    <field key="token" dbtype="varchar" precision="50" phptype="string" null="true" />
    <field key="unixtime" dbtype="varchar" precision="50" phptype="string" null="true" />

    <field ... a bunch of fields not related to the question... />

    <aggregate alias="FundRequest" class="FundRequest" foreign="payee_uid" local="id" cardinality="one" owner="local" />
    <aggregate alias="FundRequest" class="FundRequest" foreign="client_uid" local="id" cardinality="one" owner="local" />
</object>

我想我应该在FundRequest表中将我的聚合别名命名为:

<aggregate alias="PayeeEntity" class="Entities" local="payee_uid" foreign="id" cardinality="one" owner="foreign" />
<aggregate alias="ClientEntity" class="Entities" local="client_uid" foreign="id" cardinality="one" owner="foreign" />

所以我可以将它们称为

$object->FundRequest->PayeeEntity->get('whatever');

在我的代码中。

A)这是对的吗?

B)如何在实体表中标记别名?

C)我认为别名类型是正确的,如果删除另一个表中的任何一个记录都不会被删除。

1 个答案:

答案 0 :(得分:0)

  

所以它需要2个索引

实际上,你的表可能没有mysql索引(可能只有PRIMARY索引,以便在你使用xpdo对象时提高速度),它会起作用。但是使用索引请求会更快。

当您使用db的体系结构时,您应该分析将存储哪种数据以及以何种方式获取数据。

让我们分析你的计划。

  

<aggregate alias="Entities" class="Entities" local="payee_uid" foreign="id" cardinality="one" owner="foreign" /> <aggregate alias="Entities" class="Entities" local="client_uid" foreign="id" cardinality="one" owner="foreign" />

这很奇怪,我想错了。此外,我开始认为你在索引和聚合/复合关系中混淆了(我后来称之为Relations)。它们不一样。

Relations允许您在XPDO个对象之间进行实现。 XPDO使用此机制保存并获取related objects

Indexes对db很有用。它们有助于提高请求速度和控制数据(例如UNIQUE索引意味着当前字段(或几个字段)应具有唯一值/值组合)

让我们谈谈Relations

因此,每个xpdo对象都有内部属性_relatedObjects。所以它在XPDO中非常强大。关系允许这样做(这是一个相当简单的例子):

$u = $modx->newObject('modUser');
$p = $modx->newObject('modUserProfile');

$u->fromArray(…);
$p->fromArray(…);

$u->Profile = $p;
$u->save();

当您将$p分配给->Profile setter时,所有内容都可以正常工作,最后我们在_relatedObjects处拥有个人资料对象。 XPDO使用它们进行保存。这有点复杂,但简而言之XPDO两次保存relatedObjects以保留密钥,并且在我们的案例中保存所需的对象(modUser)。 最后,我们用于Relations的所有字段都将正确设置。

关于关系字段:

  • 别名 - 关系名称
  • class - xpdo object&#39; s class
  • local - 本地对象中的主键字段
  • 外来 - 相关对象中的辅助关键字段
  • 基数 - 关系类型
  • 所有者 - 密钥的所有者

关于命名

当您尝试为Relations创建名称时,您的双手是免费的。但无论如何,他们应该很高兴理解这种关系。

我是如何做到的: 名称的最佳来源是db表名。如果我正在为modx开发一个包,我也会使用它的表名。

表名:

  • modx_package_obj
  • modx_package_secondobj
  • modx_package_obj_secondobj

现在我们想要获取modx的地图(我不使用方案,因为modx不需要它们。)

CMPGenerator帮助我创建地图。 现在我们有了对象:

  • PackageObj(id,name)
  • PackageSecondobj(id)
  • PackageObjSecondobj(id,obj_id,sobj_id)

因为我的测试对象应该通过PackageObjSecondobj建立关系,我需要关系。

$xpdo_meta_map['PackageObj']= array ( … 'composites' => array ( 'ObjSecondobj' => array ( 'class' => 'PackageObjSecondobj', 'local' => 'id', 'foreign' => 'obj_id', 'owner' => 'local', 'cardinality' => 'many', ), ), ); $xpdo_meta_map['PackageSecondobj']= array ( … 'composites' => array ( 'ObjSecondobj' => array ( 'class' => 'PackageObjSecondobj', 'local' => 'id', 'foreign' => 'sobj_id', 'owner' => 'local', 'cardinality' => 'many', ), ), ); $xpdo_meta_map['PackageObjSecondobj']= array ( … 'aggregates' => array ( 'Obj' => array ( 'class' => 'PackageObj', 'local' => 'obj_id', 'foreign' => 'id', 'owner' => 'foreign', 'cardinality' => 'one', ), 'Secondobj' => array ( 'class' => 'PackageSecondobj', 'local' => 'sobj_id', 'foreign' => 'id', 'owner' => 'foreign', 'cardinality' => 'one', ), ), );

因此,如您所见,xpdo对象的包名称+ obj名称,Relations的obj名称。它非常简单,易于理解且非常有用。


让我们回到你的榜样。 你有两个表,并相互创建两次关系。这非常混乱,不可预测。此外,我们在保存对象时可能会遇到麻烦。

我不知道你试图解决的任务和问题,但可以确切地说你做错了。

您可以正确描述您的任务,也许我可以提供帮助。

UPD

据我了解,您有Payees和客户。收款人可能是客户,也可能不是。

在这种情况下,FundRequest->PayeeFundRequest->Client关系会很好。

同样PayeeClient应该是独立对象,它们可能有关系。