查找MYSQL TEXT类型列

时间:2018-05-22 22:58:19

标签: mysql ruby-on-rails activerecord

我的表/模型有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\\\"'

4 个答案:

答案 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未编入索引,则一切都很慢。
  • 如果valueVARCHAR(255)(或更小)已编入索引,则案例1和案例3会更快。它可以快速找到一行,而不是检查所有行。

不同的说法:

    带有前导通配符(LIKE)的
  • %速度很慢。
  • 对列进行索引对性能很重要,但无法对TEXT编制索引。

答案 1 :(得分:2)

&#39; =&#39; op正在寻找完全匹配,而LIKE op的工作更像是模式匹配&#39;%&#39;类似于&#39; *&#39;在正则表达式中。

所以,如果你有

的条目
  1. 质量好
  2. 更优质
  3. 只有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。要搜索\,请将其指定为   \\这是因为解析器会将反斜杠剥离一次   并且当模式匹配时,留下一个反斜杠   与...相匹配。

link

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 |
+--------------------------------------+
相关问题