Skip to content

How Brahmand Models and Stores Graph Data

Brahmand translates high-level Cypher DDL into ClickHouse tables.

Graph Example

  • Nodes: User, Post
  • Relationship: Created
CREATE NODE TABLE User(
UserId UInt64,
Reputation String,
<!-- other columns -->
NODE ID(UserId),
PRIMARY KEY(Reputation, UserId)
);
CREATE NODE TABLE Post(
PostID UInt64,
PostTypeId Int8,
<!-- other columns -->
NODE id(PostID),
PRIMARY KEY(PostTypeId, PostID)
);
CREATE REL TABLE CREATED(From User To Post);
-- node User
CREATE TABLE User(
userId UInt64,
Reputation String,
...
) ENGINE = MergeTree
ORDER BY(Reputation, userId);
-- node Post
CREATE TABLE Post(
postId UInt64,
PostTypeId Int8,
...
) ENGINE = MergeTree
ORDER BY(PostTypeId, postId);
-- edge Created
CREATE TABLE CREAETED(
from_user UInt64,
to_post UInt64,
) ENGINE = MergeTree
ORDER BY(from_user, to_post);

Work is underway on edge indexes using materialized views and bitmaps to improve both storage efficiency and traversal performance. Use ADJ INDEX when creating a bitmap index on an edge. Currently, bidirectional indexes are created by default, but once the feature matures, the API will support unidirectional indexes.

CREATE REL TABLE CREATED(From User To Post, ADJ INDEX(true));

Graph Example With Index

-- edge index - Created outgoing direction
CREATE TABLE CREAETED_outgoing(
from_id UInt64,
to_id AggregateFunction(groupBitmap, UInt64)
) ENGINE = AggregatingMergeTree
ORDER BY from_id;
-- MV for outgoing edge
CREATE MATERIALIZED VIEW mv_CREAETED_outgoing TO CREAETED_outgoing AS
SELECT
from_user AS from_id,
groupBitmapState(to_post) AS to_id
FROM CREAETED
GROUP BY from_id;
-- edge index - Created incoming direction
CREATE TABLE CREAETED_incoming(
from_id UInt64,
to_id AggregateFunction(groupBitmap, UInt64)
) ENGINE = AggregatingMergeTree
ORDER BY from_id;
-- MV for incoming edge
CREATE MATERIALIZED VIEW mv_CREAETED_incoming TO CREAETED_incoming AS
SELECT
to_post AS from_id,
groupBitmapState(from_user) AS to_id
FROM CREAETED
GROUP BY from_id;

Edges are stored using ClickHouse’s Roaring Bitmap (via AggregateFunction(groupBitmap, UInt64)), offering:

  • High compression of large integer sets

  • Fast set operations for union/intersection during traversals (WIP)