2010-01-11 100 views
0

我和我的同事正在開發一個與Stackoverflow類似的網站,但是用於提交任務(以及用於內部使用)。今天早上我們談論了標記任務,並且不能真正確定哪個選項是最快的選項,或者如果我們不缺少某些東西。如何表示DB中兩個項目之間的關係?

讓我們來想象帶有標籤的表格,這些標籤會根據用戶動態更新。用戶可以創建任何標籤並將其添加到此表中。情況如下:

  • ID

我會得到點實際的吧。例如,如果您點擊標籤「PHP」,它會向您顯示另一頁,其中包含所有標記爲「PHP」的任務。類似於this page。重要的是這相關標籤列表。如何在數據庫中表示它?

有兩種選擇出現在我們的腦海中,但我不認爲它們中的任何一個都是最有效的。

  1. 使用「PHP」標記選擇所有任務並檢查它們包含的其他標記。幾年之後,我們可能會從服務器獲得答案。

  2. 請與COLS表標籤相關標籤計數其中將所有可能的標記關係。只有我們看到的問題是雙重性。我們可以標記PHP和相關標記DB2,但我們也可以使用相關標記PHP來標記DB2,這當然是非常相同的關係,並且具有相同的計數。

我其實很喜歡選項#2,但沒有重複性。也許選擇標籤之間沒有如此密切關係的地方(就好像沒有任何「主要」和「次要」標籤)可以最好地工作。在這一點上,我並不十分確定,我不想塑造一些在未來無法工作的東西,或者如果有一百萬個標籤會太慢。

我們將使用PHP和mySQL或DB2,但我想這並不重要。

所以,實際的問題是:有沒有其他的,可能更好的選擇?如有任何問題,請問我。

在此先感謝。

+0

嗯,我會選擇2,並擁抱可能性的重複性,因爲這可以讓你有單向標籤,從而你總是搜索相關標籤基於最左邊的列 即你總是搜索標籤= [無論]你只是消費RelatedTag。如果你看到我的意思,那麼你可以將「PHP」標記爲「DB2」,而不必將「DB2」與「PHP」聯繫起來,因爲我傾向於認爲DB2-> PHP不一定與PHP-> DB2 ....然後再次有可能我瘋了大聲笑。 而且我不會擔心即使是1M標籤。索引/磁盤空間將照顧你:) – 2013-01-18 19:07:52

回答

1

我假設你這樣做是因爲想要「顯示與'tag'相關的前N個標籤'」查詢的速度非常快。

如果你在DB中這樣做,那麼你的第二種方法是最好的。您甚至可以考慮創建一個索引,該索引在標記字段上升序並在相關標記計數字段中降序。

但是,如果您真的想要速度,請考慮將其表示爲內存數據結構。

1

我想如果你有一個「分配給任務X的標籤」的表格,並帶有正確的/聰明的索引,那麼按照選項1)中所述找到標籤不應該花費那麼長時間才能使用連接。這將是最有活力的方法。

選項二將爲您提供一種方法來執行「標籤X通常與標籤Y和Z一起使用」查詢,並且可以在創建新任務時靜態填充,但是,例如,標籤被添加或從任務中刪除。對於方法1)這將是自動的。由於您沒有存儲任務ID,所以方法2(如您所述)不允許您獲取當前任務的相關標記,正好爲。但是,如果你這樣做了,你的方法與方法1)相同。

1

我假設您使用單獨的表格(只是task-id,tag-id)表示任務標記關係,因此您描述的第一個選項將是從任務表到標記的「簡單」連接表使用任務標籤關係表。恐怕我的SQL知識已經乾涸了一點,所以我不相信自己會給你建議究竟是什麼類型的INNER/OUTER/LEFT/RIGHT加入,也不會告訴你什麼類型的表現可以期望從適當的索引建立等等。試試看,這可能是最好的辦法...... sql語句可以使用Visual Studio/Access /可能是其他的東西來構建。

我會假設你的第二種方法更快,如果你希望你的數據庫中有很多項目。但是,我肯定會建議你做適當的性能測試來確定這一點而不是猜測。無論哪種方式,只要存儲其中一個標記標記對(例如db2-php而不是php-db2),就可以擺脫重複性。例如,可以通過按ID排序來確定要存儲哪一個,以便始終將它們與具有最小ID的標記一起存儲。

我也猜測你的第一個選擇是更快開始使用,這樣你就可以開始使用它,然後一旦有時間或者一旦它成爲一個性能問題,就選擇第二個選項。

相關問題