Php Zend_Db_表中的复杂引用映射用于说明多列键
我将试图使这一点尽可能简单,但我担心用例超出了Zend_Db的初衷。它涉及我在CMS中标记页面(或任何其他内容,如文档)的一组表 我有三张桌子:Php Zend_Db_表中的复杂引用映射用于说明多列键,php,zend-framework,zend-db,zend-db-table,Php,Zend Framework,Zend Db,Zend Db Table,我将试图使这一点尽可能简单,但我担心用例超出了Zend_Db的初衷。它涉及我在CMS中标记页面(或任何其他内容,如文档)的一组表 我有三张桌子: 页面(页面) 标签(标签) TagLink(tags\u link)是页面和标记之间的多对多链接表 Pages是一个简单的表(我已经从下面的代码中删除了无关紧要的列): 虽然有一个自引用列(parent\u tag\u id),但标记也非常简单: TagLink同样相当简单: CREATE TABLE `tags_link` ( `tag_id`
页面
)标签
)tags\u link
)是页面和标记之间的多对多链接表parent\u tag\u id
),但标记也非常简单:
TagLink同样相当简单:
CREATE TABLE `tags_link` (
`tag_id` int(11) NOT NULL,
`module_type` varchar(50) NOT NULL,
`foreign_key` int(11) NOT NULL,
UNIQUE KEY `Unique` (`tag_id`,`module_type`,`foreign_key`),
KEY `Search` (`module_type`,`foreign_key`),
KEY `AllByTagId` (`tag_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
复杂的因素是TagLink能够链接数据库中的任何其他表,而不仅仅是页面。例如,如果我有一个文档上传部分,那么它也可以被标记。为了方便这种工作方式,有一个有效的多列键
为了更清楚地说明这一点,我将演示在将标记添加到表(例如页面)时可能会运行的几个插入查询:
如您所见,module\u type
列只是一个任意字符串,用于描述外键的位置。但是,这不是表的名称,因为任何具有ID的对象都可以有链接到它的标记,即使它不一定在MySQL数据库中
现在转到PageTable
中的Zend\u Db\u表$\u参考地图:
protected $_referenceMap = array(
'TagLink' => array(
'columns' => 'id',
'refTableClass' => 'Models_Tag_TagLinkTable',
'refColumns' => 'foreign_key'
),
);
但这不考虑我的任意module_type
列,将返回具有相同外键的任何标记链接。很明显,这是不好的,因为你会得到一些文档的标记链接,比如页面的标记链接
因此,我的问题是,在设置此引用时,如何考虑此附加列?这样做的目的是避免像我现在这样为每个模块类型
使用一个TagLink类
我可以想象下面这样的东西可以解释我的要求,尽管很明显这不是怎么做到的:
protected $_referenceMap = array(
'TagLink' => array(
'columns' => 'id',
'refTableClass' => 'Models_Tag_TagLinkTable',
'refColumns' => 'foreign_key',
'where' => 'module_type = "Pages"'
),
);
我当前的实现以以下方式覆盖文档中的\u fetch
方法:
protected function _fetch(Zend_Db_Table_Select $select) {
$select->where("module_type = 'Documents_Secondary_Tags' OR module_type = 'Documents_Primary_Tags' OR module_type = 'Documents'");
return parent::_fetch($select);
}
正如您所看到的,可能还会有多组标记添加到任何对象。Zend Framework参考中“获取依赖行集”中的示例3演示了一种可以使用的技术:
虽然它没有显示select中包含的“where”子句,但它应该可以工作
邓肯一个与我的答案几乎相同的问题。。但有了更好的代码示例:(来自Bill Karwin,非常可靠)这正是我最终要做的。这不完全是我想要的,但它能完成任务。
protected $_referenceMap = array(
'TagLink' => array(
'columns' => 'id',
'refTableClass' => 'Models_Tag_TagLinkTable',
'refColumns' => 'foreign_key'
),
);
protected $_referenceMap = array(
'TagLink' => array(
'columns' => 'id',
'refTableClass' => 'Models_Tag_TagLinkTable',
'refColumns' => 'foreign_key',
'where' => 'module_type = "Pages"'
),
);
protected function _fetch(Zend_Db_Table_Select $select) {
$select->where("module_type = 'Documents_Secondary_Tags' OR module_type = 'Documents_Primary_Tags' OR module_type = 'Documents'");
return parent::_fetch($select);
}