我希望有效地存储和有效地操作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”。
答案 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,', ','))