mit数据库实验一总结


代码实现

实验一:tuple和tupleDesc

目标:实现tuple和tupleDesc
tupleDesc = tupleDescription

image.png

实验2:catalog

image.png

  1. 包含表和表的架构:表的引用,表的名称,表的主键
  2. 表的增、查表
  3. 通过Database.getCatalog()来获取唯一的catolog
  4. 获取表的重要方式。通过id来获取表的信息或者表文件。

实验3:bufferpool

image.png

实验4:实现heapPageId, heapPage, recordID

1. 需要实现的方法和属性

  • heappage
1. getNumTuples() : 获取元组数目
2. HeapPage(HeapPageId id, byte[] data) 
3. getHeaderSize() :获取头(位示图)的长度
4. isSlotUsed(int i):该槽位是否被使用
5. iterator()
6. getNumEmptySlots() 


属性
1. pageid
2. tupleDesc								// 表的信息,元组信息和元组
3. []header and tuples

完成HeapPageIdTest, RecordIDTest, and HeapPageReadTest.即可。

实验5:实现heapFile

image.png

  1. 读取文件使用randomFile
  2. 迭代器
    1. 打开后开始有,只读取第一页
    2. 如果未空,看是否已经到页底了,如果没有到最后一页,指向下一页的开头。

实验6:操作

  1. 唯一性事务id
  2. 表别名
  3. 表id
  4. 表的迭代器

具体操作

  1. 别名 null.
  2. 迭代器,应该判断是否未空,防止没有open。

实验7:

  1. 创建test.txt文件,类似于下面, 最后需要换行
1,1,1
2,2,2
3,3,3

  1. 将test.txt转化成.dat文件,使用HeapFileEncode中的convert
  2. 运行给出的test,注意文件名要对应
    1. some_data_file.dat
package simpledb;
import java.io.*;

public class test {
    
    

    public static void main(String[] argv) {
    
    

        // construct a 3-column table schema
        Type types[] = new Type[]{
    
     Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE };
        String names[] = new String[]{
    
     "field0", "field1", "field2" };
        TupleDesc descriptor = new TupleDesc(types, names);

        // create the table, associate it with some_data_file.dat
        // and tell the catalog about the schema of this table.
        HeapFile table1 = new HeapFile(new File("some_data_file.dat"), descriptor);
        Database.getCatalog().addTable(table1, "test");

        // construct the query: we use a simple SeqScan, which spoonfeeds
        // tuples via its iterator.
        TransactionId tid = new TransactionId();
        SeqScan f = new SeqScan(tid, table1.getId());

        try {
    
    
            // and run it
            f.open();
            while (f.hasNext()) {
    
    
                Tuple tup = f.next();
                System.out.println(tup);
            }
            f.close();
            Database.getBufferPool().transactionComplete(tid);
        } catch (Exception e) {
    
    
            System.out.println ("Exception : " + e);
        }
    }

}
  1. 或者直接创建文件后运行下面的文件
package simpledb;

import org.junit.Test;
import simpledb.common.Database;
import simpledb.common.Type;
import simpledb.execution.SeqScan;
import simpledb.storage.*;
import simpledb.transaction.TransactionId;
import java.io.*;
/**
 * @author: Zekun Fu
 * @date: 2023/2/22 10:04
 * @Description:
 */
public class SQLTest {
    
    
    
    // 看当前的类路径
    @Test
    public void testPath() {
    
    
        System.out.println(String.format("当前的类路径是%s", System.getProperty("user.dir")));
    }
    
    // 测试文件转化
    @Test
    public void convert()  {
    
    
        File infile = new File("test.txt");
        File outFile = new File("some_data_file.dat");
        try {
    
    
            HeapFileEncoder.convert(infile, outFile, BufferPool.getPageSize(), 3);      // 默认3个int类型
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    @Test
    public void test() throws IOException{
    
    
        // construct a 3-column table schema
        // 构建表头
        Type types[] = new Type[]{
    
    Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE};
        String names[] = new String[]{
    
    "field0", "field1", "field2"};
        TupleDesc descriptor = new TupleDesc(types, names);

        // create the table, associate it with some_data_file.dat
        // and tell the catalog about the schema of this table.

        // 创建表文件映射
        File file = new File("test.txt");
        if (!file.exists()) {
    
    
            throw new IOException(".dat文件不存在!");
        }
        File heapFile = new File("some_data_file.dat");
        HeapFileEncoder.convert(file, heapFile, BufferPool.getPageSize(), 3);
        HeapFile table1 = new HeapFile(heapFile, descriptor);
        Database.getCatalog().addTable(table1, "test");

        // construct the query: we use a simple SeqScan, which spoonfeeds
        // tuples via its iterator.
        // 创建查询
        TransactionId tid = new TransactionId();
        SeqScan f = new SeqScan(tid, table1.getId());

        try {
    
    
            // and run it
            f.open();
            while (f.hasNext()) {
    
    
                Tuple tup = f.next();
                System.out.print(tup);
            }
            f.close();
            Database.getBufferPool().transactionComplete(tid);
        } catch (Exception e) {
    
    
            System.out.println("Exception : " + e);
        }
        boolean end = heapFile.delete();
        System.out.println("临时数据库文件是否删除成功:" + end);
    }
}

问题

  1. heapFile中的File大小是否是页的整数倍?如果不是,从页中读取数据的时候,不足一页了怎么办?如果是,写入的时候不足一页怎么办?
    1. 写的时候就是一页一页的写的,所以读的时候,不会出现不足一页的情况?
    2. 经过验证,每一个DBfIle中的大小一定是Page的整数倍。
    3. 如果4k, 两个int类型的数据,可以存储504条信息
  2. catolog中表信息为什么要放主键呢?
    1. 表的接口DBfile, id使用DBfile的id来确定。
    2. 表的名称和主键
    3. 因为主键和名称是表的重要信息。
  3. 为什么抛出NoSunElementException?
    1. 因为这个是定义好的,如果抛出这个错误,测试中可以继续执行。
  4. 实验7没有输出,不知道是.dat转化出错了,还是读取文件出错了。
    1. 根据debug调试,发现了问题。
    2. 根据跟踪,发现输出的tuple里面的域是存在的,说明转化没有错误,并且dbfile中的读取也是没有什么问题的。
      1. 先读取头
      2. 然后根据读取tuples
      3. 最后将读取到的内容放入到page中就行了。
    3. 然后既然读取没有问题,迭代器也没有什么问题,最后返回的tuple就是没有问题的,那么就只有输出的toString出现了问题,果然是这样,当时注释掉了,忘了恢复了。

猜你喜欢

转载自blog.csdn.net/fuzekun/article/details/129231100