Как смоделировать что-то обновляемое, например, «статус» объекта в Cassandra CQL3, и иметь возможность запрашивать этот статус?

Это немного надуманный пример, иллюстрирующий мой вопрос, но допустим, у меня есть объект Car, который содержит объекты Lightbulb. В автомобиле есть несколько лампочек, каждая из которых может быть «включена», «выключена» или «сломана».

Каждый тип лампочки имеет уникальный идентификатор. (левая фара = 100, правая фара = 101... что-то в этом роде)

Состояние лампочки необходимо постоянно обновлять.

Что я хотел бы сделать, так это запросить конкретный автомобиль для набора лампочек с определенным статусом.

что-то вроде: "дайте мне все лампочки со статусом "включено" для автомобиля "шеви" модель "нова" vin "xyz-123"".

create table lightbulbstatus (
   bulbid uuid,
   carmake text,
   carmodel text,
   carvin uuid,
   lastupdate timestamp,
   status int,  
                   /* row key *                /* col keys  */
   PRIMARY KEY( (carmake, carmodel, carvin), ?   ?    ?    ?)
);

Я считаю, что в ключе строки должна быть координата автомобиля, но помимо этого я немного потерялся. Я предполагаю, что каждый раз, когда происходит изменение состояния лампочки, мы добавляем столбец. Но я не уверен, какие ключи должны быть в столбце, чтобы запрос работал.

Я думаю, что в стране RDBMS вы могли бы выполнить запрос с подвыборкой или вложенным запросом, чтобы найти лампочки со статусом = on.

select * from lightbulbstatus where status = 1 and lastupdate > (select lastupdate from lightbulbstatus where status != 1);

Не знаю, как бы вы сделали это в CQL3. Очевидно, что подзапросы не допускаются.


person marathon    schedule 04.11.2014    source источник
comment
Зачем добавлять строку для каждого изменения статуса? Нужно ли отслеживать изменения или достаточно текущего статуса? Конечно, в вашем надуманном примере нет особого смысла отслеживать, как часто и когда включается или выключается указатель поворота. В вашем реальном случае использования это может быть необходимо.   -  person Marius Waldal    schedule 05.11.2014
comment
Мое намерение состояло в том, чтобы добавить новый столбец с идентификатором лампы/статусом/временем для каждого изменения статуса. мой ключ раздела должен быть идентификатором автомобиля.   -  person marathon    schedule 05.11.2014
comment
Да, это то, что я предположил. Мне просто интересно, было ли это необходимо в вашем реальном случае использования, или, может быть, было бы лучше иметь объект-лампочку со статусом вкл/выкл/сломан, который можно было бы изменить. Это если вам нужен только текущий статус, а не история статусов.   -  person Marius Waldal    schedule 05.11.2014
comment
@Handsomeguy Ну, мне не нужна история статусов. Я немного новичок в nosql, и у меня сложилось впечатление, что лучше написать новую запись, чем обновлять некоторые существующие данные. Хотя, возможно, не в этом примере.   -  person marathon    schedule 06.11.2014
comment
Что ж, cassandra оптимизирована для записи, а это значит, что писать быстрее, чем читать или обновлять. Однако я бы не рекомендовал отправлять данные, в которых нет необходимости, только потому, что они быстрее. Если вам не нужно обновлять статус ОЧЕНЬ часто, чтение и запись не имеют значения. И это также будет означать, что у вас есть НАГРУЗКИ устаревших данных в вашем хранилище. Я попробую предложить решение для вас.   -  person Marius Waldal    schedule 06.11.2014


Ответы (1)


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

PRIMARY KEY( (carmake, carmodel, carvin), bulbid)

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

CREATE INDEX lightbulb_by_status ON lightbulbstatus (status);

SELECT * FROM lightbulbstatus 
  WHERE status = 1 
    AND carmake = 'chevy' 
    AND carmodel = 'nova'
    AND carvin = cfe638e9-5cd9-43c2-b5f4-4cc9a0e6b0ff;

Хотя кардинальность статуса невелика, ваш запрос включает ключ секции и очень эффективен.
Если число строк для фильтрации очень мало (например, количество лампочек в автомобиле), вы можете рассмотреть возможность фильтрации лампочек по статусу в приложении (и пропустить вторичный индекс).

Если вам нужно обработать случай, когда устаревшее обновление статуса лампочки может переопределить более свежее обновление статуса (как предлагает ваш запрос РСУБД), рассмотрите возможность использования легкие транзакции:

UPDATE lightbulbstatus set status = 0, lastupdate = '2014-11-08 23:50:30+0019'
  WHERE carmake = 'chevy' 
    AND carmodel = 'nova' 
    AND carvin = cfe638e9-5cd9-43c2-b5f4-4cc9a0e6b0ff 
    AND bulbid = 9124f318-8253-4d94-b865-3be07899c8ff 
  IF status = 1 AND lastupdate < '2014-11-08 23:50:30+0019';

Надеюсь, поможет.

person Ohad Bruker    schedule 08.11.2014