9

我有一个用户及其权限的数据库。例如,一行如下所示:

    Name    | sendMessages | receiveMessages | post | readPosts
------------+--------------+-----------------+------+----------
Jeff Atwood |      1       |        1        |  0   |     1

对于这种情况,单独的列(如示例中)或包含位掩码(在这种情况下,1101转换为0xD)的单个列更好?

4

4 回答 4

13

tinyint(1)因为布尔值通常是最好的方法。

使用位掩码进行查询效率不高,因为如果它必须计算它就不能使用索引,或者如果你尝试使用索引会变得非常讨厌

让我们看一下简单的查询

select * from tbl where sendMessages = 1 and readPosts = 1

单列将是:

select * from tbl where val&9 = 9

这并不是很有效,因为它必须进行全表扫描和计算。

让我们尝试重写查询,以便它可以使用索引。这可以通过列出所有可能的值来完成IN

select * from tbl where val in (9, 11, 13, 15)

现在想象一下,如果你想做简单的事情,这个查询会是什么样子where readPosts = 1

但是,如果您列出的值过多,mysql 优化器仍会进行全表扫描

于 2013-05-03T16:43:59.703 回答
8

不使用列作为权限,而是创建一个权限表和一个用户权限链接表呢?

于 2013-05-03T16:52:18.227 回答
1

最好将权限存储为具有BIT数据类型的单独列。大多数现代数据库引擎优化位列存储:

  • 对于表中最多 8 位的列,这些列存储在 1 个单字节中。
  • 对于 9 位和最多 16 位列,这些列存储在 2 个字节中,
  • 等等

因此,它充分利用了您列出的两个选项。通过位掩码需要更少的存储空间,同时保持多列的清晰度。引擎会为您处理。

于 2016-05-07T11:36:46.523 回答
0

使用位掩码,您不能使用第一个或最后一个位 0 和(32 投注中的 31 / 64 位中的 63 ???)但可以使用 pow(2, bit) & field = pow(2, bit) 轻松搜索

如果您需要超过 1 个可以处理的字段,那么您必须开始使用多个字段,然后您会陷入弄清楚您的位设置在哪个字段中的痛苦。

这可以很容易地通过一个简单的例程来克服,以根据您要查找的位和有问题的字段或行返回真或假。

但是对于权限,最好正如@CodeCaster 所说,使用权限表和链接表。

于 2015-08-25T10:58:57.070 回答