针对mysql文本类型列的查找

dnph8jn4  于 2021-06-20  发布在  Mysql
关注(0)|答案(4)|浏览(267)

我的table/模型 TEXT 输入column,在筛选模型本身上的记录时,ar where 生成正确的sql并返回正确的结果,我的意思是:

MyNamespace::MyValue.where(value: 'Good Quality')

生成此sql:

SELECT `my_namespace_my_values`.* 
FROM `my_namespace_my_values` 
WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'

再举一个我加入的例子 MyNamespace::MyValue 同时过滤 value 列,但来自另一个模型(在模型上与 my_values ). 请参见(查询#2):

OtherModel.joins(:my_values).where(my_values: { value: 'Good Quality' })

这不会产生正确的查询,这会在 value 列,就像它是字符串列而不是文本一样,因此会产生不正确的结果(仅粘贴相关的位置):

WHERE my_namespace_my_values`.`value` = 'Good Quality'

现在我可以通过像在我的ar里那样做来克服这个问题 where ,将生成正确的结果,但查询略有不同。这就是我的意思:

OtherModel.joins(:my_values).where('my_values.value LIKE ?, '%Good Quality%')

终于来回答我的问题了。这是什么?它是如何为模型上的where(对于文本列类型)生成的?

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'

也许最重要的问题是,使用以下工具在性能方面有什么不同:

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'

还有这个:

(my_namespace_my_values.value LIKE '%Good Quality%')

更重要的是,如何使用连接(query#2)获取查询,其中产生如下结果:

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
wswtfjt7

wswtfjt71#

我想这可能会有帮助。
若要搜索\n,请将其指定为\n。要搜索\,请将其指定为\这是因为反斜杠被解析器剥离一次,然后在进行模式匹配时再次剥离,只留下一个反斜杠进行匹配。
链接
like和=是不同的运算符。
=是对数字和字符串进行操作的比较运算符。比较字符串时,比较运算符比较整个字符串。
like是一个字符串运算符,用于逐个字符进行比较。

mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
|                                    1 |
+--------------------------------------+
c3frrgcw

c3frrgcw2#

(部分回答——从mysql端接近。)
什么匹配/不匹配
案例1:(我不知道多余的反斜杠和引号是从哪里来的。)

WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'

\"Good Quality\"               -- matches
Good Quality                   -- does not match
The product has Good Quality.  -- does not match

案例2:(发现 Good Quality 任何地方 value .)

WHERE my_namespace_my_values.value LIKE '%Good Quality%'

\"Good Quality\"               -- matches
Good Quality                   -- matches
The product has Good Quality.  -- matches

案例3:

WHERE `my_namespace_my_values`.`value` = 'Good Quality'

\"Good Quality\"               -- does not match
Good Quality                   -- matches
The product has Good Quality.  -- does not match

性能:
如果 value 已声明 TEXT ,所有病例均进展缓慢。
如果 value 没有索引,一切都很慢。
如果 valueVARCHAR(255) (或更小)和索引,情况1和3更快。它可以快速找到一行,而不是检查所有行。
措辞不同: LIKE 使用前导通配符( % )速度很慢。
为列编制索引对于性能很重要,但是 TEXT 无法编制索引。

35g0bw71

35g0bw713#

这是什么?它是如何为模型上的where(对于文本列类型)生成的?
这是在活动记录(arel)词汇引擎后面生成的。关于第二个问题,请看我的回答。
使用…在性能方面有什么不同。。。
“=”按整个字符串/块比较匹配,而like按字符(按字符)匹配。
在我的项目中,我得到了数百万行的表,根据我的经验,使用comparator“=”或regexp比在查询中使用like要快得多。
我如何用连接(query#2)得到我的查询,产生这样的结果。。。
你能试试这个吗,

OtherModel.joins(:my_values).where(OtherModel[:value].eq('\\\"Good Quality\\\"'))
slwdgvem

slwdgvem4#

“=”op正在寻找精确匹配,而like op的工作方式更像模式匹配,“%”与正则表达式中的“*”类似。
所以如果你有
品质优良
质量更好
只有喜欢才能得到两种结果。
关于转义字符串,我不确定这是在哪里生成的,但看起来像是一些标准化的转义,以使其对sql有效。

相关问题