我正在制作一个新闻系统,使用独特的slu to来识别文章。在创建新文章时,我需要确保该独特的slug尚未使用。因此,如果两篇文章具有完全相同的名称,则它们将生成完全相同的slug。我希望在它正在使用的情况下在slug的末尾添加一个数字。
像这样:
等等。因此,在我的测试用例中,我选择的数据库中的所有记录都与“一些非常有趣的文章”完全匹配,并带有0或更多“-number”。因此,在这种情况下,我将返回3行,因此下一个slug将是“some-really-interesting-article-3”。
这很有效,除了我的正则表达式表现特殊(或者可能非常正常,我只是吮吸正则表达式)并且还返回具有部分匹配的行。因此,如果我搜索“有些非常有趣”,那就会过去。
SELECT id, title, slug
FROM news
WHERE slug RLIKE '([[:<:]]some-really-interesting-article[[:>:]][-\d]*)'
正如我所说的,如果我用“some-really-interesting”运行上面的正则表达式,它将返回所有3行。
请告诉我,我公然无知地做错了。感谢。
答案 0 :(得分:1)
尝试
WHERE slug RLIKE '(^some-really-interesting-article(-[0-9]+)?$)'
答案 1 :(得分:1)
这个怎么样?
"^some-really-interesting-article(-[[:digit:]]+)?$"
希望这会奏效:)
答案 2 :(得分:0)
正如其他人已经指出的那样,这将有效:
SELECT id, title, slug FROM news
WHERE slug RLIKE '^some-really-interesting-article(-[0-9]+)?$'
然而,MySQL不够聪明,无法充分利用RLIKE
的索引。 (如果slug
列上有索引,它可能会尝试使用它,但必须进行完整的索引扫描。)但事实证明,您可以使用冗余LIKE
帮助MySQL更有效地处理查询的条件,如下所示:
SELECT id, title, slug FROM news
WHERE slug LIKE 'some-really-interesting-article%'
AND slug RLIKE '^some-really-interesting-article(-[0-9]+)?$'
LIKE
查询可能会匹配某些误报,例如some-really-interesting-article-about-something-else-entirely
,但RLIKE
会将它们排除在外。当然,如果你不关心这些误报,你可以完全忽略RLIKE
。
当然,另一种可能性是在slug
列上创建一个唯一索引(无论如何你应该拥有它)并且只是继续增加slug并尝试插入记录直到INSERT
成功。当然,这也意味着你应该检查错误代码和消息,看看它失败的原因。 (如果INSERT
由于重复值而失败,则error code应为1062,error message应包含重复键的名称。)
无论如何,here an SQLize link如果你想玩查询;我留下了一些评论。