仅针对特定其他列值的一列索引

时间:2017-09-20 09:09:45

标签: mysql mariadb entity-attribute-value

我'有表日志,其中有两个字段:action(VARCHAR 45)和info(VARCHAR 10000)。

此表中记录了多个内容,其中一个是访问页面时的用户ip。对于这种情况action =' ip',info =' IP.ADD.RE.SS'。

由于info可以为记录的特定内容提供大量文字,因此我只想创建适用于info =' ip&#的action字段的INDEX 39;只有这样我才能快速搜索IP,并且没有过度生长的索引"动作"。

我已经尝试过为前15个字符创建INDEX,但是IP条目仍占所有内容的1%,对我来说似乎有点矫枉过正。 整个解决方案都是从其他人那里继承而来的,遗憾的是我现在无法改变整个架构

任何消化怎么做正确的方法?它甚至可能吗?

3 个答案:

答案 0 :(得分:1)

这似乎属于“EAV”类别。你有很多东西(ip,postdel等),每一个都是可选的。其中一些需要索引,有些则不需要。

我的建议是将键值对放在void Main() { string link = "<https://api.github.com/user/repos?page=3&per_page=100>; rel=\"next\",< https://api.github.com/user/repos?page=50&per_page=100>; rel=\"last\""; LinkHeader linkHeader = LinkHeader.FromHeader(link); } 字符串中。并为您想要索引的任何事物制作一个特殊列(在您的情况下为IP)。它可以是JSON,以便最小化(但不能完全消除“浪费的”空间。

另请参阅我的blog on EAV

另请参阅MySQL和MariaDB的涉及JSON的实现。注意:它们需要相对较新版本的MySQL或MariaDB。

答案 1 :(得分:1)

某些RDBMS产品支持您所描述的内容。它被不同的产品称为partial or filtered indexes

MySQL没有实现这个想法(他们没有义务实现它,因为它是一个非标准的功能)。有人要求将此作为新功能:https://bugs.mysql.com/bug.php?id=76631

您可以在MySQL 5.7中模拟部分索引的一种解决方法是创建一个虚拟列,其值为NULL,除非action是'ip'。然后索引该虚拟列:

ALTER TABLE logs
  ADD COLUMN ip_info VARCHAR(12) 
    AS (CASE `action` WHEN 'ip' THEN LEFT(info, 12) END),
  ADD KEY (ip_info);

严格来说,它仍会为每一行编制索引,但至少它不会在索引中存储任何值,除非操作是“ip”。

P.S。:我没有测试过上面的例子,所以如果有语法错误就道歉。

答案 2 :(得分:0)

您仍然会对操作列进行过滤,因此合并索引就是此处的解决方案。在列(action, info(15))上创建索引。

但索引中列的顺序很重要。不要反过来改变它。