PHP标签Tag的设计模式

没有太多时间进行全文翻译,就把重点挑出来,用自己的话串起来,名曰 选择性翻译。 以后可能会比较多的采用这种方式。

  社会书签的tag存储一直是一个比较麻烦的问题。

  一个好的数据表设计,不但要能准确查出tag,还应该支持tag的AND/OR/NOT查询。我们来看看解决方案。

  “MySQLicious” solution

  表结构

  存储实例

  Intersection (AND)

  “search+webservice+semweb”类的查询:

  SELECT *

  FROM `delicious`

  WHERE tags LIKE "%search%"

  AND tags LIKE "%webservice%"

  AND tags LIKE "%semweb%"

  Union (OR)

  “search|webservice|semweb”类的查询:

  SELECT *

  FROM `delicious`

  WHERE tags LIKE "%search%"

  OR tags LIKE "%webservice%"

  OR tags LIKE "%semweb%"

  Minus

  “search+webservice-semweb”类的查询

  SELECT *

  FROM `delicious`

  WHERE tags LIKE "%search%"

  AND tags LIKE "%webservice%"

  AND tags NOT LIKE "%semweb%"

  优点:

  只有一个表 SQL比较直接

  可以用mysql的全文检索来做,效率更高

  缺点:

  tag的数量受到限制,通常我们都用varchar,这种字段只256个字节长。否则,你需要用text类型,速度会变慢。(Easy注,PHP(PHP培训 php教程 )more的tag用的就是TinyText)

  Like ‘%things%’不精确,当然某些应用中,这反而是需要的

  “Scuttle” solution

  数据表

  Intersection (AND)

  Query for “bookmark+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

  首先,所有书签-tag组合被搜出来 (c.category IN (‘bookmark‘, ‘webservice‘, ‘semweb‘)), ,然后选择其中包含三个的(HAVING COUNT(b.bId)=3)

  Union (OR)

  Query for “bookmark|webservice|semweb”:

  只需要去掉?AND查询中的HAVING子句:

  SELECT b.*

  FROM scBookmarks b, scCategories c

  WHERE c.bId = b.bId

  AND (c.category IN (’bookmark’, ‘webservice’, ’semweb’))

  GROUP BY b.bId

  Minus (Exclusion)

  Query for “bookmark+webservice-semweb”, that is: 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

  好处: 我觉得这个方案比前一个方案好的最大理由是,可以有无限个tag。

  “Toxi” solution

  数据表

  Intersection (AND)

  Query for “bookmark+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

  Union (OR)

  Query for “bookmark|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

  Minus (Exclusion)

  Query for “bookmark+webservice-semweb”, that is: 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

  Leaving out theHAVING COUNTleads to the Query for “bookmark|webservice-semweb”.

  好处:

  你可以给每个tag添加额外的信息

  这是最规范的方案,第三范式。

  坏处:

  删除tag时,你要从多个表中删除(Easy注,Mysql5的话,可以用trigger来做)

  然后我们把视线从功能转移到性能上。

  A+B

  250个tag

  999个tag

  A OR B

  250个tag

  添加速度比较

  测试代码下载?Download the source code (PHP) LGPL协议。

时间: 2024-10-05 22:02:08

PHP标签Tag的设计模式的相关文章

JSP自定义分页标签TAG

首先我们需要在WEB-INF/tld/目录下创建page.tld文件 <?xml version="1.0" encoding="ISO-8859-1"?> <taglib> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>page</short-name> <u

struts2 官方系列教程三:使用struts2 标签 tag

避免被爬,先贴上本帖地址:struts2 官方系列教程一:使用struts2 标签 tag http://www.cnblogs.com/linghaoxinpian/p/6901316.html 本教材假定你已完成了HelloWorld项目,你可以在 struts2 官方系列教程三:使用struts2 标签 tag 下载本章节的代码 在上一节教程中,我们在index.jsp中使用 url tag 创建了一个超链接hello.action 这节我们将探索struts2中其它tags Web应用程

一、变量.二、过滤器(filter).三、标签(tag).四、条件分支tag.五、迭代器tag.六、自定义过滤器与标签.七、全系统过滤器(了解)

一.变量 ''' 1.视图函数可以通过两种方式将变量传递给模板页面 -- render(request, 'test_page.html', {'变量key1': '变量值1', ..., '变量keyn': '变量值n'}) -- render(request, 'test_page.html', locals()) # locals() 就是将视图函数中的所有变量都传递给模板页面 2.模板页面中对变量的使用 def dtl(request): num = 3.14 ss = '大碗宽面' #

Struts2 自定义下拉框标签Tag

自定义标签主要包括三个步骤: 1.编写java类,继承TagSupport类: 2.创建tld文件,影射标签名和标签的java类: 3.jsp页面引入tld. 例子:自定义下拉框标签 如果页面上有下拉选择框,通常最好的解决方法是使用数据字典,因为有可能多个页面 使用同一个下拉框,便于后台统一维护. 自定义Tag类 import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.

androi自定义自动换行的View(类似网页的标签Tag)

看来只有礼拜天才有时间写点博客啊,平时只能埋头苦干了.今天在公司加班,遇到一个需求,就是自动换行的TextView,有点像网页的tag标签,点击一下,就自动加上去了,不过这个是根据后台拿来的数据来显示多少个View,在网上找找,看见了许多,我自己也封装写一个吧,以便以后需要...开工 package com.woyou.ui.component; import android.content.Context; import android.util.AttributeSet; import an

jsp自定义标签tag EL函数

原文:jsp自定义标签tagEL函数 源代码下载地址:http://www.zuidaima.com/share/1550463459052544.htm 简单易懂的自定义EL函数 tag.java </pre><p> </p><pre name="code" class="java">package com.zuidaima.tag; import java.io.IOException; import javax.

DESTOON B2B标签(tag)调用手册

什么是标签调用?标签调用是根据调用条件(condition)从数据表(table)读取调用数量(pagesize)条数据,并按排序方式(order)排序,最终通过标签模板的布局输出数据.可以看出,标签的工作分两个部分,一是读取数据,二是显示数据. 标签函数原型标签函数保存于 include/tag.func.php tag($parameter, $expires = 0) $parameter 表示传递给tag函数的字符串,系统自动将其转换为多个变量.例如传递 table=destoon&pa

Java解析HTML标签Tag

import java.util.HashMap; import java.util.Map; public class TagParser { private Integer index = 0; private char[] tagChar; private int position = 0; /* 解析符号 */ private char symbol = '"'; public static final String START_SCRIPT = "<script&quo

ASP.NET MVC View中的标签(tag)

在编辑View的时候会用到各种HTML标签,如<a>,<input>,<p>等待,这些标签在ASP.NET MVC中都有对应的编程语法,它叫Razor,它是帮助我们动态的生成HTML标签,好处是可以绑定数据. 现在就让我们来复习一下HTML标签的用法:<input>, 因为它是最常用的表单标签之一,所以先从它开始. 可以移步:http://www.w3cschool.cn/htmltags/tag-label.html 看下它的定义. 基本都是用于接收用户输