2017-06-04 40 views
1

雄辯查詢我有兩個表標籤和聯繫,我的標籤表如下所示:如何優化它有一個外鍵

enter image description here

而且我的管理員表如下所示:

enter image description here

admin表中的標記字段是外鍵,它引用了標記表中的標識。我想要做的是,用特定的tag拉起管理表中的記錄,現在管理表中的tag現在引用tags表中的id

所以我寫了下面的查詢來從管理表中檢索具有特定標籤(例如Javascript)的文章。

public function showTagListing($tag) { 
     $tagId = DB::table('tags')->where('tag', $tag)->first(); 
     $tagBlogList = DB::table('admin')->where('tag', $tagId->id)->orderBy('created_at' , 'desc')->get(); 
     return view('pages.taglisting', compact('tagBlogList', $tagBlogList)); 
    } 

我想我已經寫在這裏檢索文章記錄代碼一些額外的不必要的線,我怎樣才能使代碼在同一行?我如何優化這些代碼行?

+0

在性能優化方面,您不能做更多。你可以做一個連接而不是兩個查詢(這是大多數情況下應該表現更好)。但就可維護性和代碼的完整性而言,您可以做很多事情。要開始你應該創建[模型](https://laravel.com/docs/5。4/eloquent)爲您的每個數據庫表,並相應地創建它們之間的關係(即Admin belongsTo Tag,Tag有許多Admin ...)。 – devk

+0

實際上,從性能水平來看,你應該可以用1個查詢來完成這個操作,而不需要連接,使用'WHERE EXISTS(...)' - 如何用雄辯的方式做到這一點,你可以看到Sandeesh的答案。 – devk

回答

1

您可以添加一些掛羊頭賣狗肉,通過依賴注入導出$tag並通過添加一些邏輯來你RouteServiceProvider

Route::bind('tag', function ($value) { 
    if (is_int($value)) { 
     return App\Tag::findOrFail($value); 
    } else { 
     return App\Tag::where('tag', $value)->firstOrFail(); 
    } 
}); 

boot方法,通過比primary key之外的另一列解決它,那麼你可以改變你的路線因此,它需要一個標記實例,無論primary key integertag string

//no idea how your route looks, but the important part is {tag} 
Route::get('/show-tag-listing/{tag}', '[email protected]'); 

最後,更新喲烏爾功能通過依賴注入解決標籤:

public function showTagListing(App\Tag $tag) { 

現在你不再需要$tagId =,你可以只使用$tag->id以後。

您還可以確保在模型文件中建立了您的關係。因爲您對管理表tag_id,該$tag會有很多管理記錄,以及adminhaveOne標籤,就像這樣:

// App\Tag class 

public function admins() 
{ 
    return $this->hasMany('App\Admin'); 
} 

// App\Admin class 

public function tag() 
{ 
    return $this->belongsTo('App\Tag'); 
} 

而不是做現在:

$tagBlogList = DB::table('admin')->where('tag', $tagId->id)->orderBy('created_at' , 'desc')->get(); 

你可以做:

$tagBlogList = $tag->admins()->orderBy('created_at', 'desc')->get(); 
+0

幾件事要注意。當使用模型綁定時,請使用'findOrFail'和'FirstOrFail',以便在到達控制器之前拋出404並失敗。 '$ tagBlogList = $ tag-> load('admins') - > orderBy('created_at','desc') - > get();'將帶有博客的標籤作爲相關對象返回。 '$ tagBlogList = $ tag-> admins() - > orderBy('created_at','desc') - > get();'應該做所期望的事情。 – Sandeesh

+0

@Sandeesh對,好點。已更新以反映這些更改。 – Ohgodwhy

1
public function showTagListing($tag) 
{ 
    $tagBlogList = DB::table('admin') 
     ->join('tags', 'tags.id', '=', 'admin.tag') 
     ->where('tags.tag', $tag) 
     ->latest() 
     ->select('admin.*') 
     ->get(); 

    return view('pages.taglisting', compact('tagBlogList')); 
} 

我如果你想去雄辯的方式,那麼你可以做到這一點。用關係創建適當的模型。

public function showTagListing($tag) 
{ 
    $tagBlogList = Admin::whereHas('tags', function ($query) use($tag) { 
      $query->where('tag', $tag); 
     }) 
     ->latest() 
     ->get(); 

    return view('pages.taglisting', compact('tagBlogList')); 
}