【问题标题】:Modeling objects with multiple table relationships in Zend Framework在 Zend Framework 中对具有多个表关系的对象进行建模
【发布时间】:2010-10-12 22:09:40
【问题描述】:

我正在玩弄 Zend 框架,并尝试对我正在制作的网站使用“快速入门”指南,以了解该过程如何工作。如果这个答案很明显,请原谅我,希望有经验的人能对此有所了解。

我有三个数据库表:

CREATE TABLE `users` (
  `id` int(11) NOT NULL auto_increment,
  `email` varchar(255) NOT NULL,
  `username` varchar(255) NOT NULL default '',
  `first` varchar(128) NOT NULL default '',
  `last` varchar(128) NOT NULL default '',
  `gender` enum('M','F') default NULL,
  `birthyear` year(4) default NULL,
  `postal` varchar(16) default NULL,
  `auth_method` enum('Default','OpenID','Facebook','Disabled') NOT NULL default 'Default',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `email` (`email`),
  UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE `user_password` (
  `user_id` int(11) NOT NULL,
  `password` varchar(16) NOT NULL default '',
  PRIMARY KEY  (`user_id`),
  UNIQUE KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE `user_metadata` (
  `user_id` int(11) NOT NULL default '0',
  `signup_date` datetime default NULL,
  `signup_ip` varchar(15) default NULL,
  `last_login_date` datetime default NULL,
  `last_login_ip` varchar(15) default NULL,
  PRIMARY KEY  (`user_id`),
  UNIQUE KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

我想创建一个在某些情况下使用所有三个表的用户模型。例如,如果/当需要元数据时访问元数据表。只有设置了“默认”auth_method,才能访问 user_password 表。稍后我可能会添加一个我希望能够从用户模型访问的配置文件表。

采埃孚最好的方法是什么?为什么?

【问题讨论】:

  • 非常不清楚为什么这被否决:这个问题有问题吗?我找不到类似的问题来详细解释我正在寻找的问题。让我知道我是否可以更清楚。
  • 不知道,可能是数据过多?您可以将所有 SQL 替换为表的简要描述。
  • 似乎有人否决了所有新问题
  • @andybaird:你的标题有点不对劲。这些不是多个数据源,它们只是来自一个数据源(您的数据库)的多个表。对于大型应用程序来说,拥有很多表(就像真正的负载一样)是很正常的事情。

标签: php zend-framework model


【解决方案1】:

基本上不使用Zend_Db_Table,而是使用更通用的Zend_Db_SelectZend_Db_Statement 来检索数据。

顺便说一句。您可能不想直接在 User 模型中访问密码数据,而是在派生自 Zend_Auth_Adapter 的 User auth 类中访问。

【讨论】:

  • 我不打算通过用户模型访问密码数据,除了更新它。使用 Zend_Db_Select 不是完全规避了将用户数据建模为单个对象的想法吗?
  • 不是ORM,不需要1对1的类表映射。
  • 顺便说一句。如果您的数据库处于 3NF 中,则 1=1 映射是可能的,您的问题来自这样一个事实,即您对数据库进行了非规范化,将用户数据拆分为 3 个表。
【解决方案2】:

我想说,使用 ZF 做到这一点的最佳方法是使用 Doctrine

【讨论】:

    【解决方案3】:

    只需几条便条:

    第一个 User 表看起来更像是一个 Person 表,除了 auth 方法,但你可以把它放在 User_Password 表中,你可以重命名 User。 User_Metadata 表似乎可以与 User_Password/User 表合并。

    现在,即使没有这些更改,您也拥有三个不同的表,具有三个不同的概念,如果您将每个单独的表建模为不同的类,然后将 UserModel 类作为各种门面来访问每个表,那么很可能让它更容易。

    【讨论】:

      【解决方案4】:

      简而言之,我将为每个表创建一个模型,而不是一个访问所有三个表的模型。然后我会在桌子之间define relationships

      说实话,必须为每个表创建一个模型似乎不是很“干”,但这是我在网上的各种示例中反复看到的,也是我在少数几个项目中所做的使用 Zend 框架创建。如果有人有更好的处理方法,我希望将其发布在这里。

      【讨论】:

        【解决方案5】:
        class Users extends Zend_Db_Table_Abstract
        {
            protected $_name = 'users';
            protected $_rowClass = 'User';
            protected $_dependentTables = array ('UserMetadata', 'UserPassword');
        
        ...
        
        class UserMetadata extends Zend_Db_Table_Abstract
        {
            protected $_name = 'user_metadata';
            protected $_referenceMap = array (
            'Users'=> array (
            'columns'=>'user_id',
            'refTableClass'=>'Users',
            'refColumns'=>'id'
            )
            );
        
        ...
        
        class UserPassword extends Zend_Db_Table_Abstract
        {
            protected $_name = 'user_password';
            protected $_referenceMap = array (
            'Users'=> array (
            'columns'=>'user_id',
            'refTableClass'=>'Users',
            'refColumns'=>'id'
            )
            );
        

        获取数据:

        $id = //get your user id from somewhere
        
        $users = new Users();
        $user = $users->fetchRow('id=?', $id);
        if ($user->authMethod == 0)
        {
            $metadata = $user->findDependentRowset('UserMetadata')->current();
        }
        

        $user = $users->fetchRow($users->select()
                      ->where('gender=?, 'M')
                      ->order('email ASC');
        

        ...等等

        插入数据:

        $newRow = $users->fetchNew();
        $newRow->email = me@domain.com;
        $newRow->save();
        

        $users = new Users();
        $data = array('email'     => 'me@domain.com',
                      'firstname' => 'Me');
        $users->insert($data);
        

        更新:

        $user->email = 'me@domain.org';
        $user->save();
        

        删除一行:

        $user->delete();
        

        使用交易:

        $db->beginTransaction();
        $db->commit();
        $db->rollback();
        

        等等...都在ZF Manual

        【讨论】:

        • 这对我来说是最有意义的——那么你如何处理用户表的插入呢?从逻辑上讲,还应该创建一个 user_metadata 行。我可以在模型级别上以某种方式处理吗?
        • 在创建用户行时创建元数据行的逻辑您必须自己编写。但这很容易。如果您想以干净的方式使用事务...
        • 这正是我最终所做的,而且效果很好。谢谢。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-23
        相关资源
        最近更新 更多