如何在使用较少内存的单列中存储多个值?

har*_*h4u 6 mysql

我有一个用户表,其中1列存储用户的"角色".我们可以为特定用户分配多个角色.

然后我想在"角色"列中存储角色ID.

但是,如何将多个值存储到单个列中以便以易于使用的方式保存内存?例如,使用逗号分隔字段存储并不容易并且使用内存.

有任何想法吗?

小智 13

如果用户可以拥有多个角色,则最好有一个user_role存储此信息的表.它被规范化,并且查询起来会容易得多.

像这样的表:

user_id | role
--------+-----------------
      1 | Admin
      2 | User
      2 | Admin
      3 | User
      3 | Author
Run Code Online (Sandbox Code Playgroud)

将允许您查询具有特定角色的所有用户,例如SELECT user_id, user.name FROM user_role JOIN user WHERE role='Admin'不必使用字符串解析来从列中获取详细信息.

除此之外,这将更快,因为您可以正确地索引列,并且比任何将多个值放入单个列的解决方案所占用的空间略大 - 这与关系数据库的设计是相对立的.

不应该存储的原因是它效率低,因为DCoder在评论中说明了这个答案.要检查用户是否有角色,需要扫描用户表的每一行,然后必须使用字符串匹配扫描"角色"列 - 无论此操作如何公开,RMDBS都需要执行字符串操作来解析内容.这些是非常昂贵的操作,并没有完善的数据库设计.

如果您需要一个专栏,我强烈建议您不再遇到技术问题,而是人员管理问题.将其他表添加到正在开发的现有数据库中应该不难.如果这不是您有权做的事情,请向合适的人解释为什么需要额外的表 - 因为多个值复制到一个列中是个主意.


小智 7

您还可以在 MySQL 中使用按位逻辑。role_id必须在 BASE 2 (0, 1, 2, 4, 8, 16, 32...)

role_id | label
--------+-----------------
      1 | Admin
      2 | User
      4 | Author

user_id | name  | role
--------+-----------------
      1 | John  | 1
      2 | Steve | 3
      3 | Jack  | 6
Run Code Online (Sandbox Code Playgroud)

按位逻辑允许您选择所有用户角色

SELECT * FROM users WHERE role & 1
-- returns all Admin users

SELECT * FROM users WHERE role & 5
-- returns all users who are admin or Author because 5 = 1 + 4

SELECT * FROM users WHERE role & 6
-- returns all users who are User or Author because 6 = 2 + 4
Run Code Online (Sandbox Code Playgroud)


JTC*_*JTC 0

你可以做这样的事情

INSERT INTO table (id, roles) VALUES ('', '2,3,4');
Run Code Online (Sandbox Code Playgroud)

然后找到它使用FIND_IN_SET

  • JTC - 问题是,正如 @DCoder 指出的那样,您的答案是查询时效率非常低 - 而且我假设用户角色的读取次数比写入次数多得多,因此读取优化比什么更重要OP认为他们会得到的“内存节省”。 (5认同)
  • 这根本不会提高性能,数据库仍然需要扫描整个表来查找匹配项。 (4认同)
  • 我认为 StackOverflow 并不是一个鼓励我们“直接手动编辑到数据库”的解决方案的地方。OP问了一个问题,最好的答案是“不要做你所想的,正确地做”。 (3认同)
  • @akostadinov 这是一个经典的 [XY 问题](http://meta.stackexchange.com/q/66377/226333)。当用户要求某件事时,在这种情况下,这绝对不是他们想要的。未来的多表解决方案将更干净、更快、更容易维护。 (2认同)