【问题标题】:Symfony Doctrine Database Schema relation to different databaseSymfony Doctrine Database Schema 与不同数据库的关系
【发布时间】:2011-07-26 08:16:12
【问题描述】:

我在设计 Doctrine 数据库架构时遇到了这个问题。假设我有 2 个数据库,A 和 B。

我已经制作了数据库 A 架构,现在我需要制作数据库 B 架构。在数据库 B 中,其中一张表与数据库 A 的表有关系。这就是问题所在,我怎样才能将 B 与 A 联系起来?

【问题讨论】:

    标签: symfony1 doctrine schema


    【解决方案1】:

    @Dziamid 说对了一半。

    从技术上讲,您不能将两个表连接到单独的数据库。但是您可以假装它会进行任何真正的干预。

    配置多个数据库连接:

    //databases.yml
    all:
      items_db:
        class:          sfDoctrineDatabase
        param:
          dsn:          mysql://login:passwd@localhost/items
      stores_db:
        class:          sfDoctrineDatabase
        param:
          dsn:          mysql://login:passwd@localhost/stores
    

    为每个模型定义正确的连接

    //schema.yml
    Item:
      connection: items_db
      columns:
        store_id: integer(4)
      relations:
        Store:
          local: store_id
          foreign: id
          foreignAlias: Items
    
    Store:
      connection: stores_db
      columns:
        name: string(255)
    

    现在您可以像往常一样使用您的 Doctrine 模型了:

    // like this
    $item = new Item();
    $store = new Store();
    $store->save();
    $item->setStore($store);
    
    // or like this
    $item->getStore(); 
    

    唯一的限制是您不能在 DQL 查询中进行连接。

    $query = Doctrine_Query::create()
        ->from('Store s')
        ->leftJoin('s.Items i')
        ->fetchAll();
    

    但您可以使用 from Doctrine_Collections 加载关系。

    $stores = Doctrine::getTable('Store')->findAll(); // this returns a Doctrine_Collection
    $stores->loadRelated('Items');
    

    这与 Doctrine_Query 的工作方式相同。

    【讨论】:

    • 真的吗?外键约束呢?
    • Doctrine 负责数据完整性(外键)。这正是 orm 的本意。我们在大批量生产应用中广泛使用它。像魅力一样工作。
    • 您无法真正确保数据库之间的数据完整性,对吗?在更新与另一个数据库有“关系”的表时,Doctrine 必须连接到这两个数据库。我没有见过这样的行为。此外,我尝试构建您的模式但失败了 - 因为,就像我说的那样,学说会生成一个约束 ALTER TABLE item ADD CONSTRAINT item_store_id_store_id FOREIGN KEY (store_id) REFERENCES store(id) NOT DEFERRABLE INITIALLY IMMEDIATE; 并且数据库无法应用它。我认为这只适用于不关心约束的mysql MyISAM引擎。
    • 如果设置正确,Doctrine 将不会尝试创建外键,因此外键约束问题将不适用。 Doctrine 是一个 ORM 和 DBA(数据库抽象)层。它的目的是在数据库无法做到这一点时尽可能地确保数据库的完整性。是的,Doctrine 将在保存或查询关系时打开两个连接并执行两个单独的查询。如果您有问题,那是因为您的 symfony/doctrine 配置或示例存在问题。但是这个概念是可靠的并且被广泛使用。我的公司使用它取得了巨大的成功。
    • 在使用多个理论数据库连接时,一些 symfony 1.4.x 发行版也存在一个已知问题。 Symfony/Doctrine 将忽略 'connection' 属性并始终连接最后定义的数据库。这可能会导致您的问题。
    【解决方案2】:

    您不能在不同数据库中的表之间建立关系。如果这样做,您最终会遇到外键约束错误。但是,您可以做的是保留一个空的关系 ID 字段并从另一个连接手动加载相关数据。例如:

    Item:
      columns:
        store_id: integer(4)
      #relations:
      #  Store:
      #    local: store_id
      #    foreign: id
      #    foreignAlias: Items
    
    Store:
      columns:
        name: string(255)
    
    class Item extends BaseItem
    {
      protected $_store = null;
    
      public function getStore()
      {
        if (null == $this->_store)
        {
          $this->_store = Doctrine::getTable('Store')->findOneById($this->store_id);
        }
        return $this->_store;
      }
    
      public function setStore(Store $store)
      {
        $this->store_id = $store->id;
      }
    }
    

    现在您可以像使用 Item 和 Store 一样使用它们:

    $item = new Item();
    $store = new Store();
    $store->save();
    $item->setStore($store);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多