Понимание внутреннего хранения данных с помощью cassandra

у меня есть эта таблица

create table comment_by_post
(
    postId uuid,
    userId uuid,
    cmntId timeuuid,
    cmntTxt text,   
    cmntBy text,
    time bigint, 
    primary key ((postId, userId),cmntId)
)

вот внутренние данные в этой таблице

RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b:4978f728-0f96-12e5-a6c0-1697f92e537a
=> (name=d3f02a30-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270721107000)
=> (name=d3f02a30-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e743434, timestamp=1434270721107000)
-------------------
RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b:4978f728-0f96-12e5-a6c0-1697f92eec7a
=> (name=465fee30-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270483603000)
=> (name=465fee30-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7432, timestamp=1434270483603000)
=> (name=4ba89f40-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270492468000)
=> (name=4ba89f40-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7431, timestamp=1434270492468000)
=> (name=504a61f0-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270500239000)
=> (name=504a61f0-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7433, timestamp=1434270500239000)
-------------------
RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b:4978f728-0f96-12e5-a6c0-1697f92e237a
=> (name=cd1e8f30-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270709667000)
=> (name=cd1e8f30-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7433, timestamp=1434270709667000)

Если я сделаю primary key (postId, userId,cmntId), то это будет так:

RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b
=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:971da150-1260-11e5-879b-e700f669bcfc:, value=, timestamp=1434264176613000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:971da150-1260-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7431, timestamp=1434264176613000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:a0d4a900-1260-11e5-879b-e700f669bcfc:, value=, timestamp=1434264192912000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:a0d4a900-1260-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7432, timestamp=1434264192912000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:a5d94c30-1260-11e5-879b-e700f669bcfc:, value=, timestamp=1434264201331000)

Почему это так и в чем польза обоих?


person Manish Kumar    schedule 14.06.2015    source источник
comment
Есть ли конкретный вопрос, на который вы хотите получить ответ, или вам интересно, как конструкция первичного ключа взаимодействует с базовым хранилищем? Для получения дополнительной информации ознакомьтесь с этой записью в блоге, в которой показано, как CQL3 сопоставляется с внутренней структурой данных Cassandra. opensourceconnections.com /блог/2013/07/24/   -  person Christopher Bradford    schedule 14.06.2015
comment
@ChristopherBradford Это отличная статья. Джон Берриман очень хорошо все это объясняет; особенно то, как ключи кластеризации работают под капотом.   -  person Aaron    schedule 14.06.2015
comment
Я ответил на аналогичный вопрос здесь: stackoverflow.com/questions/30114854/ cassandra-storage-internal/   -  person Aaron    schedule 14.06.2015


Ответы (2)


Кристофер уже объяснил, как ключи секционирования объединяются вместе для создания ключа строки для хранения, поэтому я не буду повторять это (без каламбура). Но я объясню преимущества и недостатки этих двух подходов.

PRIMARY KEY (postId, userId,cmntId)

С этим ПЕРВИЧНЫМ КЛЮЧОМ ваши данные разделены по postId и сгруппированы по userId и cmntId. Это означает, что все комментарии к сообщению будут храниться вместе на диске по postId, а затем сортироваться по userId и cmntId (соответственно).

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

Недостатком является то, что у вас больше шансов на неограниченный рост строк, чем у другого решения. Если общее количество столбцов на postId когда-либо превысит 2 миллиарда, вы максимально увеличите количество данных, которые вы можете хранить на postId. Но вероятность того, что вы сохраните столько данных комментариев к посту, невелика, так что все в порядке.

PRIMARY KEY ((postId, userId),cmntId)

Это решение помогает исключить возможность неограниченного роста строк, сохраняя данные комментариев вместе с помощью конкатенированного ключа строки postId и userId (отсортированного по cmntId. Это преимущество по сравнению с другим вашим решением.

Недостатком является потеря гибкости запроса, так как теперь вам нужно предоставлять postId и userId с каждым запросом. Это определение PRIMARY KEY просто не будет поддерживать запросы комментариев только с postId, так как Cassandra CQL требует от вас предоставления всего ключа раздела для запроса.

person Aaron    schedule 14.06.2015
comment
Возможно, стоит отметить, что с формой PRIMARY KEY ((postId, userId),cmntId) комментарии к сообщению будут размещаться на нескольких узлах в кластере, а не только на одном, как указано с менее конкретным ключом раздела PRIMARY KEY(postId, usedId,cmndId). - person Christopher Bradford; 14.06.2015
comment
что я понял, что в случае PRIMARY KEY (postId, userId,cmntId) количество столбцов может быстро расти, но запрос будет легким. В случае PRIMARY KEY ((postId, userId),cmntId) количество столбцов будет под контролем, но с точки зрения запроса это будет не так просто. Правильно? - person Manish Kumar; 15.06.2015

Первый первичный ключ использует postId и userId в качестве ключей секции с cmntId в качестве столбца кластеризации. Обратите внимание, что значение, используемое для RowKey, содержит значения из postId и userId, разделенные :. Затем значение для столбца кластеризации используется в имени каждой ячейки в строке.

Во втором примере в первичном ключе отсутствуют скобки вокруг ключа раздела. Они могут быть опущены, но часто предпочтительнее, чтобы они присутствовали, поскольку мы можем явно определить, какие части первичного ключа предназначены для разделения и кластеризации. Когда дополнительные скобки не включены, только первый столбец используется в качестве ключа раздела (отображается в значении RowKey из cassandra-cli). Предполагается, что все последующие столбцы являются столбцами кластеризации, в чем мы можем убедиться, взглянув на имена ячеек.

person Christopher Bradford    schedule 14.06.2015
comment
каковы преимущества и недостатки обоих? - person Manish Kumar; 14.06.2015