美文网首页
六 hugegraph 源代码 之 存储模型(mysql为例)

六 hugegraph 源代码 之 存储模型(mysql为例)

作者: NazgulSun | 来源:发表于2019-06-28 12:28 被阅读0次

存储模型Overview

  • 每一个图的点,边,shema,会被映射到 BackendEntity。
  • BackEntity 以 HugeType + BackendColumn 来对数据建模
  • 模型支持传统的 row based 的关系型数据库,也支持 cassendra 这样 column based 的数据库。
  • 以addVertex 和 mysql 为例。Vertex 首先会被一个 serierlar 序列化 成 mysqlBackendEntity,对应一张数据库表的一个实体
  • MysqlBackendStore 动态生成 sql,进行 save/update/delete。

serializer

在前面讲解 graphTransaction的时候提到了
*** this.doInsert(this.serializer.writeVertex(v)); ***

这个方法会调用对应存储引擎的serializer进行数据序列化。
我们看下 序列化的接口:

public interface GraphSerializer {

    public BackendEntry writeVertex(HugeVertex vertex);
    public BackendEntry writeVertexProperty(HugeVertexProperty<?> prop);
    public HugeVertex readVertex(HugeGraph graph, BackendEntry entry);

    public BackendEntry writeEdge(HugeEdge edge);
    public BackendEntry writeEdgeProperty(HugeEdgeProperty<?> prop);
    public HugeEdge readEdge(HugeGraph graph, BackendEntry entry);

    public BackendEntry writeIndex(HugeIndex index);
    public HugeIndex readIndex(HugeGraph graph, ConditionQuery query,
                               BackendEntry entry);

    public BackendEntry writeId(HugeType type, Id id);
    public Query writeQuery(Query query);
}

写的时候,将 图对象 转化成 backendEntity,读的时候将 backendEntity转化成图的对象。

顺藤摸瓜,看看 writeVertex 的实现。

writeVertex

    @Override
    public BackendEntry writeVertex(HugeVertex vertex) {
        TableBackendEntry entry = newBackendEntry(vertex);
        entry.column(HugeKeys.ID, IdUtil.writeString(vertex.id()));
        entry.column(HugeKeys.LABEL, vertex.schemaLabel().id().asLong());
        // Add all properties of a Vertex
        this.formatProperties(vertex, entry.row());
        return entry;
    }
  • 因为看的是mysql 的实现,所以它生成的是一个TableBackEntity,数据表的形式建模,
  • TableBackendEntry 有几个重要元素,hugeType,ID,Row
  • 可以看到一共是存入了三个column,Id,label,properties(formatProperties如下)
    @Override
    protected void formatProperties(HugeElement element,
                                    TableBackendEntry.Row row) {
        Map<Number, Object> properties = new HashMap<>();
        // Add all properties of a Vertex
        for (HugeProperty<?> prop : element.getProperties().values()) {
            Number key = prop.propertyKey().id().asLong();
            Object val = prop.value();
            properties.put(key, val);
        }
        row.column(HugeKeys.PROPERTIES, JsonUtil.toJson(properties));
    }

backEndStore.mutate()

在graphTransaction里面提交的时候,都使用了 backendStore的mutate方法,我们看看
mysql Backedn的mute方法

private void mutate(Session session, BackendAction item) {
        MysqlBackendEntry entry = castBackendEntry(item.entry());
        MysqlTable table = this.table(entry.type());

        switch (item.action()) {
            case INSERT:
                table.insert(session, entry.row());
                break;
            case DELETE:
                table.delete(session, entry.row());
                break;
            case APPEND:
                table.append(session, entry.row());
                break;
            case ELIMINATE:
                table.eliminate(session, entry.row());
                break;
            default:
                throw new AssertionError(String.format(
                          "Unsupported mutate action: %s", item.action()));
        }
    }

这段代码,做了两件事

  • 生成MysqlBackendEntity,这里很简单,实际就是做了类型转化。
  • 获取操作 数据库的类是于 DAO 一样的类, 这里使用MysqlTable封装, 对于不同的类型,实现方式不一样,其实就是定义了一些schema
    比如节点,table的schema 包含 ID,Label,Properties 等,整个hugegraph封装还是做的不错的。

接下来看看 insert方法

    public void insert(Session session, MysqlBackendEntry.Row entry) {
        String template = this.buildInsertTemplate(entry);

        PreparedStatement insertStmt;
        try {
            // Create or get insert prepare statement
            insertStmt = session.prepareStatement(template);
            int i = 1;
            for (Object object : entry.columns().values()) {
                insertStmt.setObject(i++, object);
            }
        } catch (SQLException e) {
            throw new BackendException("Failed to prepare statement '%s'" +
                                       "for entry: %s", template, entry);
        }
        session.add(insertStmt);
    }
  • 根据 entry 动态构建 sql语句,并且根据columns的值设置 statement。

整个入库的过程就是这样,下面一张主要介绍,如何出库, 比如mysql 里面的数据是如何以图查询的。

相关文章

网友评论

      本文标题:六 hugegraph 源代码 之 存储模型(mysql为例)

      本文链接:https://www.haomeiwen.com/subject/vaescctx.html