Simple-db-lab1

Simple-db-lab1

本实验主要实现了一个数据库的基本组成部分:

  • TupleDesc

    TupleDesc 用来描述一个元组,一个元组包含一个或多个 字段(如 Student(id, name, age, ...)),每一个字段都需要确定的知道它的 类型 + 字段名。定义如下:

    public static class TDItem implements Serializable {
        // 类型
        public final Type fieldType;
        // 字段名
        public final String fieldName;
    }
    
    public class TupleDesc implements Serializable {
        private final TDItem[] tds;
    }
    
  • Tuple

    一个 Tuple 就是数据表中的一条记录,本实验中只包含 INT 与 STRING 两种类型的数据,对应 IntField 与 StringField 两种字段,一条记录包含了一个或多个字段,所以每一个 Tuple 需要包含一个字段的数组。

    public class IntField implements Field {
        private final int value;
    }
    
    public class StringField implements Field {
    	private final String value;
    	private final int maxSize;
    }
    
    public class Tuple implements Serializable {
        private TupleDesc tupleDesc;
        private RecordId recordId;
        private final Field[] fields;
    }
    
  • Catalog

    Catalog 存储数据库的元数据,描述了这个数据库中所有的数据表信息。这里单独定义了一个 Table 的结构体,用 ConcurrentHashMap 来存储 tableId 与 Table 加速查找并保证线程安全。每一个 Table 都对应磁盘上的一个 DbFile,用来存储数据。

    public class Catalog {
        
        private final ConcurrentHashMap<Integer, Table> catalog;
        
        private static class Table{
            
            static private long increaseID = 0;
            
            public final DbFile file;
            public final String name;
            public final String pkeyField;
            public final long tableId;
        }
    }
    
  • BufferPool

    Table 以 DbFile(e.g. HeapFile)的形式存储在磁盘上,DbFile 由许多 Page (e.g. HeapPage) 组成,每一个 Page 有固定的大小,存储固定数量的 Tuple。BufferPool 利用局部性原理来集中管理从磁盘读取的 Page(通过调用 DbFile 的 readPage 函数),提高读写效率。

    public class BufferPool {
        
        private static final int DEFAULT_PAGE_SIZE = 4096;
    
        private static int pageSize = DEFAULT_PAGE_SIZE;
    
        public static final int DEFAULT_PAGES = 50;
    
        private final int maxPages;
        private final ConcurrentHashMap<Integer, Page> pages;
    }
    
  • HeapPageId

    一个 Page 可以由 两个元素 唯一标识,这个 Page 所属的 Table,以及这个 Page 在这个 Table 中所处的位置。

    public class HeapPageId implements PageId {
        private final int tableId;
        private final int pgNo;
    }
    
  • RecordId

    一个 Record 可以由 三个元素 唯一标识,这个 Tuple 所属的 Table,在 Table 中的哪一个 Page (前两项可以用 PageId 表示)以及在 Page 中的位置。

    public class RecordId implements Serializable {
    
        private final PageId pid;
        private final int tupleno;
    }
    
  • HeapPage

    一个 Page 由 header 和多个 tuple 组成。header 是一个 bitmap,用来标注哪一个 tuple 正在被使用。header 后面就是这个 Page 存储的所有 tuple,每一个 tuple 占用一个 slot。

    public class HeapPage implements Page {
    
        final HeapPageId pid;
        final TupleDesc td;
        final byte[] header;
        final Tuple[] tuples;
        final int numSlots;
    
        byte[] oldData;
        private final Byte oldDataLock= (byte) 0;
    }
    
  • HeapFile

    每一个 Table 都唯一对应一个 DbFile 用来在磁盘上存储数据。HeapFile 是 DbFile 接口的一个实现。DbFile 的实现依赖于文件系统,readPage 函数从相应 DbFile 的偏移位置读取一个 Page 大小的字节数。

    public class HeapFile implements DbFile {
    
        private final File file;
        private final TupleDesc td;
    }
    
  • SeqScan

    SeqScan 是本实验实现的第一个运算符,利用了 HeapFile 中实现的迭代器来遍历表中的元组。

    public class SeqScan implements OpIterator {
    
        private TransactionId tid;
        private int tableid;
        private String tableAlias;
        private DbFileIterator it;
    }
    

整个数据库系统的相关数据结构及关系如下图所示:

posted @ 2021-10-11 22:50  keven137  阅读(91)  评论(1)    收藏  举报