【问题标题】:MySQL - Search the database by text string with special charactersMySQL - 通过带有特殊字符的文本字符串搜索数据库
【发布时间】:2016-02-03 06:36:00
【问题描述】:

我有一个新闻系统,我们需要您通过一个链接访问新闻的详细信息,该链接将采用新闻标题,而不是新闻 ID 数据库。

注意:有些发布的新闻中的单词和字母带有特殊字符,例如:

新闻标题:$title = Nuevo demo de la canción de ñandú;

这个标题用 PHP 爆炸去除连字符和空格会如下。

爆炸标题: $title_explode = explode(' ','-', $title);

看起来像这样: $title_filter = nuevo-demo-de-la-canción-de-ñandú;

我在数据库中创建了一个字段 title 在此字段中,$title 将被保存,并且我在数据库中还有另一个字段 title_filter,将放置在哪里标题$title_filter,它是被利用的标题,也将保存在数据库中,但我们有一个 ñ 和重音字母,我们可以查询数据库以将我带到这个记录流畅对比。

查询: $sql = SELECT * FROM news WHERE title = $title_filter;

新闻领域: www.dominio.com/nuevo-demo-de-la-canción-de-ñandú

我的问题:

  1. 这个搜索有效吗?
  2. 您可以优化和删除重音 $title 以使其:$title_filter = nuevo-demo-de-la-cancion-de-nandu;
  3. 值得创建数据库 title_filter 的附加字段以保存干净并对该标题进行标题搜索。

注意:不使用ID这个词来搜索数据库的想法是有更清晰的seo链接和改进网站。

希望你能理解我,能帮我解决这个难题,让数据库查询数据更有效。

【问题讨论】:

    标签: php mysql database


    【解决方案1】:

    我根据你给我的数据回答你:

    问题 1

    那个搜索不会给你任何结果,因为字段标题没有被过滤。这意味着,您正在比较:

    $title_filtered = 'Nuevo-demo-de-la-canción-de-ñandú';
    SELECT * FROM news  WHERE title = $title_filter
    

    title 包含 => 'Nuevo demo de la canción de ñandú'

    所以你应该把你的 SQL 查询改成这个:

    SELECT * FROM news WHERE title_filter = $title_filter

    问题 2

    是的,这可以通过两种不同的方式实现,都在 Stackoverflow 中进行了解释(我给你链接):

    • 使用正则表达式和字符串替换。
    • 使用字符列表替换
    • 使用翻译器 PHP 函数 iconv

    您可以在this stackoverflow 帖子中阅读这三个解决方案。解释得很好。

    问题 3

    当然是的,如果您不创建该字段,我们将影响您的应用程序的性能:

    1. 每次用户(或爬虫)访问您网站的任何网址时,您必须过滤标题
    2. 由于您只过滤了 URL,并且要应用过滤器您必须在数据库站点上执行此操作,这意味着不必要地过度使用数据库服务器。如您所知,这是一个众所周知的颈瓶。
    3. 这是一个巨大的安全漏洞,因为直接使用数据用户而不使用过滤器会将您暴露给SQL injections

    您可能怀疑拥有一个新字段的数据库空间消耗。但是不这样做的问题更相关,正如您在上面看到的,新标题的数量也不会导致任何空间内存问题。

    额外 - 关于过滤

    您遇到的一个可能问题是将空格替换为 - 的方式。如果你有这样的事情:

    $title = "This is a test "

    你的方法会过滤成这样:

    $title_filtered = "This-----is-a-test----"

    所以,为了避免这些问题,最好使用这样的正则表达式:

    $string = '    hello     world     ';
    $filters = array('@^[\t\s]+@', '@[\t\s]+$@', '@[\t\s]+@');
    $filtered = array('', '', '-');
    
    $title_filtered = preg_replace($filters, $filtered, $string);
    

    Extra - 关于数据库性能

    其他对您有帮助的建议是使用 MySQL 索引

    因为如果您没有,每次用户访问一个网址时,您都会对您的新闻表进行全面扫描,以搜索正确的行。这是不可扩展的,并且当您的流量和新闻数量增加时会给您的服务器带来额外的工作。

    要解决 MySQL 索引是最好的方法,请查看oficial page。简化,而不是对新闻表进行全面扫描,您只需搜索tree data structure

    用这个就够了:

    ALTER TABLE `news` ADD INDEX `index_title_filter` (`title_filter`)
    

    如果您想了解更多信息,请阅读this stackoverflow post

    【讨论】:

    • 太棒了!非常感谢您花时间回复。 1)我必须在数据库中插入没有特殊字符的优化标题吗?该标题将显示在新闻的详细信息中,并且想法是在标题的那一侧保留特殊字符。
    • 2) 如果我想保留标题的某些特殊字符会发生什么情况,我在数据库的标题字段中搜索标题 esepciales 字符,并将其显示在 URL 中分隔所有空格 guines 浏览器, 和不带重音的字母,你认为这种转换会是当我们查询数据库时而不是当新闻被嵌入数据库时​​,这样搜索数据库是否可行且有效。
    • 最好的选择是同时拥有两个字段,即过滤后的字段和另一个带有这些字符的字段。然后,当您检索 SQL 查询的输出时,您可以使用带有特殊字符的字段,因为使用 SELECT * => MySQL 将返回一个包含所有字段的新字段,包括已过滤和未过滤的标题。
    • 我必须这样做,创建两个字段,一个用于带有特殊口音的标题,另一个字段的标题不带空格,不带口音和特殊字符。可能出现的另一个困境是标题可以重复以避免这种情况,在插入之前创建了一个条件,如果现有标题我在末尾添加一个数字。关于安全性,如果你使用的是 Symfony、Laravel 或 Codeigniter 等框架……不用担心,这些都是相当安全的框架。 Miguel 非常感谢您的支持,祝您有愉快的一天。
    猜你喜欢
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    相关资源
    最近更新 更多