在我的模型中,我有几个表格以两种不同的方式相互关联,一个基金请求表,它们都会引用客户端和雇主的实体表 - 所以它需要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)我认为别名类型是正确的,如果删除另一个表中的任何一个记录都不会被删除。
答案 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
的所有字段都将正确设置。
当您尝试为Relations
创建名称时,您的双手是免费的。但无论如何,他们应该很高兴理解这种关系。
我是如何做到的: 名称的最佳来源是db表名。如果我正在为modx开发一个包,我也会使用它的表名。
表名:
现在我们想要获取modx的地图(我不使用方案,因为modx不需要它们。)
CMPGenerator帮助我创建地图。 现在我们有了对象:
因为我的测试对象应该通过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名称。它非常简单,易于理解且非常有用。
让我们回到你的榜样。 你有两个表,并相互创建两次关系。这非常混乱,不可预测。此外,我们在保存对象时可能会遇到麻烦。
我不知道你试图解决的任务和问题,但可以确切地说你做错了。
您可以正确描述您的任务,也许我可以提供帮助。
据我了解,您有Payees和客户。收款人可能是客户,也可能不是。
在这种情况下,FundRequest->Payee
和FundRequest->Client
关系会很好。
同样Payee
和Client
应该是独立对象,它们可能有关系。