Php Zend_Db_表中的复杂引用映射用于说明多列键

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`

我将试图使这一点尽可能简单,但我担心用例超出了Zend_Db的初衷。它涉及我在CMS中标记页面(或任何其他内容,如文档)的一组表

我有三张桌子:

  • 页面(
    页面
  • 标签(
    标签
  • TagLink(
    tags\u link
    )是页面和标记之间的多对多链接表
  • Pages是一个简单的表(我已经从下面的代码中删除了无关紧要的列):

    虽然有一个自引用列(
    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);
    }