2017-01-09 15 views
0

Я пытаюсь смоделировать стол в Кассандре, я совершенно новый и наткнулся на одну проблему. У меня есть следующие:Cassandra сортировать не по первичному ключу

CREATE TABLE content_registry (
    service text, 
    file text, 
    type_id tinyint, 
    container text, 
    status_id tinyint, 
    source_location text, 
    expiry_date timestamp, 
    modify_date timestamp, 
    create_date timestamp, 
    to_overwrite boolean, 
    PRIMARY KEY ((service), file, type_id) 
); 

Так как я понимаю:

  • service мой ключ разделов и на основе этого значения хэшей будет сгенерирован и значения будут разделены в кластере
  • file является ключ кластеризации
  • type_id является ключом кластеризации
  • Эти три тела объединяют первичный ключ составной (составной)

То, что я понял, что каждый раз, когда я буду вставлять новые данные, Cassandra будут upsert (либо вставить или обновить, если значение с этим составным первичным ключом существует)

Теперь то, что я изо всех сил заключается в том, что я хочу, чтобы мои данные возвращались отсортированы по create_date в порядке убывания, однако create_date не является частью первичного ключа.

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

Какие существуют другие варианты? Заказать в заявке? Это не кажется очень эффективным.

ответ

0

Если я добавлю create_date в свой первичный ключ, я не смогу обновить данные.

Почему нет? Предположим, что ваш ключ был PRIMAY KEY (service, create_date, file, type_id)? Это позволит вам сортировать по create_dateза каждую услугу, но не по всему миру.

Если вы хотите сделать это глобально (т. Е. Хотите, чтобы все службы и все файлы были отсортированы по дате создания), тогда, вероятно, все сложнее, если вы все еще хотите, чтобы вы могли очертить ваши данные. Один из вариантов - сделать первичный ключ PRIMARY KEY (create_date, service, file, type_id) и использовать один из order preserving partitioners.

Кроме того, немного больше информации здесь: http://www.datastax.com/dev/blog/we-shall-have-order

+0

Возможно, мне следовало бы более четко рассказать о моем вопросе.Каждый раз, когда вставлена ​​новая запись, она будет иметь текущую временную метку в качестве значения. скажем, если я вставляю такие значения, как '('service1', '2017-01-09 19:35:33', 'fileName1', 1)', а затем '('service1', '2017-01-09 19: 35:34 ',' fileName1 ', 1) ', я получаю две записи, потому что это первичные ключи, и они разные, не так ли? То, что я хотел бы, это сохранить только последнюю запись. Я отредактирую. –

+0

Если вы хотите иметь самую последнюю запись, за исключением отметки времени, метка времени не должна быть частью вашего ключа. – questionare

+0

@questionare Я понимаю это, но мне также нужно иметь данные, отсортированные по этой метке времени, поэтому я сказал _Если я добавлю create_date к своему первичному ключу, я не смогу обновить данные_ :). Кажется, что сортировка на уровне приложения - это опция go-to. –

2

То, что я понял, что каждый раз, когда я буду вставлять новые данные, Cassandra будет upsert (либо вставить или обновить, если значение с этим соединением первичный ключ существует)

Совершенно верно.

Теперь то, что я изо всех сил есть, что я хочу, чтобы мои данные Возвращаться сортируются по create_date в порядке убывания, однако create_date не является частью первичного ключа. Если я добавлю create_date в свой первичный ключ, я не смогу обновить данные , потому что create_date означает отметку времени, когда была вставлена ​​запись, поэтому , если я добавляю его в первичный ключ каждый раз, когда есть вставка, я в конечном итоге с несколькими записями.

С этими предложениями вы на самом деле противоречащие друг другу.

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

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

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

+0

Это служба синхронизации контента. Я написал небольшой фрагмент кода базы данных для поддержки своей модели данных без особых сомнений. И теперь я хотел бы переместить это в Cassandra как первый шаг NoSQL в нашей компании. Я пересмотрю требования и попытаюсь настроить их для модели Cassandra. –

1

Ключевым понятием в Кассандре, что вы должны решить, что ваш PRIMARY KEY, это то, что в ваших рядах может быть уникальный и известный в разы запросов. Это очень основное требование, поскольку неудача при распознавании этого приведет к плохой модели.

Из того, что я вижу, вы определили service как ваш ключ PARTITION, поэтому я думаю, что это поле - это то, что «управляет» вашими данными. Это то, что вы должно действительно знать, чтобы выполнить хотя бы один запрос (игнорируя неэффективное сканирование таблицы SELECT * FROM content_registry;). В пределах каждого service у вас в настоящее время упорядочены ваши строки: file, а затем type_id. Я не знаю точного значения последнего поля, но в настоящее время у вас есть две строки, идентифицированные ('service1', 'a.jpg', 1) и ('service1', 'a.jpg', 2). Поэтому, если type_id как-то связано с file, модель немного неверна.

Теперь, если вы хотите получать одни и те же записи для каждого service в другом порядке, что вам действительно нужно сделать, это создать еще одну таблицу, которая будет включать в себя create_date в качестве первого столбца кластеризации, например (service, create_date, file, type_id). Это позволит вам получать записи, упорядоченные по дате создания, и когда две записи создаются в одну и ту же дату, они будут дополнительно упорядочены по file, а затем по type_id.

Второй подход - прикрепить вторичный индекс к полю create_date вашей исходной таблицы. Это позволит запросить дату создания.

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

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

+0

'type_id' - это просто перечисление, которое может быть« Контейнер »,« Содержимое »,« Папка ». Теперь я просто посмотрел на фактические данные, и кажется, что 'Сервис' и' Имя' всегда уникальны, поэтому 'type_id' вообще не является частью PRIMARY KEY. Думаю, мне придется пересмотреть модель данных и попытаться адаптировать ее для Cassandra. –

+0

@EvaldasBuinauskas Что такое поле 'Name'? Вы имеете в виду 'файл'? – xmas79

+0

Да, извините. Я только что скопировал имена из экземпляра SQL Server вместо Cassandra. 'service' и' file' являются правильными именами. Извините за путаницу. –