我有一个包含2个表的MySQL数据库。第一个表格只包含产品。第二个包含用户。我正在使用PHP来处理信息。
在users表中,我想定义允许用户查看哪些产品。
我原本以为我可以通过在用户表中创建一个列来实现这一点,该列包含逗号分隔值列表,这些值对应于用户允许查看的产品(基本上可供该用户使用的product_id列表。)
由于我决定使用这种方法,我做了一些研究,我发现人们认为它不遵循数据库规范化的规则,并且可以快速创建冗余。
如果有更好的方法,我肯定会感谢任何能指出我正确方向的人的见解。
答案 0 :(得分:4)
创建另一个表格,将用户链接到产品,例如users_to_products
,并设置字段user_id
和product_id
这将允许您查询数据库以查找用户可以看到的产品:
SELECT u.id, u.name, p.id, p.name FROM users AS u
LEFT JOIN users_to_products AS up ON u.id = up.user_id
LEFT JOIN products AS p ON p.id = up.product_id
WHERE u.id = ?
答案 1 :(得分:3)
这不是最好的方式。您应该再创建一个表,其中包含允许用户使用结构查看的产品:
user_id
和product_id
引用存储用户和产品的表格中的ID。
如果您在MySQL中存储逗号分隔列表,您迟早会遇到在此类表中搜索的问题。例如,如果您想找到被允许查看产品2和5的用户,那么就不可能只在MySQL中
答案 2 :(得分:3)
否!!!请勿使用COMMA分离列表
如果你这样做,你会在未来几年内讨厌自己。处理这种关系的正确方法是使用Junction Table
你会有类似的东西:
CREATE TABLE UserProducts
(
UserID INT NOT NOT NULL FOREIGN KEY REFERENCES Users (UserID),
ProductID INT NOT NULL FOREIGN KEY REFERENCES Products (ProductID),
PRIMARY KEY (UserID, ProductID)
);
这允许正确的参照完整性管理,因为连续分隔列表允许输入任何ProductID
,而外键确保输入有效的productID。搜索具有特定产品的用户要容易得多:
SELECT u.UserID
FROM Users AS u
INNER JOIN UserProducts AS up
ON up.UserID = u.UserID
WHERE p.ProdcutID = 3;
相反:
SELECT UserID
FROM Users
WHERE CONCAT(',', ProductList, ',') LIKE '%,3,%';
它还允许您使用指标获取产品名称和查询,即如果您想要允许特定用户使用的产品列表,则需要使用效率非常低的谓词加入产品表:
SELECT p.Name AS Product
FROM Users AS u
INNER JOIN Products AS p
ON CONCAT(',', u.ProductList, ',') LIKE CONCAT('%,', p.ProductID, ',%')
WHERE u.UserID = 1
使用联结表,您只需使用:
SELECT p.Name AS Product
FROM UserProducts AS up
INNER JOIN Products AS p
ON p.ProductID = up.ProductID
WHERE u.UserID = 1;
如果您需要以逗号分隔的列表中的产品ID,则可以使用GROUP_CONCAT轻松完成此操作:
SELECT up.UserID, GROUP_CONCAT(up.ProductID) AS ProductList
FROM UserProducts AS up
GROUP BY up.UserID;
答案 3 :(得分:3)
答案中提出了一些好处,但只是为了说明为什么逗号分隔列表可能是个问题。对逗号分隔列表中的项目进行的任何检查都不能使用索引,这意味着任何常规检查都会很慢。
如果您只是检查一行,则不成问题。例如,您已将搜索范围缩小到特定用户,并希望检查该用户是否可以访问单个产品,但是如果要查找有权访问单个产品的所有用户,则表示您正在强制执行非索引表扫描(即,mysql必须读取每一行并处理该字段)。
MySQL确实支持FIND_IN_SET()函数,它确实可以轻松地搜索逗号分隔字段,如果不是快速的话。但它只能在集合中找到单个值。你不能轻易拿一套并将它与另一套比较。
答案 4 :(得分:0)
您必须创建主要有3个表格,例如user, product and user_products
。
TABLE : user_products
Fields : id, user_id, product_id
其中user_id指的是User Table的ID,product_id指的是Product table的ID。
答案 5 :(得分:0)
你应该制作3张桌子:
用户 制品 User_Products
然后从用户获取UserID,从Products中获取ProductId并将其插入User_Products表,将用户ID与允许的产品ID匹配