2009-09-03 36 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