唐国城
小米软件工程师,主要负责 MIUI 浏览器服务端研发工作。热爱开源,热爱技术,喜欢探索,热衷于研究学习各种开源中间件,很高兴能参与到 ShardingSphere 社区建设中,希望在社区中努力提高自己,为 ShardingSphere 社区的发展做更多的工作。
元数据在 ShardingSphere 中加载的过程
一、概述
元数据是表示数据的数据。从数据库角度而言,则概括为数据库的任何数据都是元数据,因此如列名、数据库名、用户名、表名等以及数据自定义库表存储的关于数据库对象的信息都是元数据。而 ShardingSphere 中的核心功能如数据分片、加解密等都是需要基于数据库的元数据生成路由或者加密解密的列实现,由此可见元数据是 ShardingSphere 系统运行的核心,同样也是每一个数据存储相关中间件或者组件的核心数据。有了元数据的注入,相当于整个系统有了神经中枢,可以结合元数据完成对于库、表、列的个性化操作,如数据分片、数据加密、SQL 改写等。
而对于 ShardingSphere 元数据的加载过程,首先需要弄清楚在 ShardingSphere 中元数据的类型以及分级。在 ShardingSphere 中元数据主要围绕着 ShardingSphereMetaData 来进行展开,其中较为核心的是 ShardingSphereSchema。该结构是数据库的元数据,同时也为数据源元数据的顶层对象,在 ShardingSphere 中数据库元数据的结构如下图。对于每一层来说,上层数据来源于下层数据的组装,所以下面我们采用从下往上的分层方式进行逐一剖析。
ShardingSphere 数据库元数据结构图
二、ColumMetaData 和 IndexMetaData
ColumMetaData 和 IndexMetaData 是组成 TableMetaData 的基本元素,下面我们分开讲述两种元数据的结构以及加载过程。ColumMetaData 主要结构如下:
public final class ColumnMetaData {
// 列名
private final String name;
// 数据类型
private final int dataType;
// 是否主键
private final boolean primaryKey;
// 是否自动生成
private final boolean generated;
// 是否区分大小写
private final boolean caseSensitive;
}
其加载过程主要封装在 org.apache.shardingsphere.infra.metadata.schema.builder.loader.ColumnMetaDataLoader#load 方法中,主要过程是通过数据库链接获取元数据匹配表名加载某个表名下所有的列的元数据。核心代码如下:
/**
* Load column meta data list.
*
* @param connection connection
* @param tableNamePattern table name pattern
* @param databaseType database type
* @return column meta data list
* @throws SQLException SQL exception
*/
public static Collection<ColumnMetaData> load(final Connection connection, final String tableNamePattern, final DatabaseType databaseType) throws SQLException {
Collection<ColumnMetaData> result = new LinkedList<>();
Collection<String> primaryKeys = loadPrimaryKeys(connection, tableNamePattern);
List<String> columnNames = new ArrayList<>();
List<Integer> columnTypes = new ArrayList<>();
List<String> columnTypeNames = new