二叉树数据存储实现

时间:2012-06-24 00:40:33

标签: c++ database data-structures binary-tree

我已经开始在c ++中使用二叉树了,我必须说我真的很喜欢这个想法,事情对我来说很清楚,直到我想到将数据存储在磁盘上的顺序,以后我可以立即读取一大块数据。 到目前为止,我已经将所有内容(节点)存储到ram中...但这只是一个简单而不是真实的应用程序。我不想将整个二进制树存储在磁盘上,因为你必须再次将它读回内存,因此它将无用!我所追求的是一种方法,例如MYSQL。 我没有找到任何关于此的好文章,所以如果我有人包含一些网址或书籍,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

与b-tree和b + tree的主要区别: - 叶节点被链接以进行快速锁定顺序读取。可以指向升序,可以指向降序,或两者(就像我在一个IBM DB中看到的那样)

  • 您应该将其写在磁盘上,如果表或文件增长,您将遇到内存问题。 (对文件的SEEK操作非常快。您可以在不到1秒的时间内在磁盘上创建1 GB文件... C#filestream,method .SetFilesize)

  • 如果您设法拥有多个读者/编写者,则需要对索引和表(或文件)进行并发控制....您可以在内存中做到这一点吗?如果发生电源故障,你怎么回滚呢?你也不要。

IE:字段f1已编入索引。

WHERE 1 = 1(不需要访问b +树,全部给我,订单无关紧要)

WHERE 1 = 1 ORDER BY f1 ASC / DESC(需要访问b +树,按升序/降序给我全部)

WHERE f1> = 100(需要访问b + tree,锁定叶节点= 100的位置,并在右指针后面给出所有叶子节点项。如果这个进程是多线程读取,它们可能会出现一个奇怪的顺序,但没有问题......没有按条款订购。)

WH1 f1> = 100顺序f1 asc(需要访问b + tree,锁定叶节点= 100的位置,并给出右指针后面的所有叶子节点项。这个过程不应该是b +树之后的多线程,来了自然有序。

字段f2用b +树索引并输入字符串。

名称如'%ODD' (在内部,必须反转比较值,并且所有符号都保持在最后,例如以“DDO”开头,并以任何内容结束。' DDOT'在组中,所以' TODD'必须属于结果!!!!棘手,棘手的逻辑; P)

有了这句话, 名称如'%OD%' (在中间' OD')。事情变热:)))) 在内部,结果是“OD%'”的子结果的UNION。将子结果反转为“DO%'”。之后,删除开始的OD'结束' OD'没有' OD'在中间,否则它是一个有效的结果(' ODODODODOD'它是一个有效的结果。无效的结果' ODABCD'以及' ABCDOD')。

考虑一下我说的话,如果你做得很深,还要检查更多的东西: - FastIO on files:C#Filestream no_buffered_flag,wriththought disk flag on。 - 内存映射文件/内存视图:是的,我们可以根据需要以小部分操作一个巨大的文件 - 索引:位图索引,哈希索引(哈希函数;完美哈希函数;哈希函数的模糊性),稀疏索引,密集索引,b +树,r树,反向索引。 - 多线程:锁,互斥,信号量 - 事务性结论(日志文件,2阶段提交; 3阶段提交); - 锁(数据库,表格,页面,记录) - 死锁:3种杀死它的方法(更长的冲突过程;更年轻的冲突过程;锁定更多对象的过程)。现代RDBM使用3种混合方式...... - SQL解析(AST-Tree)。 - 缓存周期性查询。 - 触发器,程序,视图等 - 将参数传递给过程(可以使用对象类型; P)

  • 不要在记忆中加载所有内容,智能解决方案负载部件,因为它们需要它并且在它不再可用时释放。为什么=>您的数据库引擎(和PC)使用更少的内存变得更具响应性。使用b + tree进行锁定,分支叶节点只需要2个磁盘IO。知道了锁定值,就会得到记录长指针。 SEEK位置的主文件,阅读内容。这太快了。内存更快...是的,但是你可以在内存中放入10 GB的b +树吗?如果是这样,您的数据库引擎程序如何开始表现? Slowlly?

