我的模型中有几个以几种不同方式相互关联的表,一个用于资金请求的表,它都引用了客户和雇主的实体表 - 所以它需要 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)我认为别名类型是正确的,如果删除了另一个表中的记录,则不应删除两个表中的记录。
所以它需要 2 个索引
事实上,您的表可能根本没有mysql索引(当您使用xpdo对象时,可能只有PRIMARY
索引以提高速度),并且它将起作用。但是使用索引,请求将更快地工作。
当你在数据库的架构上工作时,你应该分析将存储什么样的数据以及你想要以什么方式获取数据。
让我们分析你的计划。
<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
对数据库很有用。它们有助于提高请求速度和控制数据(例如 UNIQUE
索引意味着当前字段(或几个字段)应该具有 uniqie 值/值组合)
让我们谈谈Relations
.
因此,每个xpdo
对象都有内部属性_relatedObjects
。所以这在XPDO
中是非常强大的事情.关系允许这样做(这是一个相当简单的例子):
$u = $modx->newObject('modUser');
$p = $modx->newObject('modUserProfile');
$u->fromArray(…);
$p->fromArray(…);
$u->Profile = $p;
$u->save();
当您将$p
分配给->Profile
二传手时,您可以完成所有工作 4 您,最后我们在 _relatedObjects
处拥有配置文件对象。 XPDO
使用它们进行保存。这有点复杂,但简而言之,XPDO
保存relatedObjects
两次以保留密钥,毕竟保存所需的对象(在我们的例子中modUser
)。最后,我们将正确设置用于Relations
的所有字段。
关于关系字段:
- 别名 — 关系的名称
- 类 — XPDO 对象的类
- local - 本地对象中的主键字段
- 外键 - 相关对象中的辅助键字段
- 基数 — 关系类型
- 所有者 — 密钥的所有者
关于命名
当您尝试为Relations
创建名称时,您的双手是自由的。但无论如何,他们应该很高兴理解这种关系。
我是怎么做到的:名称的最佳来源是数据库表名称。如果我正在为 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
据我了解,您有收款人和客户。收款人可能是客户,也可能不是。
在这种情况下,FundRequest->Payee
和FundRequest->Client
关系会很好。
此外,Payee
和Client
应该是独立的对象,它们可能有关系。