SQLite 与文本文件数据库 - 大小比较?

Mas*_*ter 2 database sqlite text converter

我要转换成db形式的text文件SQLite;我很担心这些点,因为要为它编写代码:

  • 文本文件或其相应的 sqlite db 的大小是否相同?
  • SQLite 会比文本文件占用更少的空间吗?
  • 或者文本文件 db 是空间最小的文件?

Mat*_*att 5

“硬件很便宜” - 我强烈建议不要担心尺寸差异,无论如何这可能无关紧要,而是选择最能满足您其余需求的解决方案。文本文件可以很好地用于简单的项目,但数据库具有更多功能,可以帮助您更高效、更稳健地组织、备份和查询数据。

要更深入地了解这两个选项的优缺点,请查看:数据库与平面文件


Zoe*_*Zoe 5

需要记住的一些事情:

(关于此答案的注意事项:此处的文件引用内部/外部存储,而不是 SharedPrefs)

SQL:

  • 数据库有开销,这确实会占用空间
  • 如果数据库或表损坏,所有数据都会丢失(这有多糟糕取决于您的应用程序。丢失几千张图片:不好。丢失删除日志:不是很糟糕)
  • 数据库可以压缩(请参阅此)
  • 如果您对 ID(或识别行 X 的任何方式)有疑问,您可以将数据拆分到不同的表中,这意味着一个数据库可以为每个对象拥有多个表,其中对象 X 与对象 Y 存在标识冲突。这基本上意味着您可以将所有内容保存在一个文件中,并且仍然避免名称冲突。(阅读答案底部的更多内容)

文件:

  • 每个文件都必须定义为自己的单独文件,这会占用空间(文件名)
  • 如果不设置一个高级读取器来确定不同类型的数据,则无法将所有属性存储在一个文件中。如果您不这样做,并且每个属性都有一个文件,那么您将使用大量空间。
  • 读取数千行可能会很慢,特别是如果您有几个(例如 100+)非常大的文件

操作系统为每个文件使用空间,不包括内容。占用空间的实例的文件名。但需要记住的是,您可以将应用程序的所有数据保存在一个文件中。如果您的应用程序中两种不同类型的对象可能存在命名问题,则您可以创建一个新数据库。


命名冲突

假设您有两个对象,对象 X 和 Y。

场景1 '

对象X存储两个变量。文件名是(x 和 y 在本例中是坐标):

x.txt
y.txt
Run Code Online (Sandbox Code Playgroud)

但在更高版本中,对象 Y 带有相同的两个文件。所以你必须为对象 X 和 Y 分配一个 ID:

0-x.txt
0-y.txt
Run Code Online (Sandbox Code Playgroud)

每个文件仅在名称上就使用 3 个字符(总共 7 个字符,包括扩展名)。设置越复杂,这个值就越大。参见场景 2

但是保存在数据库中,您将获得 ID 为 0 的行并找到 X 或 Y 列。您不必担心文件名。

此外,如果每个对象保存大量文件,则加载或保存每个文件的引用将占用大量空间。这会影响您的 APK 文件,并慢慢将您推向 50 MB 限制(Google Play 限制)。

您可以创建通用方法,但您可以使用 SQL 执行相同的操作并节省 APK 文件中的空间。但与文本文件相比,SQL 在名称方面确实节省了一些空间。

但请注意,如果您保存 2-3 个文件(只是为了获取一个数字),那么那些用于名称的字节并不重要

当你开始保存数百个文件、长名称以避免命名冲突时,这就是 SQL 为你节省空间的时候。如果表变得太大,您可以对其进行压缩。您可以压缩文本文件,也许可以节省一些空间,但对于单行文件来说,没有什么可节省的。

场景2

对象 X 和 Y 各有三个子对象。

每个孩子都有 3 个变量保存到文件系统中。如果只有一个对象有 3 个子对象,它可以像这样保存它

[id][variable name].txt
Run Code Online (Sandbox Code Playgroud)

但是因为还有另一个父对象有 3 个子对象(相同类型,并且它们保存相同的文件),所以最后保存的对象的子对象将保持保存状态。前 3 个被覆盖。

所以你必须添加父ID:

[parent ID][child ID][variable name].txt
Run Code Online (Sandbox Code Playgroud)

请记住,这些示例集中于几个对象。节省的空间量很低,但是当您保存数百甚至数千个文件时,就开始节省空间。

现在,如果您创建一个表,您可以存储主要对象(在本例中为 X 和 Y)。然后,您可以以可识别该对象是父对象还是子对象的方式创建第一个表,也可以创建第二个表。第二个表有两个ID值;一张用于识别父母,一张用于识别孩子。因此,如果您想查找对象 436 的所有子对象,只需编写以下查询:

SELECT * FROM childrentable WHERE `parent_id`='436'
Run Code Online (Sandbox Code Playgroud)

这将为您提供以对象 436 作为其父对象的所有子对象的所有属性。

返回时所有内容都存储在 Cursor 中。

如果您要对文件执行相同的操作,则此行(其中Saver是文件保存和加载类):

Saver.load("0-436-file_name", context);
Run Code Online (Sandbox Code Playgroud)

当然,可以使用 for 循环来循环子 ID(开头的 0),但是您还必须保存有多少个子 ID:您无法轻松获取文件,因此您有存储有关对象数量和对象子对象的值。

这意味着您必须在更多文件中保存更多值才能获取您首先保存的文件。这是一种非常困难的做事方式。数据库将帮助您不必编写文件来跟踪您保存了多少文件。数据库将为每个查询返回 [x] 个结果。因此,如果对象 436 没有子对象,SQL 将返回 0 行。但在文件中,您必须保存 0 作为子项数量。猜测文件名会导致 I/O 异常。