Самый простой способ добиться этого - создать таблицу likes_by_post:
CREATE TABLE likes_by_post (
post_id text,
user_id text,
PRIMARY KEY (post_id, user_id)
);
Эта таблица позволит вам получить всех пользователей, которым понравился какой-то пост:
SELECT * FROM likes_by_post WHERE post_id='post_1';
проверить пользователя какдля некоторого поста:
SELECT * FROM likes_by_post WHERE post_id='post_1' AND user_id='user_1';
Но у этого подхода есть недостаток - если вы ожидаете большого количества лайков пользователей на пост (миллионы или миллиарды), эта таблица будет иметь слишком большие разделы, это приведет к низкой производительности инеспособность хранить так много лайков за пост.Кассандра имеет ограничение в 2 миллиарда строк на ключ раздела.
В этом случае вы можете распространять информацию о лайках одного сообщения на несколько разделов, используя составной первичный ключ (этот подход обычно называется согласованным хешированием):
CREATE TABLE likes_buckets_by_post (
post_id text,
bucket_id int,
user_id text,
PRIMARY KEY (( post_id, bucket_id ), user_id)
);
Где bucket_id
- это искусственное поле, которое отвечает за генерацию разных ключей разделов для разных пользователей для одного и того же поста.
bucked_id
должно быть своего рода хэшем на основе user_id
поле.Согласованное хеширование обеспечивает возможность генерирования некоторого числа в указанном диапазоне на основе указанного идентификатора пользователя.(Например, java-библиотека Guava предоставляет согласованную функцию хеширования )
Перед тем, как вставить данные в таблицу likes_buckets_by_post
, вам необходимо вычислить bucket_id
с использованием согласованной функции хеширования и указанного количества сегментов.:
var bucket = consistentHash(user_id, N)
Где N - общее количество сегментов, это число будет зависеть от ваших условий: сколько у вас узлов Cassandra, сколько лайков вы ожидаете, чем больше это число, тем больше разделовбудет использоваться для хранения.
Обратите внимание, что если вам нужно запросить все лайки для поста, вам нужно будет выполнить N запросов, но для вашего случая потребуется только один запрос, чтобы проверить одного пользователя, например, дляодиночная запись.
INSERT INTO likes_buckets_by_post (post_id, bucket_id, user_id) VALUES ('post_1', bucket, 'user_1' );
Также перед тем, как выбрать данные, вам нужно вычислить хэш с теми же параметрами, что и для вставки:
var bucket = consistentHash(user_id, N)
А затем вы можете проверить пользователя, например, для сообщения:
SELECT * FROM likes_buckets_by_post WHERE post_id='post_1' AND bucket_id=bucket AND user_id='user_1';