SQLite 和共享首选项的优缺点 [关闭]

Posted

技术标签:

【中文标题】SQLite 和共享首选项的优缺点 [关闭]【英文标题】:Pros and Cons of SQLite and Shared Preferences [closed] 【发布时间】:2011-09-10 16:57:14 【问题描述】:

在 SQLite 数据库和共享首选项之间存储信息的好机制是什么?

为什么要使用共享偏好?为什么要使用 sqlite?我试图找出它们之间的区别,哪个是更好的数据存储机制,但我无法在 Google 上找到合适的答案。请帮我举例和解释。

【问题讨论】:

这在很大程度上取决于您要存储的数据类型。 SharedPreferences 允许更快速、更简单地访问数据,在保留少量数据时使用起来更舒适。 除了简单的字符串和原语之外,不要在共享首选项中存储任何内容 - 如果您确实为每个文件使用单独的文件 - 尽管文档共享首选项不是线程安全的,即使仅在主线程上使用如果您在文件中存储超过 1 个键值对,则极易损坏。 SharedPreferences 在首次使用后被缓存在内存中,因此在随后的读取使用中它们应该非常快。 【参考方案1】:

这实际上取决于您要存储的数据。

SQLite

大量相同的结构化数据应存储在 SQLite 数据库中,因为数据库是为此类数据设计的。由于数据是由数据库结构化和管理的,因此可以使用 SQL 等查询语言对其进行查询以获取符合特定条件的数据子集。这使得在数据中进行搜索成为可能。当然,管理和搜索大量数据会影响性能,因此从数据库读取数据可能比从 SharedPreferences 读取数据要慢。

SharedPreferences

SharedPreferences 是一个键/值存储,您可以在其中将数据保存在某个键下。要从存储中读取数据,您必须知道数据的键。这使得读取数据非常容易。但是,存储少量数据很容易,存储和读取大型结构化数据很困难,因为您需要为每个数据定义键,而且您无法真正在数据中搜索,除非您有一定的概念命名键。

【讨论】:

举个例子,SharedPreferences 可用于存储用户偏好,其中只有少数变量需要存储。另一方面,SQLite 更适合存储有大量项目的数据,例如需要搜索的音乐库中的歌曲标题。 您无需知道键名即可使用 SharedPreferences。请参阅 getAll()。 仅供参考,还有第三个选项:将 XML 读/写到文件中。 (参见 android.util.xml 类)。适用于可以一次读取/写入的中等复杂数据。例如,用户不经常更改的值网格。特别是如果它是您以后可能想要发送到其他地方的数据,因此需要采用可解析的格式。 是否建议将 json 保存为共享首选项中的 json 字符串? @JCarlos 只要你不做一些跨进程的东西,你就可以使用 SharedPreferences。【参考方案2】:

这个问题有一个公认的答案,但我认为关于这个主题还有更多要说的——关于速度。

应用程序的 SharedPreferences 和 Sqlite DB 都只是文件,存储在设备文件系统上的应用程序目录中。如果数据量不太大,Sqlite 选项会涉及到更大更复杂的文件,对于简单访问来说处理开销更大。

因此,如果数据的性质不决定您的选择(如已接受的答案中所述),并且速度很重要,那么您最好使用 SharedPreferences。

读取一些数据通常是显示主要活动的关键路径,因此我认为速度通常非常重要。

关于速度和效率的最后一个想法 - 如果您需要将 Sqlite 数据库用于某些结构化数据,那么将用户首选项也存储在数据库中可能会更有效,这样您就不会打开第二个文件。这是一个相当次要的考虑因素 - 仅当您需要在显示主要活动之前访问结构化数据和首选项时才值得考虑。

【讨论】:

代码可读性如何?我认为在 SharedPrefs 而不是 db 表中存储多条记录时,代码变得复杂。 Sql 语法比遍历 SharedPrefs 条目更容易阅读... 伊戈尔,我不同意。 SharedPreferences 实际上是一维的,使用首选项非常简单。例如,我正在构建一个股票检查应用程序,我只是将股票代码存储在首选项中。我不需要单独抓取它们,因为我总是列出所有它们,这就是我所做的一切,存储或抓取。它是如此简单,比使用数据库简单得多。 我想不出代码的可读性变得困难而要保存的数据结构不需要使用分层数据库的情况。即使存在任何可读性问题,也可以通过使用具有所需功能的包装类来解决。 共享首选项下能否以jsonstring数据的形式存储多个key-value?是否有字符限制可能会截断我的 json 值? SharedPreferences 仅加载到内存中一次(每个应用程序进程生命周期)并保存在那里;之后它总是超级快。因此,通过将 SharedPref 数据放入 SQLite(只是为了避免额外的 SharedPref 文件访问),实际上并没有任何实际的性能提升。顺便说一句,你不应该把你的 SQLite 东西放到 SharedPrefs 中;正如我所说,它总是在内存中,这可能会导致您出现问题(内存不足)。【参考方案3】:

我的看法是,这与速度或大小无关,而是您想要对数据执行的操作类型。

如果您打算对您的数据进行加入排序和其他数据库操作,那么请选择Sqlite。一个示例是按日期对数据进行排序。

如果您想映射简单值(如 int、boolean、String),请使用 Preferences。数据库操作在这里不起作用,不用说你需要拥有所有的钥匙。一个例子是用户密码或应用程序配置。

拥抱 Preferences 的最大诱惑是当您想使用它将扁平化 POJO(序列化 JSON 对象)存储为 String 时。有这样的需求其实是使用Sqlite的标志。为什么 ?因为复杂的数据最终需要复杂的运算。想象一下检索一个可以通过简单的“SELECT ... WHERE id = 1”处理的特定条目。在 Preferences 路径中,这将是一个从反序列化到迭代结果的漫长过程。

【讨论】:

另外,SharedPreferences 不支持事务,所以如果你需要事务然后使用 SQLite。例如,如果用户按下“注销”按钮,您可能希望一次清除多个 SharedPreferences 键/值(例如,userpassword 键),以便您确定两个键都未设置或都已设置。【参考方案4】:

要存储大量数据,请选择 SQLite 数据库系统。这 将允许用户搜索数据。

另一方面,为了存储少量数据,选择 Shared 优先。在这种情况下,不需要庞大的数据库系统。 这将允许用户简单地保存数据并加载它们。

【讨论】:

300 个键值对是海量数据吗?我需要准确地存储它。 在这种情况下,您应该选择 SQLite 数据库。否则,将很难管理和检索这 300 条数据。 但是如果所有的键都知道,从共享首选项中获取数据不是更容易吗?【参考方案5】:

忘记 SQLLite 忘记 SharedPreferences,使用 Realm。适用于所有本地存储的单一解决方案。您可以使用普通的旧 Java 对象作为 RealmObjects 并将您的数据存储在那里。您可以将选择的查询转换为 JSON 文件。无需解析整个数据库。 检查此链接: https://realm.io/news/introducing-realm/

【讨论】:

忘掉你对沙发套的了解。

以上是关于SQLite 和共享首选项的优缺点 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用共享首选项的情况下将数据存储为颤动的对象[关闭]

即使在应用关闭时,共享首选项也会永久传递给另一个活动

应用程序崩溃时,共享首选项会重置数据。请指导

使用共享首选项保存和重新加载 ListView [保存 onDestroy()]

Android - 保存自定义对象 - 共享首选项或数据库?

保存的首选项在重新启动时不起作用