我正在构建一个功能来估算我的广告服务平台的库存。我尝试估算其基数的字段如下:
字段:基数
位置:10000(类加罗尔、金奈等..)
n/w 速度:6(w、4G、3G、2G、G、NA)
价格范围:10(1、2、3、4、5、6、7、8、9、10)
用户:包含属于上述任何组合的用户数。
例。 {'location':'bengaluru', 'n/w':'4G', priceRange:8, users: 1000}
表示 1000 名用户来自类加罗尔,拥有 4G 和 priceRange = 8
所以总组合可以是 10000 * 6 * 10 = 600000 并且将来可以添加更多字段到 29 左右(目前是 3 个位置,n/w,价格范围)并且总组合可以达到 1000 万的数量级。现在我想估计有多少用户属于
现在我需要的查询如下: 1) 找到所有来自 location:bengaluru , n/w:3G, priceRange: 6 的用户
2) 找到来自类加罗尔的所有用户
3) 查找所有属于 n/w: 3G 和 priceRange: 8 的用户
解决这个问题的最佳方法是什么?
哪个数据库最适合这个需求。我需要建什么索引。复合索引有帮助吗?如果是那么如何?感谢您的帮助。
最佳答案
这是我的最终答案:
Create table Attribute(
ID int,
Name varchar(50));
Create table AttributeValue(
ID int,
AttributeID int,
Value varchar(50));
Create table userAttributeValue(
userID int,
AttributeID varchar(20),
AttributeValue varchar(50));
Create table User(
ID int);
Insert into user (ID) values (1),(2),(3),(4),(5);
Insert into Attribute (ID,Name) Values (1,'Location'),(2,'nwSpeed'),(3,'PriceRange');
Insert into AttributeValue values
(1,1,'bengaluru'),(2,1,'chennai'),
(3,2, 'w'), (4, 2,'4G'), (5,2,'3G'), (6,2,'2G'), (7,2,'G'), (8,2,'NA'),
(9,3,'1'), (10,3,'2'), (11,3,'3'), (12,3,'4'), (13,3,'5'), (14,3,'6'), (15,3,'7'), (16,3,'8'), (17,3,'9'), (18,3,'10');
Insert into UserAttributeValue (userID, AttributeID, AttributeValue) values
(1,1,1),
(1,2,5),
(1,3,9),
(2,1,1),
(2,2,4),
(3,2,6),
(2,3,13),
(4,1,1),
(4,2,4),
(4,3,13),
(5,1,1),
(5,2,5),
(5,3,13);
Select USERID
from UserAttributeValue
where (AttributeID,AttributeValue) in ((1,1),(2,4))
GROUP BY USERID
having count(distinct concat(AttributeID,AttributeValue))=2
现在,如果您需要一个计数,将 userID 包装在计数中,然后除以传入的属性,因为每个用户的每个属性都有 1 条记录,要获得“用户数”,您需要除以属性数。
- 如果 UI 设计正确,这允许 N 个属性和每个用户的 AttributeValues 增长,而无需更改 UI 或数据库。
- 通过将每个数据点视为一个属性并将它们存储在一个地方,我们可以加强数据库的完整性。
- Attribute 和 AttributeValue 表成为 UserAttributevalue 的查找表,因此您可以将 ID 转换回属性名称和值。
- 这也意味着我们只有 4 个表 user、attribute、attributeValue 和 UserAttributeValue。
- 从技术上讲,您不必将 attributeID 存储在 userAttributeValue 上,但出于以后加入/报告的性能原因,我认为您会发现它很有用。
- 您需要为表添加适当的主键、外键和索引。它们应该是相当 self 解释的。在 UserAttributeValue 上,我会有几个复合索引,每个索引都有不同的唯一键顺序。仅取决于您将要进行的报告/分析的类型,但在需要进行性能调整时添加键是很常见的。
假设:
- 您可以接受在所有情况下所有数据值都是 varchar 数据。
- 如果需要,您可以在属性表上添加数据类型、精度和比例,并允许 UI 根据需要转换属性值。但由于它们都在数据库中的同一字段中,因此它们都必须是相同的数据类型。并且具有相同的精度/比例。
- 可能需要使用数据透视表来显示数据,并且您知道如何处理这些数据(并且引擎支持它们!)
不得不说我喜欢金属运动;但仍然会感谢其他人对 SO 的反馈。我在我开发的 1 个系统中使用了这种方法,并且在我支持的两个系统中使用了这种方法。存在一些挑战,但它确实遵循第三范式数据库设计(userAttributevalue 中的复制属性 ID 除外,但这是为了提高报告/过滤的性能。
关于database - 使用复合索引通过查询参数的多个组合进行查询的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43504604/