7

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

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

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

有任何想法吗?

4

5 回答 5

16

如果一个用户可以有多个角色,最好有一个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 在对此答案的评论中声明。要检查用户是否具有角色,需要扫描用户表的每一行,然后必须使用字符串匹配扫描“角色”列 - 无论此操作如何公开,RMDBS 都需要执行字符串操作来解析内容。这些都是非常昂贵的操作,而且根本不是好的数据库设计。

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

于 2013-09-04T05:21:42.450 回答
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

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

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
于 2016-10-25T06:44:20.073 回答
2

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

假设,你必须表。一个是“meal”表,另一个是“combo_meal”表。现在我想你想在一个combo_meal_id中存储多个meal_id而不分离coma [,]。你说它会让你的数据库更标准。

如果我没有从你的问题中得到错误,那么请仔细阅读我在下面的建议。它可能对你有帮助。

首先认为是你的概念是对的。绝对会为您提供更标准的数据库。

为此,您必须再创建一个表 [ 示例表: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

希望你明白:)

于 2016-03-24T05:16:25.923 回答
0

你可以做这样的事情

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

然后找到它使用FIND_IN_SET

于 2013-09-04T05:16:30.590 回答
0

您可能已经知道,在一个单元格中存储多个值违反 1NF 形式。
如果您对此感到满意,那么使用 json 列类型是一种很好的方法,并且有很好的方法来正确查询。

SELECT * FROM table_name 
WHERE JSON_CONTAINS(column_name, '"value 2"', '$')

将返回任何带有 json 数据的条目,例如

[
    "value",
    "value 2",
    "value 3"
]

您正在使用 json,所以请记住,您的查询性能将会下降。

于 2021-12-16T11:54:14.420 回答