忘记二叉树和常规的btree:它们是学术教程。现实生活中他们被哈希表或b +树取代(B PLUS TREE显示存储和有序上升 - http://en.wikipedia.org/wiki/B%2B_tree

  • 考虑在多个磁盘中为数据空间使用数据空间。您可以并行化磁盘IO性能。不要忘记镜像它们......每个数据空间应该有一个带有indice片段的表的片段,以及一个部分日志文件。你应该开发一个协调器,它可以很好地呈现子单元的查询。

IE:3个数据空间...... INSERT INTO等......只应该在1个表空间中发生。

但 从TB_XPTO中选择*应该显示在所有数据空间中。

通过索引字段从TB_XPTO顺序中选择*,应该呈现给所有数据空间。每个数据空间都执行指令,所以现在我们按子顺序有3个子集。

结果将出现在协调员处,将再次对其进行重新排序。 混淆,但快!!!!!!!

协调员应控制主交易。

如果数据空间A已提交 数据空间B提交 dataspace C处于uncommited状态 协调员将回滚C,B和A.

如果数据空间A已提交 数据空间B提交 数据空间C提交 协调员将承诺整个交易。

COORDINATOR日志: 创建主交易UID 121212,儿童交易(1111,2222,3333)

DATA SPACE A LOG 1111 INSERT len字节数组 1111 INSERT len字节数组 COMMIT 1111

DATA SPACE B LOG 2222 INSERT len字节数组 2222 INSERT len字节数组 COMMIT 2222

DATA SPACE C LOG 3333 INSERT len字节数组 3333 --->没有更多......这里的电力故障!!!!!!!

在启动协调器上检查数据库是否正确关闭,如果没有,它将检查他的日志文件。好吧,缺少像COMMIT 121212这样的主提交行。因此它会查询数据空间以获取日志一致性。 A,B接收COMMITED,但是在检查了他的日志文件后,C检测到失败。回复UNCOMMITED。 主协调员FORCES TABLESPACE A,B,C FOR ROLLBACK 1111,2222,3333 之后,他自己回滚了他的主事务并将DB状态= OK。

这里的要点是插入,选择,更新和删除的速度

  • 考虑保持指数平衡。索引上的许多删除都会使它失去平衡。不平衡的索引会降低其性能....在索引文件的头部添加一个堆,用于控制它。这里有些数学会有所帮助。如果删除超过记录的5%,请平衡并重置计数器。如果索引字段上的更新结束,则应对其进行计数。

  • 考虑到现场指数,要聪明一点。如果列是Gender,则只有2个选项(我希望,lol .... ops,也可以为空...),一个位图索引很好地应用。如果字段的清晰度(我认为我拼写错误)是100%(所有值都是异构的),就像应用在像Oracle这样的字段上的序列,或者像SQL Server那样的标识字段,那么b +树就可以很好地应用了。如果一个字段是几何类型,就像在Oracle中一样,R-Tree是最好的。对于字符串,可以很好地应用反向索引,或者如果是异类则使用b +树。

  • 休斯顿,我们有问题.... 在索引中也应该考虑NULL值字段。它的价值也是!!!! IE:WHERE F1为空

  • 添加一些套接字功能:异步TCP / IP服务器

- 如果删除记录,请不要立即调整文件大小。将其标记为已删除。你也应该在这里做一些指标。如果未使用的空间> x和transactions = 0,执行数据库锁定并重新分配指针,然后调整数据库大小。 DB文件中出现了一些空格,你可以尝试做一些页面锁而不是数据库锁...事情可以继续下去,没有人受伤....测量数据库的最后一个解锁页面,锁定它。检查您可以填写页面的已删除页面。未找到,释放锁定;如果找到,请移动新位置,修复指针,将旧页面标记为已删除,调整文件大小,释放锁定。为什么这么多操作?保持日志良好形成!!!!你可以用小页面拆分页面,但是你得到了碎片(唉...我们失去了速度指挥官?)...... 2算法来到这里。最适合,最适合......谷歌吧。最好的是....使用两者:P

如果你解决了所有这些问题,你可以大声喊出来,DAM,我发了一个数据库...... IM GONA NAME ORACLE !!!!" ; P