2009-09-03 38 views
1

我有3個表MySQL數據庫:如何找到補充標籤?

  1. 叫 「軌道」記錄的主表(如音樂)
  2. 一個標籤表 所謂的「標籤」
  3. 聯接表這兩個叫做「標籤」

標籤表基本上是一個流派的列表,它是預定義的。一個曲目可以有一個或多個標籤(通過連接表)。

想法是,用戶檢查他或她想要找到曲目的流派(標籤)。但我也希望界面反映哪些標籤不再「有用」,即與當前選擇標籤互補的標籤。

編輯:我錯過的是,我需要找到與當前選擇的標籤互補的標籤。看到我下面的評論。例如:用戶選擇「搖滾」和「流行」標籤,並顯示匹配「搖滾」+「流行」的曲目列表。但假設數據庫中沒有跟蹤匹配「爵士樂」。在這種情況下,我想禁用界面中的「爵士」標籤,因爲「搖滾」+「流行」+「爵士」會給出零結果。

有沒有一種巧妙的方式來與MySQL做到這一點?

+0

我添加了另一個選項,它實際上只是第一個選項的重複,但也許它不會殺死您的客戶端。 – scottm 2009-09-03 18:25:38

+0

一位朋友指出了一些事情,這使事情變得複雜:查詢應該找到可能的「連續」標籤,可以這麼說。即如果你尋找標籤1和/或3,你會發現有一個或兩個的軌道。到現在爲止還挺好。但是下面的查詢會告訴我們軌道是否有標籤1&X,_or_ tag 3&X,但實際上需要的是看是否有軌道有標籤1 _和_ 3 _和_ X.這就使得這一切非常棘手,至今我可以告訴 – Flambino 2009-09-04 00:43:02

回答

0

落得這樣做的:

  • 當一個音軌被標記,其標籤ID被級聯(按順序),並加入到一個1列的查找表(當然也給的Tagging)。例如。 「1,2,4,6,9」被添加到查找中(這是前導/後綴逗號的原因)
  • 當在搜索時選擇標籤時,它們被類似地連接,並用於LIKE從查找表中選擇包含這些標籤ID的所有連接
  • 然後處理找到的連接以獲取它們包含的所有ID
  • 無論結果列表中的哪個ID與選定的ID不匹配
1
select 
    tagid 
from 
    taggings 
where 
    trackid in ([list of, or subquery for your selected tracks]) 

禁用所有標記,除非結果包含其標識。或者禁用所有標籤,然後重新啓用由此查詢返回的標籤。你也可以做一些重組並將其轉換爲「不在」查詢,但通常會變慢。

+0

我認爲重點是讓控件啓用並允許用戶點擊它們。 – scottm 2009-09-03 16:24:20

+0

嗯,是的,用戶應該能夠點擊「有意義」的標籤控件。無論是更有效率的東西是禁用所有,然後啓用一些,或啓用所有,然後禁用一些,我不知道。取決於最有效的查詢是什麼;發現標籤與已發佈的標籤一起使用,或者找到那些與現有標籤不匹配的標籤。 – Flambino 2009-09-03 16:58:43

+0

由於通常需要對錶進行全面掃描,因此「未進入」查詢效率低下,而「入」只需要搜索,直到第一次點擊。 '不在'更容易閱讀和理解,但效率較低。如何處理檢索後的數據處理,如果不瞭解更多關於界面設計的知識,我不能說。 – krdluzni 2009-09-03 17:40:05

0

這可能不是最有效的:

SELECT 
    TagId --to disable 
FROM Tags 
WHERE TagId NOT IN(
    SELECT Distinct TagId FROM Taggings WHERE TrackId IN (
     SELECT TrackId FROM Taggings WHERE TagId in (1, 2) 
    ) 
) 
  1. 獲取匹配當前選定的標籤的所有曲目。
  2. 以在此列表中

分配給那些軌道

  • 禁用標籤不編輯
    所有標籤這個怎麼樣:

    SELECT 
        DISTINCT TagId 
    FROM 
        Taggings 
    GROUP BY 
        TagId, 
        TrackId HAVING TrackId IN (
         SELECT 
          TrackId 
         FROM 
          Taggings 
         WHERE 
         TagId in (1, 2) 
        ) 
    

    這將返回所有標籤應被啓用。

  • +0

    嗯..崩潰我的MySQL客戶端:-) 麻煩的是,我有成千上萬的軌道,我需要的界面是真正的響應。雖然你的答案可能會起作用,但可以這麼說,這似乎太蠻橫。 我在想,應該可以找到一起使用的tag_ids,只需從所選標籤的簡短列表中選擇,而不是成千上萬的track_ids列表。 – Flambino 2009-09-03 16:56:04

    +0

    是的,我覺得這會有點粗糙。我認爲你不會只用標籤就能做到。我確實認爲你必須有足跡才能知道剩下的標籤可能性。 – scottm 2009-09-03 17:05:17

    +0

    是的,你可能是對的。但現在我正在考慮添加另一個帶有不同標籤組合的表格,以便快速查找。我會讓這個問題坐在這裏一段時間,看看會發生什麼。但感謝迄今爲止的輸入! – Flambino 2009-09-03 18:14:54

    0

    您是否可以控制標籤如何添加到軌道?如果你可以掛鉤,你可以創建一些額外的元數據。

    實質上是標籤之間的多對多連接。每次添加標籤時,都會爲該軌道上的每個舊標籤添加一條記錄,該記錄包含舊標籤/新標籤對(以較低的ID作爲減少重複的第一個值)。 IIRC,有一種方法可以設置表忽略重複插入,而不是拋出錯誤。在刪除標籤時,您還必須管理此表,這會更加耗時,但這可能是罕見的事件。

    有了上面你有一個簡單的查詢,以確定仍在相關標籤:

    select 
        tag_a 
    from 
        related_tags 
    where 
        tag_b in ([tags_already_in_search]) 
    union 
    select 
        tag_b 
    from 
        related_tags 
    where 
        tag_a in([tags_already_in_search]) 
    

    該解決方案本質上轉移一些地方的標籤添加和刪除的處理時間的時間點。

    +0

    有趣!我會試試這個。是的,我正在考慮創建一個與您所描述的完全相同的2列查找表,這正是因爲它會將服務器負載移動到不同的時間點,並且因爲我完全控制了何時添加/刪除/更改了標籤。 – Flambino 2009-09-03 19:40:58