简体   繁体   English

在房间数据库中存储复杂数据类型的替代方法

[英]Alternate approach to storing complex data types in room database

Existing approach : Currently we use TypeConverters to help database to store and retrieve complex data type (POJO class objects).现有方法:目前我们使用TypeConverters来帮助数据库存储和检索复杂数据类型(POJO class 对象)。 But that involves serializing and deserializing the objects, which seems unnecessary when we only need a simple primitive data type like int, string, float, etc.但这涉及对象的序列化和反序列化,当我们只需要一个简单的原始数据类型如 int、string、float 等时,这似乎是不必要的。

My approach : I am thinking of an approach of breaking down the complex data type to primitive ones and create separate columns to store them.我的方法:我正在考虑一种将复杂数据类型分解为原始数据类型并创建单独的列来存储它们的方法。 When we need a simple primitive type from the database, then we won't have to go through the process of deserializing complex objects.当我们需要从数据库中获取一个简单的原始类型时,我们就不必通过反序列化复杂对象的过程 go 了。

I have tried the my approach and it is working but I'm not sure of the corner cases that may arise while implementing this approach in big projects.我已经尝试了我的方法并且它正在工作,但我不确定在大型项目中实施这种方法时可能出现的极端情况。

I am still new to this, need help in finding pros and cons of my approach.我对此还是陌生的,需要帮助来找出我的方法的优缺点。

There are some who advocate storing a representation of objects as a single column.有些人提倡将对象的表示形式存储为单个列。 This is fine if you just want to store and retrieve the objects and then work with the objects.如果您只想存储和检索对象然后使用这些对象,这很好。 The code itself can often be shorter.代码本身通常可以更短。

If you want to manipulate the underlying values (fields in the object) embedded in the representation via the power of SQLite then matters can get quite complex and perhaps inefficient due to the much higher likelihood of full table scans due to the likely lack of available/usable indexes.如果您想通过 SQLite 的功能来操纵表示中嵌入的基础值(对象中的字段),那么事情会变得非常复杂并且可能效率低下,因为由于可能缺乏可用/可用的索引。

eg if myvalue is a value within a representation (typically JSON) then to find rows with this value you would have to use something like例如,如果 myvalue 是表示(通常是 JSON)中的一个值,那么要查找具有该值的行,您将不得不使用类似

@Query("SELECT * FROM the_table WHERE the_one_for_many_values_column LIKE '%myvalue%'")

or或者

@Query("SELECT * FROM the_table WHERE instr(the_one_for_may_values_column,'myvalue')

as opposed to myvalue being stored in a column of it's own (say the_value) then而不是将 myvalue 存储在它自己的列中(比如 the_value)然后

@Query("SELECT * FROM the_table WHERE the_value LIKE 'myvalue')
  • the former two have the flaw that if myvalue is stored elsewhere within the representation then that row is also included even.前两个有一个缺陷,如果 myvalue 存储在表示中的其他地方,那么该行也包括在内。 Other than the fact that LIKE is case independent the third is an EXACT.除了 LIKE 与大小写无关之外,第三个是 EXACT。
  • an index on the the_value column may improve performance the_value 列上的索引可以提高性能

Additionally the representation will undoubtedly add bloat (separators and descriptors of the values) and thus will require more storage.此外,表示无疑会增加膨胀(值的分隔符和描述符),因此需要更多存储空间。 This compounded as the same data would often be stored multiple times whilst a normalised relational approach may well store just 1 instance of the data (with just up to 8 bytes per repetition if a 1-M relationship (indexes excluded)).由于相同的数据通常会被存储多次,而规范化的关系方法可能只存储数据的一个实例(如果 1-M 关系(不包括索引),每次重复最多只存储 8 个字节)。

  • 32 bytes of bloat and the maximum needed to cater for a many-many relationship (8 bytes parent 8 bytes child and two 8 bytes columns in the mapping table) will be exceeded.将超过 32 字节的膨胀和满足多对多关系所需的最大值(映射表中的 8 字节父项、8 字节子项和两个 8 字节列)。

As the SQLite API utilises Cursors (buffering) to retrieve extracted data, then with a greater storage requirement fewer rows can be held at once by a CursorWindow (the limited sized buffer that is loaded by x rows of output).由于 SQLite API 使用 Cursors(缓冲)来检索提取的数据,因此随着存储需求的增加,CursorWindow(由 x 行输出加载的有限大小的缓冲区)一次可以保存的行数更少。 There is also greater potential, again due to the bloat, of a single row being larger than the CursorWindow permits.还有更大的潜力,同样由于膨胀,单行大于 CursorWindow 允许的。

In short for smaller simpler projects not interested greatly in performance, then storing representations via TypeConverters could be the more convenient and practical approach.简而言之,对于对性能不太感兴趣的更小、更简单的项目,然后通过 TypeConverters 存储表示可能是更方便和实用的方法。 For larger more complex projects then unleashing the relational aspects of SQLite via data that is related rather than embedded within a representation could well be the way to go.对于更大更复杂的项目,然后通过相关数据而不是嵌入表示中的数据释放 SQLite 的关系方面很可能是通往 go 的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM