今天主要是帮助陈柏雄同学测试他的sreach方法,主要难点在连接数据库,互相传递数据
发现的主要问题是运行速度太慢,效率不高,我们准备一起学习一下数据库中常用的倒排表知识,
改进一下算法,目前的算法是直接字符串匹配的。。。。
public class ConnDb
{ OleDbConnection conn = null;//连接数据库的对象
//下面是构造函数连接数据库
public ConnDb()
{ if (conn==null)//判断连接是否为空
{ conn = new OleDbConnection();
conn.ConnectionString="provider=sqloledb.1;data source=.;initial catalog=capucivar;user id=sa;pwd=";//连接数据库的字符串 }
if (conn.State == ConnectionState.Closed)
{ conn.Open();//打开数据库连接
} }
//下面这个方法是从数据库中查找数据的方法
public DataSet query(string sql)
{ DataSet ds = new DataSet();//DataSet是表的集合
OleDbDataAdapter da = new OleDbDataAdapter(sql,conn);//从数据库中查询
到排表知识
1、 基于属性的倒排
在一个带结构的记录文件中,如数据库文件等。文件里存放的都是一条接着一条的整齐的记录,每个记录又可分为一个个的属性。检索过程往往要求找出,在某个或者某些属性上满足一定条件的记录集合。像这一类的检索我们称为基于属性的检索。
比如北大里某次活动的学生报名登记表文件,部分信息如下:
编号(关键码) |
学号 |
姓名 |
性别 |
年龄 |
院系 |
001 |
xxx142 |
张三 |
男 |
18 |
元培 |
002 |
xxx205 |
李四 |
女 |
17 |
哲学 |
003 |
xxx187 |
王五 |
男 |
19 |
生物 |
004 |
xxx325 |
赵六 |
女 |
18 |
元培 |
…… |
…… |
…… |
…… |
…… |
…… |
表1 主文件
对这类文件的往往会进行这样的一些查询,如:找出院系为“元培”的所有学生(简单查询),找出年龄在18到20之间的所有学生(范围查询),找出年龄在19岁以上的所有男生(逻辑查询)等等。如果没有倒排表,我们则只能顺序从头到尾的一条一条检查记录,判断是否符合条件。这样当文件很大的时候,往往要多次读写磁盘会耗费相当大的时间。就算之前我们把记录按照关键码排序,也仍无法使用普通的检索方式来提高效率,因为查找的条件不是和关键码相关的。
而我们利用倒排文件来实现上述非关键码的查询,就能大大提高速度。对于前面的情况设计倒排表如下:
性别倒排表 |
编号# |
男 |
001,003 |
女 |
002,004 |
年龄倒排表 |
编号# |
16 |
|
17 |
002 |
18 |
001,004 |
19 |
003 |
20 |
|
…… |
…… |
院系倒排表 |
编号# |
元培 |
001,004 |
生物 |
003 |
哲学 |
002 |
…… |
…… |
表2 倒排表文件
有了这样的倒排表后,前面的查询就很容易了。如找出院系为“元培”的所有学生(简单查询),可以在院系倒排表中,取出属性值为“元培”的那一行倒排表,它里面包含的所有编号对应的记录就是所求的记录。又如找出年龄在18到20之间的所有学生(范围查询),我们可以把年龄倒排表中18,19和20这三行所对应的三个编号集合做并运算,最后结果就是我们要找的。而找出年龄在19岁以上的所有男生(逻辑查询),这个我们找出19岁以上的所有编号集合,用并运算合在一起,再同性别倒排表中的男生那一行的集合做与运算,最后就能得到正确结果。
由此可见,有了倒排文件,我们就可以将查询变成几个集合之间的交,并等运算,得到的最后结果即时我们要求的,这样不用挨个读取记录,且参与运算的数据大大减少,基本可以不用多次读写磁盘而直接在内存里进行运算,大大提高了检索速度。