SQLite和共享首选项的优缺点


155

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

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


这在很大程度上取决于您要存储的数据类型。SharedPreferences允许更快,更简单地访问数据,在保留少量数据时使用起来更舒适。
Egor

2
除了简单的字符串和原语,不要在共享首选项中存储任何内容-如果确实为每个字符串和原语使用单独的文件-尽管文档“共享首选项”不是线程安全的,即使仅在主线程上使用,如果您存储更多内容,则极有可能损坏文件中的1个键值对。
RunLoop

首次使用后,SharedPreferences会缓存在内存中,因此在随后的Read使用中,它们应该非常快。
斯坦(Stan)

Answers:


167

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

SQLite的

大量相同的结构化数据应存储在SQLite数据库中,因为数据库是为此类数据设计的。由于数据是由数据库结构化和管理的,因此可以使用查询语言(如SQL)来查询数据,以获取与某些条件匹配的子集。这样就可以搜索数据。当然,管理和搜索大量数据会影响性能,因此从数据库中读取数据可能比从SharedPreferences中读取数据要慢。

共享首选项

SharedPreferences是一个键/值存储,您可以在其中存储某些键下的数据。要从商店读取数据,您必须知道数据密钥。这使得读取数据非常容易。但是,存储少量数据就像存储和读取大型结构化数据一样困难,因为您需要为每个数据定义键,此外,您不能真正在数据中进行搜索,除非您有特定的概念命名键。


24
举个例子,SharedPreferences对于存储用户首选项很有用,因为那里只有少数几个变量需要存储。另一方面,SQLite最好用于存储有大量项目的数据,例如音乐库中的歌曲标题需要搜索的地方。
CL22

5
您无需知道键名称即可使用SharedPreferences。请参见getAll()。
ZaBlanc 2012年

5
仅供参考,有一个THIRD选项:将XML读/写到文件中。(请参阅android.util.xml类)。适用于可以一次全部读取/写入的中等复杂数据。例如,用户不经常更改的值的网格。特别是如果您稍后可能希望将其发送到其他地方的数据,则将需要可解析的格式。
ToolmakerSteve

1
是否建议将json作为json字符串保存在共享首选项中?
Kaveesh Kanwal

2
@JCarlos只要您不做一些跨进程的工作,就可以使用SharedPreferences了。
Mygod '17年

96

这个问题的答案是可以接受的,但是我认为关于速度的话题还有更多要说的。

应用程序的SharedPreferences和Sqlite DB都只是文件,存储在设备文件系统上的应用程序目录中。如果数据量不太大,则Sqlite选项将涉及一个更大,更复杂的文件,并且具有更多的处理开销以进行简单访问。

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

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

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


6
代码的可读性如何?我认为当在SharedPrefs中而不是db表中存储多个记录时,代码变得很复杂。SQL语法比遍历SharedPrefs条目更容易阅读...
IgorGanapolsky 2013年

8
伊戈尔,我不同意。SharedPreferences实际上是一维的,使用首选项非常简单。例如,我正在构建一个股票检查应用程序,我只是将股票代码存储在首选项中。我不需要单独抓取它们,因为我总是列出所有它们,而这就是我要做的,存储或抓取的所有事情。它是如此简单,比使用数据库简单得多。
AutoM8R 2013年

1
我无法想到这样一种情况,在这种情况下,代码的可读性会变得很困难,而要保存的数据结构则不需要使用分层数据库。即使存在任何可读性问题,也可以通过使用具有必需功能的包装器类来解决。
Sarath Sadasivan Pillai 2014年

1
我们可以在共享首选项下以jsonstring数据的形式存储多个键值吗?是否有可能限制我的json值的字符数限制?
2014年

2
SharedPreferences仅一次加载一次(在每个应用程序生命周期中)并保存在内存中;之后,它总是超级快。因此,将SharedPref数据放入SQLite中实际上并没有任何实际的性能优势(只是为了避免额外的SharedPref文件访问)。顺便说一句,您不应该将SQLite内容放入SharedPrefs中。如我所说,它总是存在于内存中,这可能会导致您遇到问题(内存不足的问题)。
Zsolt Safrany,2015年

20

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

如果你打算做加盟排序和其他操作数据库上的数据,然后去sqlite的。一个示例是按日期对数据进行排序。

如果要映射简单值(如int,boolean,String),请使用“首选项”。数据库操作在这里不起作用,不用说您需要拥有所有键。一个示例是用户密码或应用程序配置。

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


另外,SharedPreferences不支持事务,因此如果需要事务,请使用SQLite。例如,如果用户按下“注销”按钮,则可能要SharedPreferences一次清除多个键/值(例如userpassword键),以确保两个键都未设置或两个键都已设置。
runeks

5
  • 为了存储大量数据,请使用SQLite数据库系统。这也将允许用户搜索数据。

  • 另一方面,要存储少量数据,请使用“共享首选项”。在这种情况下,不需要庞大的数据库系统。这将允许用户简单地保存数据并加载它们。


1
300个键值对是海量数据吗?我需要完全存储它。
JCarlosR

1
在这种情况下,您应该使用SQLite数据库。否则,将很难管理和检索这300个数据。
萨米·贾巴尔

但是,如果所有密钥都是已知的,从“共享首选项”中获取数据会更容易吗?
Arjun

-6

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


12
忘记关于套子的所有知识。
Andrew G
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.