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

时间:2013-09-04 04:55:40

标签: mysql

我有一个用户表,其中1列存储用户的“角色”。 我们可以将多个角色分配给特定用户。

然后我想将角色ID存储在“角色”列中。

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

有什么想法吗?

4 个答案:

答案 0 :(得分:12)

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

表格如下:

user_id | role
--------+-----------------
      1 | Admin
      2 | User
      2 | Admin
      3 | User
      3 | Author

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

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

由于DCoder在comment to this answer上声明的原因,不应该存储它的原因是它效率低下。要检查用户是否有角色,需要扫描用户表的每一行,然后必须使用字符串匹配扫描“角色”列 - 无论此操作如何公开,RMDBS都需要执行字符串操作来解析内容。这些都是非常昂贵的操作,并没有完善的数据库设计。

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

答案 1 :(得分:3)

您也可以使用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

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

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

答案 2 :(得分:1)

你可以做这样的事情

INSERT INTO table (id, roles) VALUES ('', '2,3,4');

然后找到它使用FIND_IN_SET

答案 3 :(得分:1)

从你的问题我得到了什么,

假设你必须表。一个是"饭"表和另一个是" combo_meal"表。现在我想你想在一个combo_meal_id中存储多个meal_id而不分离昏迷[,]。而且你说它会使你的数据库更加标准化。

如果我的问题没有出错,请仔细阅读我的建议。它可能对你有帮助。

首先想到的是你的观念是对的。当然,它会为您提供更多标准数据库。

为此,您必须再创建一个表[example table:combo_meal_relation]来引用这两个表数据。可能是一个可见的例子将清除它。

meal table

+------+--------+-----------+---------+
|  id  |  name  | serving   |  price  |
+------+--------+-----------+---------+
|  1   | soup1  |  2 person |  12.50  |
+------+--------+-----------+---------+
|  2   | soup2  |  2 person |  15.50  |
+------+--------+-----------+---------+
|  3   | soup3  |  2 person |  23.00  |
+------+--------+-----------+---------+
|  4   | drink1 |  2 person |  4.50   |
+------+--------+-----------+---------+
|  5   | drink2 |  2 person |  3.50   |
+------+--------+-----------+---------+
|  6   | drink3 |  2 person |  5.50   |
+------+--------+-----------+---------+
|  7   | frui1  |  2 person |  3.00   |
+------+--------+-----------+---------+
|  8   | fruit2 |  2 person |  3.50   |
+------+--------+-----------+---------+
|  9   | fruit3 |  2 person |  4.50   |
+------+--------+-----------+---------+

combo_meal table

+------+--------------+-----------+
|  id  |  combo_name  | serving   |
+------+--------------+-----------+
|  1   |   combo1     |  2 person |
+------+--------------+-----------+
|  2   |   combo2     |  2 person |
+------+--------------+-----------+
|  4   |   combo3     |  2 person |
+------+--------------+-----------+

combo_meal_relation

+------+--------------+-----------+
|  id  | combo_meal_id|  meal_id  |
+------+--------------+-----------+
|  1   |      1       |      1    |
+------+--------------+-----------+
|  2   |      1       |      2    |
+------+--------------+-----------+
|  3   |      1       |      3    |
+------+--------------+-----------+
|  4   |      2       |      4    |
+------+--------------+-----------+
|  5   |      2       |      2    |
+------+--------------+-----------+
|  6   |      2       |      7    |
+------+--------------+-----------+

当您在表格内搜索时,它会产生更快的结果。

搜索查询:

SELECT  m.*
FROM    combo_meal cm
JOIN    meal m
ON      m.id = cm.meal_id
WHERE   cm.combo_id = 1

希望您明白:)