Поскольку у вас есть два разных запроса, вам, вероятно, понадобятся две разные таблицы, чтобы они работали хорошо. Это не является необычным для моделей данных Cassandra. Имейте в виду, что для обоих из них определение PRIMARY KEY в Cassandra в значительной степени зависит от количества элементов и ожидаемых шаблонов запросов. Поскольку вы предоставили только последнее, вам может потребоваться внести коррективы на основе количества элементов id1
, id2
и type
.
select * from table_name where id1 = X and id2 = Y and type = Z;
Так что здесь яЯ собираюсь сделать обоснованное предположение, что id1
и id2
почти уникальны (высокая мощность), как обычно имеют идентификаторы. Я не знаю, сколько типов доступно в вашем приложении, но до тех пор, пока их не более 10 000, это должно работать:
CREATE TABLE table_name_by_ids (
id1 TEXT,
id2 TEXT,
type TEXT,
time TIMESTAMP,
data TEXT,
version TEXT,
PRIMARY KEY ((id1,id2),type));
Это позволит разделить ваши разделы на общий хэш * 1014. * и id2
, сортировка строк внутри по type
(по умолчанию).
select * from table_name where id1= X and type = Z and time > A and time < B;
Аналогично, таблица для поддержки этого запроса будет выглядеть следующим образом:
CREATE TABLE table_name_by_id1_time (
id1 TEXT,
id2 TEXT,
type TEXT,
time TIMESTAMP,
data TEXT,
version TEXT,
PRIMARY KEY ((id1),type,time))
WITH CLUSTERING ORDER BY (type ASC, time DESC);
Опять же, это должно работать до тех пор, пока у вас не будет более нескольких тысяч комбинаций типа / времени.
Одна заключительная корректировка, которую я хотел бы сделать, заключалась бы в оценке того, сколькокомбинации типа / времени, которые вы ожидаете получить в течение срока службы приложения. Если эти данные со временем будут расти, то приведенное выше приведет к тому, что разделы вырастут до не поддерживаемой точки. Чтобы этого не происходило, я бы также рекомендовал добавить временное «ведро».
version TEXT,
month_bucket TEXT,
PRIMARY KEY ((id1,month_bucket),type,time))
WITH CLUSTERING ORDER BY (type ASC, time DESC);
Аналогично для этого необходимо будет скорректировать запрос:
select * from table_name_by_id1_time
where id1= 'X' and type = 'Z'
and month_bucket='201910'
and time > '2019-10-07 00:00:00' and time < '2019-10-07 16:22:12';
Надеюсь, это поможет.
Как я могу гарантировать атомарность этих двух вставок?
Проще говоря, вы можете запустить два INSERT
вместе в атомной партии.
BEGIN BATCH
INSERT INTO table_name_by_ids (
id1, id2, type, time, data, version
) VALUES (
'X', 'Y', 'Z', '2019-10-07 12:00:01','stuff','1.0'
) ;
INSERT INTO table_name_by_id1_time (
id1, id2, type, time, data, version, month_bucket
) VALUES (
'X', 'Y', 'Z', '2019-10-07 12:00:01','stuff','1.0','201910'
);
APPLY BATCH;
Для получения дополнительной информации ознакомьтесь с документами DataStax по атомарным партиям: https://docs.datastax.com/en/dse/6.7/cql/cql/cql_using/useBatchGoodExample.html