What is the difference between using external db file(from assets) and creating a new db using SQLiteOpenHelper? Performance wise which one will be fast? will accessing db from assets slow down my application.
What is the difference between using external db file(from assets) and creating a new db using SQLiteOpenHelper?
You cannot directly use a database that is pre-packaged in your app as an asset. SQLite needs a file; an asset is not a file, but rather is an entry in the ZIP file that makes up an APK.
Using something like SQLiteAssetHelper, you can a pre-packaged database as the starting point for your user, by copying the database from assets into internal storage for your app.
will accessing db from assets slow down my application.
That depends on what you compare it to, and even then the difference will only be the first time you try to work with the database.
With the database-packaged-as-a-asset approach, the database needs to be copied from assets before it can be used. This takes time. It should not be dramatically slower than creating an empty database and executing SQL statements to populate it. In fact, I would expect it to be faster in many cases. However, it will be slower than starting from an empty database.
Once the database is created and set up -- whether via your own CREATE TABLE statements or by copying a starter database from assets -- performance will be identical, because the databases themselves are identical.
The assets folder is read-only, so if you need to edit your database then it won't work for yourapp. If you have a pre-populated database, one option is to make a copy from the assets folder into somewhere that is writeable when your app is first accessed, and then continue with using the writeable version.
There isn't a performance difference assuming your database is properly configured. See this:
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
I'm using this procedure for a ~500mb database upon which I have to do fairly complex and substantial queries routinely, and which I zip for distribution and unzip on the first run due to size and this works flawlessly.
Related
(I'm new to android development)
Say android app-1 created a database hello, via roo.
Then could android app-2 created a database hello, on the same phone?
My guess is yes, since room use sqlite, each app may start a new sqlite instance, and may store its data in private space, otherwise it's too easy to get conflict. But I'm not sure.
The questions are:
Will 2 app share the same sqlite instance, or each app will start a new sqlite?
Is the database's name app scoped?
I guess the data of a database is also private to the application?
(I've searched about this, didn't get a confirm.)
By default, Room databases are stored in internal storage, and each app has its own internal storage. You can have two databases named hello, one per app, without a problem.
Really SQLite is a set is a set of file handling routines (more complex than just simple writes and reads though).
Android devices come with the routines built in (albeit different versions of SQLite which are typically backwards compatible).
Room is a wrapper around SQLite and thus the routines and caters for an object orientated approach to accessing the data (file(s)).
Unlike, for example, MySQL, SQLite it is not a server that manages transactions from extrenal sources, so SQLite is not a running instance background app/service. (The command line interface would be though)
A device can have many Apps that use the routines to access and update the underlying file (3 files if using the default WAL (Write-Ahead Logging, the core database file, the wal file and a third file the shm file a WAL file for the WAL), (2 files if using JOURNAL mode).
with WAL changes are applied to the WAL file which are then committed at times to the core/master file. Likewise for the shm file in regard to the WAL file. This allows a rollback to simply effectively delete/empty the WAL file.
JOURNAL mode the journal is a record/log of the changes made to the core database. A rollback is accomplished by reversing the changes according to the JOURNAL.
WAL is typically more efficient.
Typically this is all handled by the SQLite routines.
An App can itself access multiple databases if need be. SQLite even caters for accessing multiple database by ATTACHing databases to another.
By default the database is stored in the App's protected data storage area and thus is unique to the App. What you couldn't do, by default, is have the same database name twice within an App
you could say have two hello databases in different locations e.g. data/data/the_package/databases/hello and data/data/myotherdatabasesfolder/hello
note sure how you would go about this using Room though, certainly feasible using just the SQLite API.
So App1 and App2 could have the same hello database as the files will be in separate App specific locations (data/data/the_apps_package_name/databases by default).
I have an Android app that writes data to a db. Initially, when we started, we stored the db in an app-specific folder (something like /storage/org.domain.app/db/db.sync and so on). Things worked with no issues. However, the issue was that this DB would get wiped out everytime we reinstall the app.
We therefore moved the DB to a different folder outside the app. (Now the path is something like /storage/data/db/db.sync). Now, if we reinstall the app, we still have the old DB entries. However, now reading and writing to the DB is a lot lot slower.
I am not sure if this slowness is because the amount of data has shot up. Since the data is now persistent across multiple reinstalls.
I suspect this could also be because the DB is now in a folder external to the app. To rule this out, I setup the DB in an app specific folder and intend to copy the entire DB from some previous tests (that contains lot more data - the amount of data which caused the DB access to slow down). However, I am unable to do so.
Some questions:
1. I am not able to actually access the folder where the DB is setup. The folder is created in Context.MODE_PRIVATE mode. Therefore, only the app itself can access it. I tried changing it to MODE.WORLD_READABLE. However, this is deprecated and throws an exception while using it. Is there a way to make this folder easily editable?
I also tried accessing the DB from Device file explorer in Android studio. I opened the existing DB (db.sync file) and just copy-pasted the large DB I already have. However, it looks like this method does not allow us to copy or even display more than 400 KB of information. The DB I have is around 60-70 MB. Hence this approach did not work either.
Is there a way I can edit the db.sync file?
Does DB being in a folder external to the app make it slower? Esp when there are too many entries. In my case, certain search operations happen via a local cache and happens in a giffy. However, we also need to log some stuff to the DB and that takes forever. I figured this out by adding timer logs in the code.
Anything else, I could do to identify if the DB path is causing the issue?
Thanks,
Anand
Since there are two ways by which we can store or copy the data from database. one is from sqlite file which we lay in assets folder and another by database which is created programmatically.
I have following questions regarding the sqlite database in android:
1.which performs faster while getting performing select query from database and why?
2.what are the advantages of each approach.
I found on internet but i could not get any proper information, the only thing that i come to know by Googling is copying data from assets is better for static data like list of country(that is obvious because you will not perform any bulk operation of inserting data programmatcially in android). Any help regarding this is appreciated . :)
It does not make a difference.
Your select query is performed on the final database, which would be identical whether you copied it from assets, or imported it programmatically. Your approach to its creation does not influence its behaviour.
As for advantages, that's entirely up to you. In some scenarios, having a base database in assets would give you better, and easier to read, control over versioning, as you could commit it easily with your repository, vs. having thousands of SQL statements in code.
On the flip side, updating a database that you copy from the assets folder with each version could be difficult, especially if you modify data within the app frequently. Instead of programmatically simply altering the schema or data on update, you would have to export any modifications, copy the new database, and then import all your modifications by performing some form of merge.
Basically, I'm trying to store some data (~300 rows, ~10 columns) for an android app. This data will not be changed by the app, just used in calculations and stuff.
However, everything I've found online (example) talks about using a database that is created at runtime. I do not want this, the data will be the same every time the app is run.
So is there a way of using a databse like this? (Or any other way of storing data in a table-like fashion?)
Generate the SQLite database as part of your build and keep it in your app's raw resources. Since all you need is the file's path and name to open it, you can still read it fine. Your open helper will still go through onCreate() the first time unless you include the table Android uses for its own bookkeeping, but that should be okay.
Make sure you only open it for reading, and you should be good to go.
Put your custom file in the assets folder under the project root.
To get a inputstream from the file, just do:
context.getAssets().open(file);
In this way you can store your static data in conma separated or any model you want.
If you want the data constantly changing, you can create a temporary file in the SDCard, by accessing and creating a new file under some path at:
Environment.getExternalStorageDirectory()
How about storing this data in raw file under Assets or Res/raw folder. You can either dump this data on the fly in Database or read it and process it [which may be costly]. Dynamic handling may be costly, test it and compare performance.
I am seeing some strange behavior with my application and the state of its database file after running some tests that close the database, delete it, and replace it with a test fixture. When I examine the database file with a tool on my debugging PC, it doesn't match what the application itself seems to be reporting. It's possible that this strange behavior is related to this bug.
I noticed that there are two files with the same base name as the database (with the normal .db extension.) The file extensions are .db-shm and .db-wal, and each is newer than the .db file's timestamp.
I assume that these are some type of temporary files. However, I am wondering if the application is terminated, shouldn't they be deleted? More importantly, I assume whatever data is stored in them is updated inside the .db file before the application is terminated by the operating system. Is this correct?
You are correct, these are temporary files created by SQLite. If you are manually deleting the main db you should probably delete these too. From what I can gather the WAL is a replacement for the rollback journal that enables SQLite to rollback changes when a transaction fails. How SQLite uses them and why they are kept around for so long is up to the authors of SQLite but in general SQLite seems pretty rock solid so I wouldn't worry too much about them. For more info take a look here:
http://www.sqlite.org/fileformat2.html#walindexformat
These files are a new feature of SQLite 3.7. I'm not sure if their existence relates to the bug you point out but the bug report suggests a work-around anyway.
UPDATE:
Better documentation about the WAL is here:
https://www.sqlite.org/wal.html
The contents of the WAL are periodically moved to the DB file but this is not guaranteed to occur each time the process exits. Thus when WAL is enabled each SQLite DB consists of two files on disk that must be preserved, both the .db file and the .db-wal file.
The .db-shm file is a shared memory file that contains only temporary data.
I do not yet have enough reputation to just add a comment to satur9nine's answer, so I'll pile on here.
As per the SQLite docs, the DB-SHM file is a Shared Memory file, only present when SQLite it running in WAL (Write-Ahead Log) mode. This is because in WAL mode, db connections sharing the same db file must all update the same memory location used as index for the WAL file, to prevent conflicts.
As for WAL file, as hinted above, it is a write log/journal, useful for commits/rollback purposes.
Make sure that you have closed cursor properly into SELECT operation. Sometimes SQLiteOpenHelper creates .db-shm and .db-wal extensions database due to unclosed Cursor.