2011-06-14 58 views
1

我有以下表格(type,id,title)。Doctrine2:相關密鑰

當創建新的對象和類型= 1個ID應該是1,類型= 1個ID = 2的下一個對象。但是,當我創建的對象類型= 2 ID應該是1

哪有我用Doctrine2和Symfony2來做?

+0

你對我來說意義不是很清楚。你正在處理兩個獨立的實體並試圖將它們存儲在同一個表中嗎?如果是這樣,爲什麼? – Problematic 2011-06-14 22:49:43

+0

不,這是一個實體。 'type'是類別,並且在每個類別id中應該包含。獨立於其他人。 – nucleartux 2011-06-14 22:57:34

+0

如果id是主鍵,則不能在同一個表中執行此操作。我想你可以有一個category_id字段並以編程方式爲每個類別構建它,但據我所知,Doctrine不會支持這種開箱即用的方式。 – Problematic 2011-06-14 23:11:17

回答

2

像其他人所說的那樣,Doctrine 2並沒有開箱即用。通常的做法是使ID字段自動增量,並在這種情況下不可能使用主鍵。主鍵必須是唯一的。

隨着中說,一個解決方案可以是使用實體設法找到ID的最大值,其中所述類型是所選擇的類型和由1

遞增該值例如:

// Retrieve the current maximum ID for the selected type 
$id = $em->createQuery("SELECT MAX(e.id) AS id FROM Entities\entity e WHERE e.type = ?1") 
    ->setParameter(1, $type) 
    ->getSingleScalarResult(); 

// Set your current entity's ID 
$entity->setId(++$id); 

// Save the entity 
... 
+0

這就是我想要的。 – Problematic 2011-06-14 23:32:18

+0

併發性如何?當兩個請求試圖同時創建一個實體並且它們都「選擇max」並且獲得相同的id時,會發生什麼?因此創建兩個具有相同id的實體(除非設置了一個唯一的屬性,這會在插入時引發異常無論如何)。 – Jens 2012-06-07 16:29:20

1

正如我上面的評論所指出的那樣,我認爲不直接支持你想要開箱即用的東西。但是,我認爲您應該能夠用class table inheritance來近似它,其中type類別中的每一個都是它自己的實體,它們在類表上共享公用數據並跟蹤其自己的索引。

+0

我不能使用表繼承,因爲它們應該動態創建。 – nucleartux 2011-06-14 23:19:42

2

使用MAX(id)不是最好的解決方案,因爲它可能會導致一些問題。如果刪除給定類別中的最新記錄,然後添加一個新記錄,會發生什麼?它將具有與以前一樣的ID。

  1. 複合主鍵(typeid)沒有很好的處理原則,到目前爲止,所以我建議創建一個經典的主鍵:整數,自動增量鍵(至少在原則的使用)。此外,您始終可以在typetype_id列上獲得唯一索引,並在需要時使用它。
  2. 創建您自己的type_id列的自動增量實現:next_auto_increment,其存儲將用於值:

    1. 作爲type_id類型你可以在type表中存儲附加列相關下一個記錄。
    2. 每當你在你的餐桌只需選擇價值創造的新紀錄爲它的type_idtype表:

      $type = ...; 
      
      $entity = new Entity(); 
      $entity->setType($type); 
      $entity->setTypeId($type->getNextAutoIncrement()); 
      // btw: typeId is not a very best name 
      
      $em->persist($entity); 
      
    3. 您還需要一個觸發在數據庫中每次插入時間遞增的next_auto_increment值記錄(例如MySQL的):

      DELIMITER $$ 
      CREATE TRIGGER increment_ai AFTER insert ON entity_table FOR EACH ROW BEGIN 
          UPDATE type_table 
          SET next_auto_increment = next_auto_increment + 1 
          WHERE id = NEW.type; 
      END$$ 
      DELIMITER ;