文章目录
代码实现
实验一:tuple和tupleDesc
目标:实现tuple和tupleDesc
tupleDesc = tupleDescription
实验2:catalog
- 包含表和表的架构:表的引用,表的名称,表的主键
- 表的增、查表
- 通过Database.getCatalog()来获取唯一的catolog
- 获取表的重要方式。通过id来获取表的信息或者表文件。
实验3:bufferpool
实验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
- 读取文件使用randomFile
- 迭代器
- 打开后开始有,只读取第一页
- 如果未空,看是否已经到页底了,如果没有到最后一页,指向下一页的开头。
实验6:操作
域
- 唯一性事务id
- 表别名
- 表id
- 表的迭代器
具体操作
- 别名 null.
- 迭代器,应该判断是否未空,防止没有open。
实验7:
- 创建test.txt文件,类似于下面, 最后需要换行
1,1,1
2,2,2
3,3,3
- 将test.txt转化成.dat文件,使用HeapFileEncode中的convert
- 运行给出的test,注意文件名要对应
- 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);
}
}
}
- 或者直接创建文件后运行下面的文件
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);
}
}
问题
- heapFile中的File大小是否是页的整数倍?如果不是,从页中读取数据的时候,不足一页了怎么办?如果是,写入的时候不足一页怎么办?
- 写的时候就是一页一页的写的,所以读的时候,不会出现不足一页的情况?
- 经过验证,每一个DBfIle中的大小一定是Page的整数倍。
- 如果4k, 两个int类型的数据,可以存储504条信息
- catolog中表信息为什么要放主键呢?
- 表的接口DBfile, id使用DBfile的id来确定。
- 表的名称和主键
- 因为主键和名称是表的重要信息。
- 为什么抛出NoSunElementException?
- 因为这个是定义好的,如果抛出这个错误,测试中可以继续执行。
- 实验7没有输出,不知道是.dat转化出错了,还是读取文件出错了。
- 根据debug调试,发现了问题。
- 根据跟踪,发现输出的tuple里面的域是存在的,说明转化没有错误,并且dbfile中的读取也是没有什么问题的。
- 先读取头
- 然后根据读取tuples
- 最后将读取到的内容放入到page中就行了。
- 然后既然读取没有问题,迭代器也没有什么问题,最后返回的tuple就是没有问题的,那么就只有输出的toString出现了问题,果然是这样,当时注释掉了,忘了恢复了。