Best way to store related data in LocalStorage

I have quite a bit of experience using relational databases and I’m wondering what is the best way of storing a “lot” of related data using LocalStorage.

For example, if I was writing an invoice app with customer and invoice data, I could store all the data in one storage object i.e. store all the customers and all the invoices in one storage object

Or, I could split it to have a separate storage object for EACH customer, or one storage object for ALL customers, and similarly a separate local storage object for ALL invoices, or each invoice?

Logically I would think that performance would be better if the data was split, and I only loaded whatever data was needed? Is this the case?

If there wasn’t going to be much data I would stick it all into one object, for convenience.

I am planning on incorporating offline functionality in an app that I am putting together and have investigated the use of pouchDB as it will provide much more flexibility than localStorage.

Thanks for the answer, but I think that addresses a different question. I have tinkered with Pouch/CouchDb a while ago and had to abandon it because, at the time, there was no way to delete old data from the server. They have probably fixed that by now.

I’m looking for an answer to the question of the best way to handle related data on a device so that performance is optimal on the device.

Please keep reading all the way to the end, because there is an important ancillary point there.

The performance difference will likely be very dependent on how many and how big these objects are, so there really isn’t any substitute for trying various strategies and profiling them. If you take care to structure everything so that there is always a single service provider responsible for interacting with storage, this should be easy to do without touching any code outside that class.

It helps if you keep in mind what goes on behind the scenes when you are updating something from storage:

  • a query is made to the underlying driver, that retrieves a string
  • that string is parsed as JSON into a JavaScript object
  • you walk through that object changing stuff
  • the updated object gets stringified again
  • and then passed back to the driver and stored as text

So the most natural granularity would generally be “whatever unit is modified as a chunk”.

Important ancillary point: you don’t want to be putting things in “LocalStorage”. Use Ionic Storage instead. True “LocalStorage” is fool’s gold. While its API may seem easier to deal with, its synchronous nature will make your app less responsive, and, more importantly, is not guaranteed against being reaped when the underlying OS feels like it.

Thanks Robert, Yes I’m using Ionic Storage, with Sqlite installed, I used the wrong terminology.

I guess what I’m asking is…is it OK to have lots of data stores, e.g. Invoices …

this.storage.set(this.invoiceId, this.invoiceObject)

…so each invoice is stored with its own key.

I think I’d prefer not to do this, but if I store them all in the “invoices” key and there get to be thousands of invoices then retrieving that data will be a memory hog.

“Invoices” is just an example, the data I’m saving will be coming from a bluetooth device and 100% stored on the phone.

[edit] I’ll try the single key approach to start with. As you suggested by using a DataProvider it’s very easy to switch between techniques. The single key approach will make management of the data a bit easier - I think? [/edit]

Yes. Each one would correspond to a “row” in your mental database model. That would generally be the most efficient method if those “data stores” are largely independent entities. I can’t say I’ve done thousands of these, but did not experience any problems with hundreds of them.