我的表/模型有TEXT
类型列,当过滤模型本身的记录时,AR where
生成正确的SQL并返回正确的结果,这就是我的意思:< / p>
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
列上过滤,就像它是一个String列而不是Text一样,因此会产生不正确的结果(仅粘贴相关位置):
WHERE my_namespace_my_values`.`value` = 'Good Quality'
现在我可以通过在我的AR where
中做LIKE来解决这个问题,这会产生正确的结果,但查询略有不同。这就是我的意思:
OtherModel.joins(:my_values).where('my_values.value LIKE ?, '%Good Quality%')
最后来到我的问题。 这是什么以及如何为模型的位置(文本列类型)生成?
WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
也许最重要的问题使用:
在性能方面有何不同?WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
和此:
(my_namespace_my_values.value LIKE '%Good Quality%')
更重要的是如何通过连接获取我的查询(查询#2)产生类似的内容:
WHERE `my_namespace_my_values`.`value` = '\\\"Good Quality\\\"'
答案 0 :(得分:5)
(部分答案 - 从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
未编入索引,则一切都很慢。value
为VARCHAR(255)
(或更小)且已编入索引,则案例1和案例3会更快。它可以快速找到一行,而不是检查所有行。不同的说法:
LIKE
)的%
速度很慢。TEXT
编制索引。答案 1 :(得分:2)
&#39; =&#39; op正在寻找完全匹配,而LIKE op的工作更像是模式匹配&#39;%&#39;类似于&#39; *&#39;在正则表达式中。
所以,如果你有
的条目只有LIKE会得到两个结果。
关于转义字符串,我不确定它的生成位置,但看起来像是一些标准化的转义,以使其对SQL有效。
答案 2 :(得分:2)
这是什么以及如何在模型的哪个位置生成(for 文本列类型)?
这是在Active Records(Arel)词汇引擎背后产生的。 请参阅下面关于您的第二个问题的答案。
使用...
的性能有何不同
&#34; =&#34;匹配整个字符串/块比较 LIKE按字符匹配(按字符匹配)。
在我的项目中,我得到了数百万行的表格,从我的经验来看,使用比较器真的更快#34; =&#34;或regexp而不是在查询中使用LIKE。
如何通过连接获取查询(查询#2)产生这样的地方......
你能试试吗,
OtherModel.joins(:my_values).where(OtherModel[:value].eq('\\\"Good Quality\\\"'))
答案 3 :(得分:2)
我认为这可能会有所帮助。
搜索\ 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 |
+--------------------------------------+