我相信您会发现这篇博文很有趣:标签: 数据库模式
问题:您想要一个数据库模式,您可以在其中标记
带有任意数量标签的书签(或博客文章或其他内容)。
稍后,您想要运行查询以将书签限制为
标签的并集或交集。您还想排除(例如:减号)
搜索结果中的一些标签。
“MySQLicious”解决方案
在此解决方案中,模式只有一个表,它是非规范化的。这种类型被称为“MySQLicious解决方案”,因为MySQLicious将del.icio.us数据导入到具有这种结构的表中。
交叉点(与)
查询“search+webservice+semweb”:
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags LIKE "%semweb%"
联盟(或)
查询“search|webservice|semweb”:
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
OR tags LIKE "%webservice%"
OR tags LIKE "%semweb%"
减
查询“search+webservice-semweb”
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags NOT LIKE "%semweb%"
“天窗”解决方案
Scuttle将其数据组织在两个表中。该表“scCategories”是“标签”表,并且具有“书签”表的外键。
交叉点(与)
查询“书签+webservice+semweb”:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
HAVING COUNT( b.bId )=3
首先,搜索所有书签标签组合,其中标签为“bookmark”、“webservice”或“semweb”(c.category IN ('bookmark', 'webservice', 'semweb')),然后仅搜索已考虑搜索到的所有三个标签(HAVING COUNT(b.bId)=3)。
联盟(或)
查询“bookmark|webservice|semweb”:只需省略 HAVING 子句即可获得并集:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
减号(排除)
查询“bookmark+webservice-semweb”,即:bookmark AND webservice AND NOT semweb。
SELECT b. *
FROM scBookmarks b, scCategories c
WHERE b.bId = c.bId
AND (c.category IN ('bookmark', 'webservice'))
AND b.bId NOT
IN (SELECT b.bId FROM scBookmarks b, scCategories c WHERE b.bId = c.bId AND c.category = 'semweb')
GROUP BY b.bId
HAVING COUNT( b.bId ) =2
省略 HAVING COUNT 会导致查询“bookmark|webservice-semweb”。
“毒”解决方案
Toxi想出了一个三表结构。通过表“tagmap”,书签和标签是n对m相关的。每个标签可以与不同的书签一起使用,反之亦然。 wordpress 也使用此数据库模式。
查询与“scuttle”解决方案中的查询完全相同。
交叉点(与)
查询“书签+webservice+semweb”
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
HAVING COUNT( b.id )=3
联盟(或)
查询“书签|webservice|semweb”
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
减号(排除)
查询“bookmark+webservice-semweb”,即:bookmark AND webservice AND NOT semweb。
SELECT b. *
FROM bookmark b, tagmap bt, tag t
WHERE b.id = bt.bookmark_id
AND bt.tag_id = t.tag_id
AND (t.name IN ('Programming', 'Algorithms'))
AND b.id NOT IN (SELECT b.id FROM bookmark b, tagmap bt, tag t WHERE b.id = bt.bookmark_id AND bt.tag_id = t.tag_id AND t.name = 'Python')
GROUP BY b.id
HAVING COUNT( b.id ) =2
省略 HAVING COUNT 会导致查询“bookmark|webservice-semweb”。