Как правильно определить псевдонимы индекса в моделях Modx/xPDO?
У меня есть несколько таблиц, которые связаны между собой несколькими различными способами в моей модели, таблица для запросов средств, которая будет ссылаться на таблицу Entity для клиента и работодателя - так что для этого нужны 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');
в моем коде.
А) Это правильно?
Б) Как я должен пометить мои псевдонимы в таблице сущностей?
C) Я думаю, что типы псевдонимов являются правильными, ни одна запись в любой таблице не должна быть удалена, если удалена другая.
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
полезны для БД. Они помогают повысить скорость запросов и контролировать данные (например, UNIQUE
индекс означает, что текущее поле (или пара полей) должно иметь уникальное значение / комбинацию значений)
Давайте поговорим о Relations
,
Итак, каждый xpdo
объект имеет внутреннее свойство _relatedObjects
, Так что это очень мощная вещь в XPDO
, И отношения позволяют это сделать (это довольно простой пример):
$u = $modx->newObject('modUser');
$p = $modx->newObject('modUserProfile');
$u->fromArray(…);
$p->fromArray(…);
$u->Profile = $p;
$u->save();
Когда вы назначаете $p
в ->Profile
сеттер выполняет всю работу 4 u, и в конце мы имеем объект профиля в _relatedObjects
, XPDO
использует их для сохранения. Это немного сложно, но вкратце XPDO
экономит relatedObjects
дважды сохранить ключи и в конце концов сохранить нужный объект (modUser
в нашем случае). В конце концов все поля, которые мы используем для Relations
будет установлен правильно.
О полях отношения:
- псевдоним - имя отношения
- class - класс объекта xpdo
- local - поле первичного ключа в локальном объекте
- поле внешнего - вторичного ключа в связанном объекте
- кардинальность - тип отношения
- владелец - владелец ключа
О наименовании
Когда вы пытаетесь создать имя для Relations
твои руки свободны Но в любом случае им должно быть приятно понять отношение.
Как я это делаю: лучший источник для имени - это имя таблицы базы данных. Если я разрабатываю пакет для modx, я также использую его название для таблиц.
Имена таблиц:
- modx_package_obj
- modx_package_secondobj
- modx_package_obj_secondobj
Теперь мы хотим получить карты для modx (я не использую схемы, потому что они не нужны для modx).
CMPGenerator помогает мне создавать карты. Теперь у нас есть объекты:
- PackageObj (идентификатор, имя)
- 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, имя объекта для объекта Relations
, Это довольно просто, легко понять и очень полезно.
Вернемся к вашему примеру. У вас есть две таблицы и вы создаете связь друг с другом дважды. Это очень грязно и не будет работать предсказуемо. Также могут возникнуть проблемы при сохранении объектов.
Я не знаю ваших задач и задач, которые вы пытаетесь решить, но могу точно сказать, что вы делаете неправильно.
Вы можете правильно описать свою задачу и, возможно, я могу помочь.
UPD
Как я понимаю, у вас есть получатели и клиенты. Получатель платежа может быть клиентом, а может и нет.
В этом случае FundRequest->Payee
а также FundRequest->Client
отношения были бы хорошими.
Также Payee
а также Client
должны быть независимыми объектами, и они могут иметь отношения.