Jonathan
Jonathan

Reputation: 1508

Multi dimension Lookup Table

I need to define a large amount of data to be stored within an app and used as a lookup table. For instance, I have an array of manufacturer names, each with a mfg code. Each manufacturer can make different products, each with their own code as well.

A,7 could be deciphered to mean

Manufacturer: Apple(A)
Product: MacMini(7)

I see several ways of defining this, but I'm not sure which would be best.

Option 1) #define these constants in a separate header file such as:

#define MFG_APPLE @"A"
#define MFG_DELL  @"B"

#define PRODUCT_MAC_MINI 7
#define PRODUCT_INSPIRON 2

Option 2) create a dictionary object filled with dictionary objects to allow me to index through them easier.

Option 3) use core data to create a database of these mfgs and products and relationships.

If option 2 or 3 is suggested, are there easy ways to pre-populate these data structures instead of hard-coding them to populate during program startup?

Option 4) Create a web service to tie this back to a server, where the data can be updated more often. A JSON query will send the mfg and product codes to the server, where it can respond with the mfg and product names.

Upvotes: 1

Views: 634

Answers (1)

Mecki
Mecki

Reputation: 132879

You should consider the following: If the database is shipped with the app, you will have to release an update for the app each time the database must be updated. So the question is, how frequently will you have to update the data? If it's fine to update the database once every couple of months or maybe just once a year, shipping the database with your app might be an option, if you need to update it every month or even weekly, you should definitely host the database somewhere on the web; releasing an update in such short intervals is not a feasible option.

Another thing you should consider: If the database exists solely as a web service and each look up requires a JSON call to the server, it won't be possible to perform a lookup if the user is offline (currently has no network access for whatever reason). Also each lookup costs the user traffic, so if the user has a monthly limit, yet needs to perform plenty of lookups a day, using your app may quickly cause him to exceed that monthly limit, leaving him without any Internet service (or a very throttled one) in the end.

From my experience, it is best to host such a database online, yet cache it for offline access if possible. The app itself ships with a database copy, that was up-to-date the day you built the app for distribution. Each time the app is started, and maybe once a day in case the app is never quit, it will query a web server for the current "version" of the database. If this version is newer than the one shipped with the app, it tries to downloads a copy of this database to its local cache and then switches to the cached copy for future lookups. If the cached copy gets lost (caches may be flushed by the system at any time), it will have to re-download it. In the meantime, it can use the shipped database, which is outdated, yet better than nothing. If download is not possible (e.g. not enough free space is available on the device), the app may want to make online queries directly if the user currently is online, fall back to the out-dated shipped database if he is offline, and retry to download a cache copy at some later time (maybe the device will have more free space available at that time).

So basically your app will have a work flow as follows:

  1. START
  2. A locally cached copy exists? If NO Goto 6.
  3. The locally cached copy is up-to-date? If NO Goto 5.
  4. Perform the lookup using the local cached copy. Goto 12.
  5. Delete the outdated cached copy. Goto 1.
  6. The shipped database is up-to-date? If NO Goto 8.
  7. Perform the lookup using the shipped database. Goto 12.
  8. Download the updated database.
  9. Download succeeded? If YES Goto 4.
  10. The user is currently online? If NO Goto 7.
  11. Perform the lookup using a JSON webservice. Goto 12.
  12. END

If you only add more entries to the database in the future, yet existing entries will never change, there is also another, even much better option: You have simply two databases. One that ships with the app and one that only contains the updates (new entries added) after the last app release. This shrinks the amount of data that needs to be downloaded and cached dramatically. In that case your app must always perform two lookups, one in the shipped database (which is always performed first), and if nothing is found there, in the downloaded cached copy, which does not contain the entries already found in the shipped database (or directly online, if no cached copy is available, yet the user currently has Internet access). Each time you release a new update of the app, it will get a new full copy of the database, hence you can reset the update database back to zero entries and only keep adding new entries there (or you can keep different update databases lying around on the server for different app versions that had different databases shipped with them, if you don't think that is too much hassle to manage).

The update database for download may even be created dynamically by the server, that would of course be the best option. E.g. after shipping the app, you add 3 vendors and 30 products to the database, and every vendor and product has a unique ID (that is strictly increasing with each new entry added), then the app can tell the server that the highest vendor it knows has ID X and the highest product has ID Y, in which case the server sends out an update database with all vendors and products whose IDs are higher than X and Y.

All these decisions influence on the database format to use. Generally it sounds a lot like a job for CoreData, yet if you want dynamic update databases, the updates should be delivered in a different format (JSON, XML, CVS, or something else a server can easily generate) and be converted to CoreData by the app after the download is completed, since dynamically generating CoreData databases on a server is rather hard and definitely not recommend.

Upvotes: 2

Related Questions