Дизайн хранилища таблиц для запросов со значением в диапазоне

Я ищу использование хранилища таблиц, такого как Azure, Google или Apache HBase, для хранения сущностей / строк, но я не смог найти в Интернете никакой справки по моему шаблону использования. Это выглядит так:

  • У объекта есть идентификатор или ключ, например UserId.
  • Значение даты, например "StartedUsingProduct".
  • Значение даты, например StoppedUsingProduct.

Запросы в основном будут иметь тип «На дату T найти всех пользователей, которые использовали продукт». Обратите внимание, что один и тот же UserId будет иметь много (тысячи) пар старт / стоп.

В случае с Azure - PartitionKey будет UserID - RowKey «StartedUsingProduct», но тогда я не могу найти достойный способ запроса без полного сканирования раздела.

В случае Google, следуя их рекомендации, ключ - будет иметь вид «UserID_StartUsingProduct», и я получаю ту же проблему, когда мне нужно получить значительное количество строк, а затем отфильтровать с помощью второго свойства.

Есть ли у кого-нибудь представление о том, как атаковать этот конкретный шаблон использования?


person Francois    schedule 27.05.2017    source источник
comment
Это довольно широко - нет единого правильного расположения стола. Я предлагаю 1) сделать это более конкретным - показать запросы, которые вы выполняете, и проблемы, с которыми вы сталкиваетесь, и 2) разделить свои вопросы. Прямо сейчас вы отметили двух совершенно разных облачных провайдеров / сервисов хранения таблиц.   -  person David Makogon    schedule 27.05.2017
comment
Я не согласен с вами. Хранилище таблиц Azure и большая таблица Google - это, по сути, одно и то же, с той небольшой разницей, что Azure разделил ключ строки на две части, а Google рекомендует объединить эти две части в один ключ. Они оба являются NoSql, хранилищами ключей и значений, и запросы оптимизируются при прямом нажатии клавиши или диапазона клавиш. У них обоих может быть любое количество столбцов, и эти столбцы могут изменяться от одной строки к другой.   -  person Francois    schedule 29.05.2017
comment
Что касается 1), покажите запросы, они уже есть, жирным шрифтом. На данный момент это единственный вопрос, вызывающий беспокойство.   -  person Francois    schedule 29.05.2017
comment
Просто чтобы уточнить: вы получаете обновление только тогда, когда пользователь начинает или прекращает использовать продукт? Вы не получаете ежедневный пинг о том, что пользователь все еще использует продукт? Так, например, если пользователь начинает использовать продукт 1 января и прекращает работу 31 декабря, но 5 июля, если вы зададите вопрос, он должен найти маркер начала 1 января, но не существующий маркер остановки, и следовательно, сделать вывод, что этот пользователь все еще использует продукт?   -  person Misha Brukman    schedule 31.05.2017


Ответы (1)


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

  1. ID пользователя
  2. Действие - указывает на запуск или остановку
  3. DateTime

Поэтому, когда пользователь начинает использовать продукт, вы вставляете объект для этого пользователя с Action = start и DateTime = current date/time. Аналогичным образом, когда пользователь прекращает использовать продукт, вы вставляете объект для этого пользователя с Action = stop и DateTime = current date/time.

Шаблон, который вам придется использовать, - хранить несколько записей для одного действия.

Это необходимо, потому что вы можете либо запрашивать дату (как вы упомянули выше), либо запрашивать пользователя, например. скажите мне, сколько раз этот пользователь начинал / прекращал использовать продукт.

1-я сущность будет иметь PartitionKey = UserId и RowKey = Current Date/Time. Вы можете сохранить текущую дату / время в виде тиков, преобразованных в строку, используя что-то вроде DateTimeValue.Ticks.ToString("d20"). Этот шаблон гарантирует, что вы сможете запрашивать активность пользователя. Вы должны указать запрос как PartitionKey eq UserId, и вы получите все записи для этого пользователя. Если вы хотите сначала получить последние данные о действиях, вы можете использовать обратные галочки в RowKey, используя что-то вроде (DateTime.MaxValue.Ticks - DateTimeValue.Ticks).ToString("d20"). Это обеспечит добавление последних записей в начале, а не в конце.

2-я сущность будет иметь PartitionKey = DateTimeValue.Date и RowKey = UserId. Если вы думаете, что пользователь начнет / прекратит использование программного обеспечения более одного раза в день, вы также захотите добавить значение даты и времени в RowKey, используя что-то вроде RowKey = UserId|DateTimeValue. Это гарантирует, что несколько действий запуска / остановки для пользователя в день могут быть зарегистрированы без перезаписи предыдущей активности для этого пользователя в этот день. Теперь вы можете выполнить запрос по PartitionKey, и он точно скажет вам, что все пользователи начали / прекратили использовать продукт.

person Gaurav Mantri    schedule 27.05.2017