如何使用快速二进制操作在MySQL中操作SET数据类型?

时间:2016-10-08 08:56:13

标签: mysql set bit-manipulation

我希望有效地存储和有效地操作MySQL中记录的位标志。 SET 数据类型满足第一个愿望,因为最多64个标志存储为单个数字。但那第二个怎么样?我只看到像

这样的尴尬解决方案
UPDATE table_name SET set_col = (set_col |  4) WHERE condition;
UPDATE table_name SET set_col = (set_col & ~4) WHERE condition;

分别包含和排除成员的值。即我必须使用数字常量,这使得代码不可维护。然后我也可以使用 INT 数据类型。如果set_col定义被更改(添加,删除或重新排序可能的成员),具有硬编码常量的代码就变得一团糟。我可以尝试对编码器强制执行一些规则,只使用应用程序语言中的命名变量而不是数字常量,这样可以使维护更容易,但不能完全防错。有没有一个解决方案,其中 MySQL会将集合成员的符号名称解析为正确的数值?例如。这不起作用:

UPDATE person SET tag=tag | 'MGR'

为了阻止无用的答案,我知道数据库规范化和单独的m-to-n关系表,这不是这里的主题。如果你需要一个更具体的例子,那么你就是:

CREATE TABLE `coder` (
    `name` VARCHAR(50) NOT NULL,
    `languages` SET('Perl','PHP','Java','Scala') NOT NULL
)

设置定义的更改不太可能,但可能是每隔一年,例如将“Perl”拆分为“Perl5”和“Perl6”。

1 个答案:

答案 0 :(得分:0)

我在这里找到答案: https://dev.mysql.com/doc/refman/5.7/en/set.html

  

John Kozura发表于2011年4月12日

     

至少请注意MySQL   5.1+,似乎用额外的逗号处理得很好,因此可以非常简单地设置/删除单个位,而无需创建   “正确的”清单。所以即使像SET flags =',,, foo ,, bar ,,'也可以   好的,如果你不关心截断的数据警告。

     

添加位:

UPDATE tbl SET flags=CONCAT_WS(',', flags, 'flagtoadd');
  

删除位:

UPDATE tbl SET flags=REPLACE(flags, 'flagtoremove', '')
  

..或者如果你有一点这个名字是另一个像的名字   “foo”和“foot”,稍微复杂一点:

UPDATE tbl SET flags=REPLACE(CONCAT(',', flags, ','), ',foo,', ',')
  

如果警告确实引起了您的问题,则会发布解决方案   以上工作:

     

添加:

UPDATE tbl SET flags=TRIM(',' FROM CONCAT(flags, ',', 'flagtoadd'))
  

删除:

UPDATE tbl SET flags=TRIM(',' FROM REPLACE(CONCAT(',', flags, ','), ',flagtoremove,', ','))