Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否有适当的方法来管理从文件中删除数据?_Java_C#_Database_Performance - Fatal编程技术网

Java 是否有适当的方法来管理从文件中删除数据?

Java 是否有适当的方法来管理从文件中删除数据?,java,c#,database,performance,Java,C#,Database,Performance,我有一个小型自定义数据库,我很好奇是否应该以不同的方式处理数据更新: 目前,我在HD上写入文件的结构如下所示: Header(uniqueID,lengthOfDataInBytes,HeaderChecksum) data 文件中有数千个这样的结构,数据部分平均只有几百kb 如果我想更新/删除一个结构,我会将以下所有结构读入内存,将它们写回要更新/删除的结构开头的文件,清除索引器字典,然后将更新后的结构附加到文件末尾/不做任何操作,让我的索引器再次运行整个文件 这非常有效,因为通常的文件大小

我有一个小型自定义数据库,我很好奇是否应该以不同的方式处理数据更新:

目前,我在HD上写入文件的结构如下所示:

Header(uniqueID,lengthOfDataInBytes,HeaderChecksum)
data
文件中有数千个这样的结构,数据部分平均只有几百kb

如果我想更新/删除一个结构,我会将以下所有结构读入内存,将它们写回要更新/删除的结构开头的文件,清除索引器字典,然后将更新后的结构附加到文件末尾/不做任何操作,让我的索引器再次运行整个文件

这非常有效,因为通常的文件大小是~2Gbyte,并且更新的结构最有可能再次更新,因此不太可能在文件开始时对结构进行持续更新

然而,我不准备面对这样一种情况:用户的文件大小大于其RAM,我猜这种情况会破坏我当前更新/删除部件的设置吗

对于如何解决这一问题,是否有共同的做法? 我心目中的备选方案是:

  • 使用“跳过此扇区”命令覆盖已更新/已删除结构的标头,将其作为junkcode保存在文件中,并将更新版本附加到末尾。 好的方面是,我不必阅读以下所有部分。缺点是,我必须决定一个运行清理例程的好时机

  • 将数据库拆分为多个固定大小的文件,并将所需扇区的文件指针添加到索引器中。保留旧的更新/删除方式。 Updside:不需要进一步的清理工作 缺点:增加了另一个抽象层次

这通常是如何处理的?有没有更好的解决办法

编辑:请停止建议使用sql。 我试过了,它的性能比我目前正在使用的解决方案差得多。 如果这是难以置信的,考虑一下:

  • 我两侧都没有冗余的内存缓冲区
  • 我保存缓冲数据的引用
  • 我不需要在查询字符串上浪费额外的周期
  • 我可以通过对已经读取/即将写入的数据执行一些反序列化工作来填补HD读/写时间的延迟,而不必等待数据库返回查询结果/在将其传递给sql之前必须完成所有这些工作。(这是迄今为止影响最大的)

考虑将自定义文件格式替换为实际数据库,例如。(甚至可能是客户机/服务器数据库,如MySQL或SQL server。)

以额外实施工作为代价,您可以获得以下好处:

  • 处理数据的经过测试和验证的代码
  • 对数据的随机访问(数据库为您建立记录索引)意味着快速插入/更新/删除

在您的情况下,uniqueID将成为表的主键,您可以删除数据列的校验和和长度,并使数据列成为blob或文本(取决于内容)。

考虑用实际数据库(例如)替换自定义文件格式。(甚至可能是客户机/服务器数据库,如MySQL或SQL server。)

以额外实施工作为代价,您可以获得以下好处:

  • 处理数据的经过测试和验证的代码
  • 对数据的随机访问(数据库为您建立记录索引)意味着快速插入/更新/删除

在您的情况下,uniqueID将成为表的主键,您可以删除数据列的校验和和长度,使数据列成为blob或文本(取决于内容)。

将所有内容加载到RAM的动机是什么?这种操作最有效的选项是内存映射文件(
FileChannel\map
)?类似sqlite的东西似乎就是您想要使用的东西。@SteffenWinkler,因为我试过了,速度慢了大约一倍100@MarkoTopolnik我不是把所有的东西都装进ram。当我读的时候,我只读想要的扇区,当我写的时候,我只读我想要的扇区后面的扇区update@user3488765我非常确信:如果你的实验表明使用分贝会使你的速度降低100倍。。。然后你做错了什么。我发现你处理如此大量数据的方法是“手动”的,通过重新创建自己的数据库层,使之成为“一个有趣的想法”。将所有内容加载到RAM中的动机是什么?这种操作最有效的选项是内存映射文件(
FileChannel\map
)?类似sqlite的东西似乎就是您想要使用的东西。@SteffenWinkler,因为我试过了,速度慢了大约一倍100@MarkoTopolnik我不是把所有的东西都装进ram。当我读的时候,我只读想要的扇区,当我写的时候,我只读我想要的扇区后面的扇区update@user3488765我非常确信:如果你的实验表明使用分贝会使你的速度降低100倍。。。然后你做错了什么。我发现你处理如此大量数据的方法需要“手动”重新创建自己的数据库层,这是一个很好的“有趣的想法”。尝试过之后,速度要慢上百倍,而且还需要客户设置db@user3488765我无法想象速度慢是由发动机本身造成的(特别是对于客户机/服务器引擎),但更多的是根据特定的用例(我们需要更多的细节,它是特定于SQLite的问题的候选)。此外,SQLite不需要安装。如果您将驱动程序与应用程序一起分发,它将被删除。@user3488765有很多应用程序在内部使用数据库,而不要求用户安装/设置任何内容