Catalog

关系型数据库存储在 bind、optimism 的时候需要知道相关的系统元信息,这些 metadata 被存储在 Catalog 中。RisingLight 相关代码在 src/catalog 中。由于 RisingLight 比较简单,所以 Catalog 中没有存储太多的东西,只存储了 Column、Table、Scheme 之间的关系。

RisingLight 中 Catalog 的视图如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            +------+
| Root |
+------+
/ \
+---------+ +---------+
| Scheme1 | ... | Schemen |
+---------+ +---------+
/ \
+--------+ +--------+
| Tablek | ... | Tablen |
+--------+ +--------+
/ \
+---------+ +---------+
| Column1 | | Column2 | ...
+---------+ +---------+

Root Catalog
Root Catalog 是 Catalog 结构的最顶层,描述了 Root Catalog 和 Scheme 之间的关系。根据代码的定义来看,一个 Root 会有多个 Scheme,但是除了增加 Root 的时候,我没有找到其他添加 Scheme 的地方。猜测可能是一个 Root 对应一个 scheme,只是为了与其他系统的概念对应才这样设计的

1
2
3
4
5
6
7
8
9
10
11
/// The root of all catalogs.
pub struct RootCatalog {
inner: Mutex<Inner>,
}

#[derive(Default)]
struct Inner {
schema_idxs: HashMap<String, SchemaId>,
schemas: HashMap<SchemaId, SchemaCatalog>,
next_schema_id: SchemaId,
}

Schema Catalog
Schema 是数据库对象的集合,table、view、index 都可以包含在一个 Scheme 中,对于有用户权限的数据库系统,在 Scheme 上还可以指定不同的用户权限。

在 RisingLight 中,一个 Scheme Catalog 只描述了 table name 到 table 的映射,以及 table id 到 TableCatalog 的映射。我们可以通过 table name 或者 table id 在一个 Scheme 中唯一确定一个 table,但是由于不同 Scheme 中可能有相同的 table name,所以我们需要使用 <scheme_name, table_name> 才能唯一确定一个 table。在 bind 阶段,就需要通过 <scheme_name, table_name> 在 catalog 中查找是否能够找到对应的 Scheme 和 table。

1
2
3
4
5
6
7
8
9
/// The catalog of a schema.
#[derive(Clone)]
pub struct SchemaCatalog {
id: SchemaId,
name: String,
table_idxs: HashMap<String, TableId>,
tables: HashMap<TableId, Arc<TableCatalog>>,
next_table_id: TableId,
}

Table Catalog
Table Catalog 描述了一个 Table 中 Columns 的信息。与查找 Table 类似,定位一个 table 中的 Column 需要通过 <scheme, table, column> 三元组来查找。由于一个 table 中可能会有主键,为了快速找到主键 table 还记录了主键列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
pub struct TableCatalog {
id: TableId,
name: String,
/// Mapping from column names to column ids
column_idxs: HashMap<String, ColumnId>,
columns: BTreeMap<ColumnId, ColumnCatalog>,

#[allow(dead_code)]
is_materialized_view: bool,
next_column_id: ColumnId,
#[allow(dead_code)]
ordered_pk_ids: Vec<ColumnId>, // 主键列表,因为主键可能是 pk(col1, col2...) 这样的形式
}

Column Catalog
Column Catalog 描述了一个 Column 的相关信息,包括 Column 的类型、是否为空、是否是主键等信息。Column Catalog 的结构信息如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct ColumnCatalog {
id: ColumnId,
desc: ColumnDesc,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct ColumnDesc {
datatype: DataType,
name: String,
is_primary: bool,
}
/// Data type with nullable.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct DataType {
pub kind: DataTypeKind,
pub nullable: bool,
}