我有两个表用于存储产品和其他用于存储订单列表.
CREATE TABLE ProductsList(ProductId INT NOT NULL PRIMARY KEY,
ProductName VARCHAR(50))
INSERT INTO ProductsList(ProductId, ProductName)
VALUES(1,'Product A'),
(2,'Product B'),
(3,'Product C'),
(4,'Product D'),
(5,'Product E'),
(6,'Product F'),
(7,'Product G'),
(8,'Product H'),
(9,'Product I'),
(10,'Product J');
CREATE TABLE OrderList(OrderId INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
EmailId VARCHAR(50),
CSVProductIds VARCHAR(50))
INSERT INTO OrderList(EmailId, CSVProductIds)
VALUES('PersonA@domain.com', '2,4,1,5,7'),
('PersonB@domain.com', '5,7,4'),
('PersonC@domain.com', '2'),
('PersonD@domain.com', '8,9'),
('PersonE@domain.com', '4,5,9'),
('PersonF@domain.com', '1,2,3'),
('PersonG@domain.com', '9,10'),
('PersonH@domain.com', '1,5');
产量
ItemName NoOfOrders
Product A 3
Product B 3
Product C 1
Product D 3
Product E 4
Product F 0
Product G 2
Product H 1
Product I 3
Product J 1
Run Code Online (Sandbox Code Playgroud)
订单列表将ItemsId存储为每个下订单的客户的逗号分隔值.就像我在我的dB表中有超过40k的记录
现在,我被分配了一个创建报告的任务,我应该在其中显示项目和下面显示的人员订购项目
我在我的PHP中使用了以下查询,将Orders One By One和存储在数组中.
SELECT COUNT(PL.EmailId)
FROM OrderList PL
WHERE CSVProductIds LIKE '2' OR
CSVProductIds LIKE '%,2,%' OR
CSVProductIds LIKE '%,2' OR
CSVProductIds LIKE '2,%';
Run Code Online (Sandbox Code Playgroud)
1.使用单一查询可以获得相同的输出
2.当表中有更多的记录即40k行时,在mysql查询中使用like会减慢dB的速度
是的,使用带有前导通配符的LIKE强制它执行表扫描,即读取表中的每一行.桌子越大,它就越慢.例如,它可能慢几百或几千倍!
这是将逗号分隔列表存储在VARCHAR中并期望访问单个元素的几个原因之一,这对于关系数据库来说是一个糟糕的设计.
另请参阅我的答案是否在数据库列中存储逗号分隔列表真的那么糟糕?
你应该做的是定义你的OrderList表来存储一对电子邮件和productid.如果订单包含多个产品,则必须存储多行.但这意味着您可以随时找到您正在寻找的单一产品,计算购买该产品的人数等等,并且您可以通过定义索引来快速完成这些查询.
反对在单列中存储列表的规则称为第一范式.