【发布时间】:2011-01-15 20:15:32
【问题描述】:
我们有一个包含用于在网站上格式化的 HTML 标记的字段,但我们只需要查询应该在屏幕上呈现的文本,而不是 CSS 标记、标记名称、属性名称等内容。
有没有办法忽略 SQL 查询或存储过程中的标记?如果有办法做到这一点,我们以后会不会出现性能问题?
我的猜测是有某种方法可以使用尖括号来解析可搜索文本的字段。
【问题讨论】:
我们有一个包含用于在网站上格式化的 HTML 标记的字段,但我们只需要查询应该在屏幕上呈现的文本,而不是 CSS 标记、标记名称、属性名称等内容。
有没有办法忽略 SQL 查询或存储过程中的标记?如果有办法做到这一点,我们以后会不会出现性能问题?
我的猜测是有某种方法可以使用尖括号来解析可搜索文本的字段。
【问题讨论】:
【讨论】:
这样的处理不应该在数据库中进行。我建议创建一个仅包含文本内容的单独字段。
回应@Nissan Fans 评论:从 HTML 中提取文本不是 IMO 数据库的工作。它的工作太复杂了,它有太多的变数。我不精通阅读存储过程,但如果我正确阅读代码,它会在源代码中出现(无效但仍经常发生)未编码的< 的问题。而且它很可能会因为无效的 HTML 而中断。
或者想象有一天,客户来了,并希望 img 元素的 ALT 属性也被索引。或titles。使用“开始位置,结束位置”算法开始构建它。你会发疯。
我说,如果需要在日常基础上处理来自您无法控制的不同来源的 HTML,请将其留给 DB 之上的层,以便更好地处理这些东西。基于 DOM 的方法——也许使用 BeautifulSoup 来处理无效的 HTML——解析所有 nodeValues 将是最可靠的方法。
也许这是矫枉过正,存储过程在 OP 的情况下可以正常工作 - 从他的评论中看起来很像,这完全没问题。我只是说,如果您无法控制传入的 HTML,请不要使用数据库为这项工作提供的有限手段来剥离 HTML。
【讨论】:
我同意 Pekka 的观点;这不是您的数据库应该处理的事情。
在数据库中进行这种解析的缺点:
性能问题。使用 UDF 会降低性能并导致表扫描。即使你避免了表扫描,你仍然要求数据库做一堆它不是设计要做的事情(字符串操作)。
更难做到正确。正确解析 HTML 是一项艰巨的工作。确实,您可以使用 UDF 完成 95% 的工作,但在应用程序层处理此问题可能会让您完成 100% 的工作。
更难测试。我更愿意为在 C# 中针对字符串文字执行的 HTML 剥离代码编写单元测试,而不是往返于数据库。
如果您必须在数据库中执行此操作...
如果需要在数据库中执行此操作,请考虑以下方法:
向您的数据库添加第二个字段以保存内容的纯文本版本。
添加触发器,以便每次更改 HTML 值时,都会重新生成文本版本。
针对纯文本字段编写查询。
您将获得更好的性能,因为您只在写入时进行解析,而不是在每次搜索时进行,并且您的数据库将更好地利用您在纯文本字段中定义的任何索引。
【讨论】:
如果您可以在查询中运行正则表达式,则可以使用此处的示例去除 HTML 并仅返回文本:http://www.regular-expressions.info/examples.html
【讨论】:
如果您尝试索引这些列之一并通过删除 html 来访问它:
WHERE dbo.anyRemoveHtml(yourColumn)='your search text'
不会使用索引,您将进行表扫描。当应用程序的数据很少时,这可能不是问题,但随着向表中添加更多数据,会导致 SELECT 越来越慢。
注意:dbo.anyRemoveHtml 只是一个虚构的名称,代表您选择删除 HTML 的函数,实际上并不存在
【讨论】: