database - 使用复合索引通过查询参数的多个组合进行查询的最佳方法?

标签 database inventory-management nosql

我正在构建一个功能来估算我的广告服务平台的库存。我尝试估算其基数的字段如下:

字段:基数

位置: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 条记录,要获得“用户数”,您需要除以属性数。

  1. 如果 UI 设计正确,这允许 N 个属性和每个用户的 AttributeValues 增长,而无需更改 UI 或数据库。
  2. 通过将每个数据点视为一个属性并将它们存储在一个地方,我们可以加强数据库的完整性。
  3. Attribute 和 AttributeValue 表成为 UserAttributevalue 的查找表,因此您可以将 ID 转换回属性名称和值。
  4. 这也意味着我们只有 4 个表 user、attribute、attributeValue 和 UserAttributeValue。
  5. 从技术上讲,您不必将 attributeID 存储在 userAttributeValue 上,但出于以后加入/报告的性能原因,我认为您会发现它很有用。
  6. 您需要为表添加适当的主键、外键和索引。它们应该是相当 self 解释的。在 UserAttributeValue 上,我会有几个复合索引,每个索引都有不同的唯一键顺序。仅取决于您将要进行的报告/分析的类型,但在需要进行性能调整时添加键是很常见的。

假设:

  1. 您可以接受在所有情况下所有数据值都是 varchar 数据。
  2. 如果需要,您可以在属性表上添加数据类型、精度和比例,并允许 UI 根据需要转换属性值。但由于它们都在数据库中的同一字段中,因此它们都必须是相同的数据类型。并且具有相同的精度/比例。
  3. 可能需要使用数据透视表来显示数据,并且您知道如何处理这些数据(并且引擎支持它们!)

不得不说我喜欢金属运动;但仍然会感谢其他人对 SO 的反馈。我在我开发的 1 个系统中使用了这种方法,并且在我支持的两个系统中使用了这种方法。存在一些挑战,但它确实遵循第三范式数据库设计(userAttributevalue 中的复制属性 ID 除外,但这是为了提高报告/过滤的性能。

关于database - 使用复合索引通过查询参数的多个组合进行查询的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43504604/

相关文章:

mongodb - 如何在一个查询中多次更新而不共享简单查询?

node.js - 用于 node.js(MongoDB?)的分布式数据库的事件记录

mongodb - 有人能告诉我为什么不允许在 MongoDB 副本集中写入辅助数据的详细技术原因吗

database - 购物商店的基础知识及其架构

mysql - 使用关系数据库进行 Map Reduce

payment-gateway - 如何在 BlueSnap API 中管理入场券库存

nosql - 宇宙数据库 : collection & atomic counter

sql - 使用 IN 或子查询到另一个表的 where 查询速度更快吗?

MySQL 选择响应大小 .NET