Понимание внутреннего хранения данных 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)
Почему это так и в чем польза обоих?
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 требует от вас предоставить полный ключ раздела для запроса.
Первый первичный ключ использует postId
а также userId
в качестве ключей раздела с cmntId
как столбец кластеризации. Обратите внимание на значение, используемое для RowKey
содержит оба значения из postId
а также userId
разделены :
, Затем значение для столбца кластеризации используется в имени каждой ячейки в строке.
Во втором примере у первичного ключа отсутствует скобка вокруг ключа раздела. Они могут быть опущены, но часто предпочтительнее присутствовать, поскольку мы можем явно определить, какие части первичного ключа предназначены для раздела и кластеризации. Если дополнительные скобки не включены, в качестве ключа раздела используется только первый столбец (видимый в RowKey
значение от Кассандра-кли). Предполагается, что все последующие столбцы являются столбцами кластеризации, что мы можем проверить, посмотрев на имена ячеек.