1.综述
所有的索引都实现了org.h2.index.Index接口
Index接口有add、remove、find方法,但是没有update方法
实现Index接口的两个直接子类是:
org.h2.index.MultiVersionIndex
org.h2.index.BaseIndex
BaseIndex是一个抽象类,如果要实现新的索引类型,可以从此类扩展。
H2目前实现了13种索引类型(请看"Index类图"文件)
2. 各类索引类型说明
org.h2.index.MetaIndex
MetaIndex是只读的,不支持add、remove方法,
用于查找数据库元数据,比如通过java.sql.DatabaseMetaData提供的方法查找
org.h2.index.FunctionIndex
FunctionIndex是只读的,不支持add、remove方法,
用于"SELECT * FROM VALUES(1, 'Hello'), (2, 'World')" ,遍历VALUES
3. 查询记录时,如何通过索引中的key与PageDataIndex中的数据关联起来
在org.h2.command.dml.Select.queryFlat(int, ResultTarget, long)中调用
for (int i = 0; i < columnCount; i++) {
Expression expr = expressions.get(i);
//触发:
//org.h2.expression.ExpressionColumn.getValue(Session)
//org.h2.table.TableFilter.getValue(Column)
row[i] = expr.getValue(session);
}
会取得当前行的所有字段,expr.getValue(session)会触发org.h2.table.TableFilter.getValue(Column)
public Value getValue(Column column) {
if (currentSearchRow == null) {
return null;
}
int columnId = column.getColumnId();
if (columnId == -1) {
return ValueLong.get(currentSearchRow.getKey());
}
if (current == null) {
Value v = currentSearchRow.getValue(columnId);
if (v != null) {
return v;
}
current = cursor.get();
if (current == null) {
return ValueNull.INSTANCE;
}
}
return current.getValue(columnId);
}
currentSearchRow是索引字段组成的行,如果要取的列包含在currentSearchRow中,那么直接返回currentSearchRow中的列,
否则调用org.h2.index.IndexCursor.get() => org.h2.index.PageBtreeCursor.get()
public Row get() {
if (currentRow == null && currentSearchRow != null) {
//currentSearchRow.getKey()得到的就是PageDataIndex中的key
currentRow = index.getRow(session, currentSearchRow.getKey());
}
return currentRow;
}
=>org.h2.index.PageBtreeIndex.getRow(Session, long)
public Row getRow(Session session, long key) {
return tableData.getRow(session, key);
}
=>org.h2.table.RegularTable.getRow(Session, long)
public Row getRow(Session session, long key) {
return scanIndex.getRow(session, key);
}
=>org.h2.index.PageDataIndex.getRow(Session, long)
public Row getRow(Session session, long key) {
return getRowWithKey(key);
}