文章分類和標簽的數據庫設計


幾乎在所有web項目中,都涉及文章分類和標簽的設計,應該說這是一個比較常見、典型的案例。站長並不保證我的思路就是最好的,只是分享出來大家一起交流一下,互相促進與提高。

我們假設的開發項目是一個博客系統,最核心的部分就是與文章相關的,那么我們今天討論如何設計博客系統的文章分類和標簽。

1、首先,分類和標簽都是要和具體的文章相關聯的,當然也可能一些文章既沒有分類也沒有標簽,這一點是大家在寫查詢的時候容易疏忽的地方。因為我們的第一感覺就是,在查詢文章列表的時候關聯分類表,查出所有的文章和分類,對應關系一般是文章表的分類id對應分類表的id,使用where子句進行限定。這里就存在一個問題了,由於使用了where子句,那么只能查詢有分類的文章,而沒有分類的文章就查詢不到了。這時候怎么辦?應該使用連接查詢,left join,這要沒有分類的文章,在文章分類id那一欄會顯示null。通常我們只使用left join,而很少使用right join。

2、一般,一篇文章最好只對應一個分類,當然如果你想要對應多個分類也可以。但站長並不提倡,文章在多個分類中重復會給人很不專業的感覺,即使有些文章可能確實設計到多方面的內容,那么你應就其中的側重點來分類。而標簽就不一樣了,一篇文章可能有多個標簽。這就意味着我們無法靠一個sql語句既查出所有文章的分類和標簽,又做到查詢結果中的文章id不重復。通常我們需要把查詢出來的結果直接循環出來,那么這個結果一般是二維數組,第二維的都存儲了唯一一篇文章的相關信息。但是,標簽和文章是多對一的關系,多個標簽對應一篇文章,如果你只用一條sql語句的話,那么我們查詢出來的結果,當然也是多行,這不符合我們目標數據的要求。應此,需要在查詢完文章和分類之后,在前面結果的基礎上再查詢一次文章標簽,把兩次的結果結合起來,存在數組中,這是對應文章列表頁面的查詢方法。對於具體文章頁面,可以分兩次查詢。

好了,還沒有給出具體的數據庫設計,就先說了如何查詢結果,相信大家也看煩了,下面就舉例說明:

一、文章表:post,字段如下:

id【唯一標識】,aid【作者id】,title【標題】,content【內容】,cid【分類id】

二、分類表,category,字段如下:

id【唯一標識,與post表的cid關聯】,name【分類名】

三、標簽表,tag,字段如下:

id【唯一標識】,name【標簽名】

四、標簽與文章對應關系表,tag_relationship,字段如下:

id【唯一標識】,postid【文章id,與post表的id關聯】,tagid【標簽id,tag表的id關聯】

有朋友可能會問:為什么要單獨用一個表來存儲文章與標簽的對應關系,為什么不可以直接在tag表中增加一個文章id字段呢,比如:

tag表:

id,postid,name

這樣做的話,並不是不可以,但是,由於一篇文章對應多個標簽,所以name字段的值會出現很多重復,比如一篇文章,假設文章id為1,有2個標簽,php和mysql,那么在tag表會這樣存儲:

id:1,postid:1,name:php

id2,postid:1,name:mysql

另一篇文章,假設id為2,有2個標簽,也是php和mysql,那么在tag表中它會這樣存儲:

id:3,postid:2,name:php

id4,postid:2,name:mysql

大家很快就發現了問題,這樣的設計name字段也就是標簽的名稱在同一張表中可能會大量重復。但是這樣設計的好處是,如果你要查詢一個標簽下有多少篇文章,只要單獨查這個表就可以了,比如要查詢含有php標簽的文章有多少篇,只需要select count(name) from tag where name=’php’,就可以查出來。不好的地方是,如果要查詢所有標簽的集合,使用這種設計需要使用group by name語句來去除重復的行。如果用之前的那種,只需要select * from tag就可以了。一時之間,好像不太好取舍。這兩種設計都會有數據冢余,第一種tag_relationship表中,存在tagid字段的重復;而這兩種設計又都有各自的好處。那么我們到底該怎么選擇呢?站長也說不好,所以無法為大家下結論。但是站長在研究wordpress數據結構的時候,發現wp是采用的單獨建表存儲文章與標簽對應關系的方式。

另外,如何設計有時候也是取決具體功能的需求的,所以這個問題就留給大家一起來討論吧~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM