Итак, я разрабатываю эту модель данных для отслеживания цены продукта.Моделирование данных Кассандры
За продуктом могут следовать многие пользователи, и пользователь может следить за множеством продуктов, так что это отношение много-много. Продукты находятся под постоянным отслеживанием, но новая цена вставляется только в том случае, если она отличается от предыдущей.
Пользователи установили верхний предел цены для своих продуктов, поэтому каждый раз, когда цена меняется, предпочтения проверяются, и пользователи будут уведомлены, если цена упадет ниже их цены.
Так первоначально я думал о следующей модели продукта:
Однако «subscriberEmails» представляет собой сборник список, который будет обрабатывать до 65536 элементов. Но, будучи большим решением для данных, это граница, которую мы не хотим иметь. Таким образом, мы в конечном итоге писать отдельную таблицу для этого:
Так что теперь «usersByProduct» может иметь до 2 млрд столбцов, достаточно справедливо. И пользовательские предпочтения сохраняются в «Карте», которая снова ограничена, но мы считаем, что это хорошее максимальное количество продуктов для пользователя.
Теперь проблема мы сталкиваемся заключается в следующем:
Каждый раз, когда мы хотим обновить цену товара мы должны сделать запрос следующим образом:
INSERT INTO products("Id", date, price) VALUES (7dacedd2-c09b-46c5-8686-00c2a03c71dd, dateof(now()), 24.87); // Example only
Но ВСТАВИТЬ операции DON» t допускают другие условные предложения, чем (ЕСЛИ НЕ СУЩЕСТВУЕТ), и это не то, что мы хотим. Нам нужно обновить цену, только если она отличается от предыдущей, поэтому это вынуждает нас делать два запроса (один для чтения текущего значения, а другой - для его обновления, если это необходимо).
PD. Операции UPDATE имеют условия IF, но это не наш случай, потому что нам нужен INSERT.
UPDATE products SET date = dateof(now()) WHERE "Id" = 7dacedd2-c09b-46c5-8686-00c2a03c71dd IF price != 20.3; // example only
Просто любопытно, но зачем вам нужен «INSERT»? Под капотом «UPDATE» и «INSERT» одинаковы: http://stackoverflow.com/questions/28350630/when-are-rows-overwritten-in-cassandra/28351184#28351184 – Aaron
Потому что, хотя я сделал все операции UPDATES, я все равно должен предоставить временную метку (которая находится в первичном ключе) для вставки определенной цены продукта. При вводе новой цены в заданное время новое время не существует в базе данных, и по этой причине операция обновления всегда будет рассматриваться как вставка (и не будет проверять, совпадает ли последняя вставленная цена). – user1799563
Кроме того, вы не хотите этого делать: 'dateof (now())'. 'DateOf' возвращает метку времени, но' now' возвращает timeuuid, которые имеют разную точность. Это означает, что ваши данные будут иметь временную метку, но на самом деле будут хранить timeuuid, сгенерированный из 'now()', что затрудняет вам запрос по диапазону дат (если это то, что вы планируете делать): http : //stackoverflow.com/questions/26237940/cassandra-cql-select-query-not-returning-records-which-have-timestamp-as-cluster/26239367#26239367 – Aaron