【问题标题】:How to correctly define index aliases in Modx/xPDO models?如何在 Modx/xPDO 模型中正确定义索引别名?
【发布时间】:2014-12-28 21:57:32
【问题描述】:

我的模型中有几个表以几种不同的方式相互关联,一个用于资金请求的表将同时引用客户和雇主的实体表 - 所以它需要 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) 我认为别名类型是正确的,如果删除另一个表中的任何一个记录,则不应删除另一个记录。

【问题讨论】:

  • MODX Revo 不运行 xml 方案。它使用地图文件。最好的解决方案是通过 CMPGenerator extra 从你的表中生成它们。这个方法解决了你所有的问题:A、B、C
  • CMPGenerator 不会为您创建索引,您必须自己创建索引。 CMPGenerator 实际上确实创建了一个 XML 模式,然后从中生成地图和类文件。如果您需要定义表关系 [或别名],则需要编辑该 XML 模式。
  • 关于索引。当然,您应该手动完成。 PhpMyAdmin 是最好的工具。它也不会为您创建关系。但是您也应该在 XML 方案中手动创建它们(如创建地图)。我想您正在生成方案来生成地图。我对吗?在这种情况下,它们是不必要的。您可以使用索引创建自定义数据库,然后为 modx 生成地图。 CMPGenerator 还生成 xml 4 u(当然没有关系)。当您以这种方式创建地图时,您可以确保所有数据类型都是正确的。

标签: mysql modx xpdo


【解决方案1】:

所以它需要 2 个索引

事实上,您的表可能根本没有 mysql 索引(可能只有PRIMARY 索引以提高您使用 xpdo 对象时的速度)并且它会起作用。但是使用索引请求会更快。

当您处理数据库架构时,您应该分析将存储什么样的数据以及您希望以何种方式获取数据。

让我们分析一下你的计划。

<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 分配给-&gt;Profile 时,setter 4 u 都可以工作,最后我们在_relatedObjects 有配置文件对象。 XPDO 使用它们进行保存。这有点复杂,但简而言之,XPDO 保存了两次relatedObjects 以保留密钥,然后保存所需的对象(在我们的例子中为modUser)。 最后,我们用于Relations 的所有字段都将正确设置。

关于关系字段:

  • 别名——关系的名称
  • class — xpdo 对象的类
  • local - 本地对象中的主键字段
  • foreign - 相关对象中的辅助键字段
  • 基数 — 关系类型
  • owner — 密钥的所有者

关于命名

当您尝试为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 名称。它非常简单,易于理解且非常有用。


让我们回到你的例子。 您有两个表,并且彼此创建了两次关系。这非常混乱,无法预测。此外,我们在保存对象时可能会遇到麻烦。

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

您可以恰当地描述您的任务,也许我可以提供帮助。

更新

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

在这种情况下,FundRequest-&gt;Payee 和 FundRequest-&gt;Client 的关系会很好。

另外Payee 和Client 应该是独立的对象,它们可能有关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 2016-04-04
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多