我有一张桌子
CREATE TABLE user_songs (user_id int, song text, listen_date date, PRIMARY KEY (user_id, song))
,并且需要获得用户唯一听过的歌曲。但是某些用户可以生成big partitions(更多100.000或100 MB)。
如果将listen_date添加到分区键(大分区),我将无法获得独特的歌曲,因此需要在应用程序端使用其他重复数据删除功能。而且它使分页变得复杂。
也许有更有效的解决方案?
答案 0 :(得分:1)
我会像这样建模您的数据;
user_id(分区键)| song_id(集群键)| listen_date
user_id(分区密钥)| song_id(clustering_key)
无论何时将记录插入到listened_songs_by_user表中,都应在插入之后进行
如果要检索独特的歌曲,请按user_id阅读 songs_by_user 表
数据的非规范化和重复是Cassandra的生活。不要害怕。 https://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling
答案 1 :(得分:1)
您可以通过对部分分区键使用一致性哈希将大分区划分为几个分区:
CREATE TABLE songs_listenings (
user_id int,
song_hash int,
song text,
listen_date date,
PRIMARY KEY (( user_id, song_hash ), song)
);
song_hash
-是基于歌曲文本生成的哈希。要生成此哈希,您需要在应用程序中启用一致性哈希函数,该函数将能够为指定的输入参数(歌曲文本)生成指定范围内的某个数字(您希望单个用户拥有的最大分区数) 。 (例如Guava Java库提供了consistent hashing function)
对于多次收听同一首歌曲的情况,一致的哈希将返回相同的数字,因此它将是相同的分区键,并且每位用户每首相同的歌曲只有一个记录。
但是由于每个用户有多个分区,您将必须执行多个请求才能获取用户的所有数据(遍历所有可能的哈希值)。