2016-05-24 17 views
0

我正在研究一個數據庫,它允許我存儲嵌套標籤和類別,並且證明很難找出一種相對簡單的查詢方法。我使用的是Laravel,所以另一個障礙是確保它以合理的方式與Eloquent兼容。用於存儲嵌套標籤和類別的數據庫結構

目前,我嘗試了兩種方法。

的第一種方法是有稱爲entities單個表,其中有一個type柱,設置爲tagcategory。對於正在使用的數據結構來說,這看起來工作得很好,但對查詢有點不愉快。

第二種方法是有兩個表,每個類型一個表。這是一個完整的噩夢,因爲這兩個表都需要有兩個父列,並且使用理智的代碼進行查詢變得不可能。

所以,我假設第一種方式是正確的。 有沒有一種明智的方式來安排模型和數據庫遷移?我如何準確地查詢數據庫?這是我的模型(文件是指文件被標記):

class Entity extends Model 
{ 
    public function children() { 
     return $this->hasMany('App\Entity'); 
    } 
    public function parent() { 
     return $this->belongsTo('App\Entity'); 
    } 
    public function files() { 
     return $this->belongsToMany('App\File')->withTimestamps(); 
    } 
} 

我的遷移(order是確保標籤和類別顯示在正確的位置,如果兄弟姐妹一欄也應該讓我。使用JavaScript在前端重新排列,這是我沒有研究正確尚未):

Schema::create('entities', function (Blueprint $table) { 
    $table->increments('id')->unsigned(); 
    $table->integer('order'); 
    $table->enum('type', ['tag', 'category']); 
    $table->string('name'); 
    $table->string('title'); 
    $table->text('description')->nullable(); 
    $table->integer('entity_id')->unsigned()->nullable(); 
    $table->timestamps(); 

    $table->foreign('entity_id')->references('id')->on('entities'); 
}); 

這是數據結構的工作示例由前端,我將需要從生成利用數據庫:

[ 
    { 
     "__type": "Tag", 
     "id": "water", 
     "name": "Water", 
     "description": "Containing water of any kind.", 
     "checked": false, 
     "children": [ 
      { 
       "__type": "Tag", 
       "id": "salt_water", 
       "name": "Salt Water", 
       "description": "Salt Water, for example in the Ocean.", 
       "checked": false, 
       "children": [] 
      }, 
      { 
       "__type": "Category", 
       "id": "fresh_water", 
       "name": "Fresh Water", 
       "description": "Fresh Water, such as rivers and lakes.", 
       "children": [ 
        { 
         "__type": "Tag", 
         "id": "river", 
         "name": "River", 
         "description": "A river of water.", 
         "checked": true, 
         "children": [] 
        }, 
        { 
         "__type": "Tag", 
         "id": "lake", 
         "name": "Lake", 
         "description": "A lake of water.", 
         "checked": false, 
         "children": [] 
        } 
       ] 
      } 
     ] 
    }, 
    { 
     "__type": "Category", 
     "id": "species", 
     "name": "Species", 
     "description": "The Species of creature.", 
     "featured": true, 
     "children": [ 
      { 
       "__type": "Tag", 
       "id": "dog", 
       "name": "Dog", 
       "description": "Canis Familiaris.", 
       "checked": false, 
       "children": [] 
      }, 
      { 
       "__type": "Tag", 
       "id": "cat", 
       "name": "Cat", 
       "description": "Felis Catus.", 
       "checked": false, 
       "children": [ 
        { 
         "__type": "Tag", 
         "id": "tiger", 
         "name": "Tiger", 
         "description": "A tiger.", 
         "checked": false, 
         "children": [] 
        } 
       ] 
      } 
     ] 
    } 
] 
+0

您的解決方案不工作嗎?我可以很快看到模型如何與孩子/父母實體相關。您將需要執行一些翻譯以使輸出json匹配所需的格式。沒有測試過,這似乎很穩固。 –

+0

@ j.steelman說實話,現在我的主要問題似乎是搞清楚如何檢查哪些是「檢查」。我剛剛意識到的事情將是一個問題。你知道是否有辦法檢查哪些是通過數據透視表連接的,所以我可以將它們標記爲'checked:true'? – Forest

回答

0

,如果你在PHP數組有你的數據已經,您可以使用這些遞歸函數的一個

function getChecked($root) 
{ 
    $output = []; 
    if(!is_array($root) && !isset($root['children'])) 
    { 
     $root = array($root); 
    } 
    foreach($root as $item) 
    { 
     if(isset($item['checked']) && $item['checked']) { 
      if(isset($item['children'])) 
      { 
       $children = getChecked($item['children']); 
       $item['children'] = $children; 
      } 
      $output[] = $item; 
     } 
    } 
    return $output; 
} 

function getChecked_lazy($root) 
{ 
    $output = []; 
    if(!is_array($root) && !isset($root['children'])) 
    { 
     $root = array($root); 
    } 
    foreach($root as $item) 
    { 
     if(isset($item['children'])) 
     { 
      $children = getChecked_lazy($item['children']); 
      $item['children'] = $children; 
     } 
     if((isset($item['checked']) && $item['checked']) || isset($item['children']) && !empty($item['children'])) 
     { 
      $output[] = $item; 
     } 
    } 
    return $output; 
} 

$data = [ 
    [ 
     "id" => "dog", 
     "checked" => true, 
     "children" => [ 
      [ 
       "id" => "wolf", 
       "checked" => true, 
      ], 
      [ 
       "id" => "fox", 
       "checked" => false 
      ], 
     ] 
    ], 
    [ 
     "id" => "cat", 
     "checked" => false, 
     "children" => [ 
      [ 
       "id" => "lion", 
       "checked" => true 
      ], 
     ], 
    ], 
]; 

echo json_encode(getChecked($data), JSON_PRETTY_PRINT); 
echo "\n"; 
echo json_encode(getChecked_lazy($data), JSON_PRETTY_PRINT); 

輸出:

 
[ 
    { 
     "id": "dog", 
     "checked": true, 
     "children": [ 
      { 
       "id": "wolf", 
       "checked": true 
      } 
     ] 
    } 
] 
[ 
    { 
     "id": "dog", 
     "checked": true, 
     "children": [ 
      { 
       "id": "wolf", 
       "checked": true 
      } 
     ] 
    }, 
    { 
     "id": "cat", 
     "checked": false, 
     "children": [ 
      { 
       "id": "lion", 
       "checked": true 
      } 
     ] 
    } 
] 

或者您也可以通過SQL這裏檢查查詢=真實,然後嘗試找到根(父母爲空)。

或其他方式