我有100M用户和10M项目。数据库(mysql)存储用户单击的项目。平均而言,用户点击了15个项目。每个用户/项目都有一个唯一的ID,即长号码。
这是我的问题:
- 给出一些项目,即: a,b,c 。和他们之间的逻辑运算符,即:
a AND b NOT c
(表示:用户点击 a AND b 但未点击 c 项目
- 返回满意的用户数量。
响应时间必须在几秒钟内。
结果不需要100%准确,但具有合理的误差。
我尝试了什么:
使用Java HashMap将整个数据存储在内存中,并使用一些Java 8流API进行计数。它真的很快但需要与数据库同步。它使用了大量的内存。
那么,有没有任何内存数据库可以做到这一点上面的计数?我知道Redis是一个内存数据库,但不知道如何为这个计数工作存储我的数据。
并且,结果不需要100%准确,是否存在快速且不使用大量内存的数据结构?
修改:
正如评论建议我应该使用mysql数据库进行查询。
这是我的“小”表,有~178M行。一个非常简单的查询,计算点击项目1的用户数量需要7.85秒。它不是太慢。但是(对我来说)构建一个非常复杂的逻辑查询似乎并不容易,例如
1 AND (2 OR (3 OR 4))
mysql> DESCRIBE user_item; +---------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+------------+------+-----+---------+-------+ | user_id | bigint(20) | NO | PRI | NULL | | | item_id | int(11) | NO | PRI | NULL | | +---------+------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> select TABLE_ROWS from information_schema.TABLES where table_name = 'user_item'; +------------+ | TABLE_ROWS | +------------+ | 178611337 | +------------+ 1 row in set (0.00 sec) mysql> SELECT COUNT(1) FROM `user_item` WHERE `item_id`=1; +----------+ | COUNT(1) | +----------+ | 33923046 | +----------+ 1 row in set (7.85 sec)