2016-03-23 4 views
2

У меня есть таблицаКак добавить элемент в коллекцию с тем же TTL другого столбца в Кассандре

CREATE TABLE myTable (
    id bigint, 
    other_id text, 
    my_set SET<bigint>, 
    my_date timestamp, 
    PRIMARY KEY (id, other_id) 
); 

Я хочу иметь общий TTL внутри всех столбцов, поэтому по истечению TTL, строка исчезает.

мне удается вставить новые строки с:

INSERT INTO myTable (id, other_id, my_date, my_set) 
VALUES (1,'foo','2014-10-20 12:05:08-0300', {22}) 
USING TTL 20; 

Я также могу обновить свой набор добавление новых элементов с:

UPDATE myTable USING TTL 20 SET my_set=my_set + {99} 
          WHERE id=1 AND other_id='foo'; 

, но моя проблема в том, что этот новый элемент имеет новый TTL, поэтому через некоторое время число 22 исчезает и 99 все еще присутствует.

Как добавить новый элемент в мой набор с тем же TTL других элементов набора?

Решение, которое я имею в виду, чтобы сделать два запроса:

  1. Ask my_date колонку его TTL
  2. При том, что TTL сделать UPDATE добавления нового элемента в my_set

Есть ли лучшее решение?

ответ

1

Я мало знаю о том, чего вы пытаетесь достичь. Но по моему опыту TTL внутри больших сборников - плохая новость (или имеющая более пары десятков элементов в коллекции).

Так или иначе, поскольку под крышками комплекты реализованы как дискретные столбцы в форме (name = setName: valueOfItem, value =) (see this article for more), вам придется взломать что-то сверху. Мое предложение было бы инкапсулировать коллекцию в колонке кластерной следующим образом:

CREATE TABLE my_table (
    id bigint, 
    other_id text, 
    collection_ttl timeuuid, 
    my_set SET<bigint>, 
    my_date timestamp, 
    PRIMARY KEY (id, other_id, collection_ttl) 
); 

Где collection_ttl может быть просто время вставки, и, по существу, предназначен для отслеживания TTL содержавшихся коллекции.

Или вы могли бы разворачивать свой сет в колонку кластером и достичь по существу то же самое, выполнив:

CREATE TABLE my_table_no_set (
    id bigint, 
    other_id text, 
    my_set_key bigint, 
    my_set_value text, 
    my_date timestamp, 
    PRIMARY KEY (id, other_id, my_set_value) 
); 

Это было бы гораздо удобнее Кассандре, если у вас есть достаточно большая коллекция, и вы можете просто сделать TTL на order_id или что-то подобное.

+0

Hi @fromanator, спасибо за ответ !. Я собираюсь работать с наборами 100-150 элементов. Думаю, я поеду с первым предложенным вариантом. Считаете ли вы, что 100-150 элементов в наборе повлияют на производительность Кассандры? –

+0

Трудно сказать, у меня есть только опыт, видя плохую работу с коллекциями, насчитывающими около 1000 предметов. В общем, коллекции в Кассандре предназначены только для «небольшого» количества предметов. Casssandra читает Коллекции полностью (даже если вы просто хотите, чтобы из него был один элемент). Если ваш случай использования включает чтение 1 или диапазонов данных в вашей коллекции, вам обычно лучше «разворачивать» вашу коллекцию с помощью столбца кластеризации, как в моем втором примере. – fromanator

+0

Большое спасибо @fromanator !! , Я должен прочитать все значения набора, поэтому я думаю, что в моем конкретном случае это одно и то же. Я буду учитывать ваш комментарий, если мне придется читать только некоторые значения. –

0

Вы можете использовать функцию TTL() в SELECT

SELECT TTL(my_set) FROM myTable; 

Затем использовать это значение ... но я не думаю, что будет работать на то, что вы пытаетесь сделать.

Вместо этого я бы добавил дату создания строки. Более или менее, что-то вроде этого:

CREATE TABLE myTable (..., created_on timestamp); 
INSERT INTO myTable (..., created_on) VALUES (..., toTimestamp(now())); 
... 
SELECT created_on FROM myTable WHERE ... 
INSERT INTO myTable ... USING TTL now - created_on ... 

(вместо toTimestamp(now()) вы, возможно, придется использовать dateOf(now()) в зависимости от версии CQL вы используете; see documentation Вы также можете использовать собственное значение временной метки, конечно.).

Если now - created_on меньше 1, тогда вы не должны обрабатывать этот INSERT. (на самом деле, я где-то читал, что минимальное значение TTL должно быть, по крайней мере, 3 секунды, но даже 3 действительно мало для базы данных TTL ...)

Существует также функция writetime(). Но я не слишком уверен, что это сработает для вас. Вы, конечно, можете дать ему попробовать:

SELECT writetime(id) FROM myTable WHERE ... 

Не исключено, что writetime() изменения на UPDATE, но я не знаю, изменяет ли она на каждый столбец основе или на строку и не рекомендуется использовать такая системная информация для ваших собственных данных (How to retrieve the timestamp from cassandra?).