I need to store an retrieve a vector of an unknown number of objects in an android sqlite database.
Essentially, the setup is this: I am developing a task management app, where the user can add as many notes as they like to their tasks. My current setup uses one database, with one row per task. This presents a problem when I need to associate multiple notes and their associated information with one task. I can see two approaches: try to store an array of notes or a vector or something as a BLOB in the task's row, or have another notes database in which each row contains a note and it's info, as well the id of the task which the note belongs to. This seems a little easier to implement, as all I would have to do to retrieve the data would be to get a cursor of all notes matching a particular id and then iterate through that to display them to the user. However, it seems a little inefficient to have a whole new database just for notes, and it makes syncing and deleting notes a little more difficult as well.
What do you think? Is it worth it to have a separate notes database? Should I use a BLOB or go for the separate database? If a BLOB, are there any good tutorials out there for storing and retrieving objects as BLOBs?
It sounds like you need another table in your database (not another database). You already have a table for Tasks. Now make one for Notes. Make a column be a foreign key into the Tasks table. That is, Notes.Task_ID would hold the ID of the Task that the Note is for. Then when you want to get all of the notes for a task, query the Notes table.
I think the answer to this question really lies in how you're going to go about updating things should they change. For now, the BLOB route probably seems like a really good idea, but what happens if you want to add some new functionality and you want to store some new property of notes (think of things like starred or importance). What would you need to do in order to update the notes object to add this new field? If it's just a database table, it's quite easy to change the layout of the table and even add a default value. If it's a BLOB, you're going to need to go through each entry, de-serialize the BLOB object, fix it, and re-serialize. That could get tricky.
Also, and this probably isn't as important to a small application using an embedded database, but it's easier to modify the database outside of the application if the object isn't a BLOB. Not to mention the queries you'll be able to write with the separate table. For example, how might someone calculate the number of notes that are attached to a task? If it's separated out in the database, it's a simple query.
Just my two cents.
Related
For example, Here is the data type,
User {
String name;
String lastName;
}
Now I'm storing this User class with Room and retrieving the list of all users with Dao
LiveData<List<User>> getAllUsers();
Now I want to add the Delete User functionality to it. And I also wanted to store all the deleted users in a separate table so that I can show them in a different place/Activity.
But I couldn't able to figure out what could be the better approach for this. Since the data type of deleted user is the same as User.
One way is to add an additional field into the User class and filter the list every time before displaying
User {
String name;
String lastName;
boolean deleted = false;
}
I just have to change the boolean value deleted when I delete the User object.
But I don't want to filter the list every time instead I want to store this deleted user in a separate table and this way I can retrieve the list of User and list of Deleted User much faster and save the time while filtering.
So how can I do this or is this the right way of achieving this delete functionality?
I guess there are two questions:
How to store two tables in Room Persistence Library of same data Type?
This question from your post' title
and
What is better - to store two tables or just one but to filter it?
I think this is the core of your question.
So,
1. How to store two tables in Room Persistence Library of same data Type?
The answer is simple. You should make two separate Room's entities, two separate DAO's for them (though you can use just one) and after deleting user you should in transaction delete it from one table and insert into another.
2. What is better - to store two tables or just one but to filter it?.
Of course, the answer is opinionated. You should consider all PROs and CONTRAs and make your choice.
Why to filter is better?
User and DeletedUser essentially are the same, they just has different status.
You don't need to duplicate the same fields in two tables. Otherwise you (and another developers who will maintain your app) should hold in mind that each change in User table (adding some field etc.) should be followed by the same changes in DeletedUser.
As usual Room's entities have id-s and they could be used in another entities as foreign key. As such you can't use User's id as foreign key, since after deleting it from User you can lose data in entities that are attached to it. In general, if User table is planned to have connections with another tables in app, then using separate DeletedUser is a bad way.
Why two tables is better?
As you've mentioned the filtered query might be slower. How much slower? That depends. For small tables (with up to 1,000 rows or even 10,000 rows) I guess you may not to see the difference. Still if you have some edge-case (enormous table) and struggle for performance really makes sense, you can choose that way.
P.S. Using Livedata in Room filtered result will be updated for you. So if you decide to use single table and one of the users in the table turns into delete-state, result will be updated without any special refresh-calls.
I am currently developing a health app on android.
There would be a need to store personal data like gender, height and settings for app.
I plan to create a table with different columns.
My question is about creating the table with default values and editing the database.
My first thought is to create table and add a row with default values in onCreate().
But it seems to be wrong usage of onCreate() as i see multiple examples that only db.execSQL(SQL_CREATE_ENTRIES) is onCreate().
Second thought is to make use of DEFAULT in SQL but still i have to find somewhere to run add row.
What's the good practice to do so?
About editing those data, i put multiple public get and set function in sqliteopenhelper class.
Is it right to do so?
As multiple tables are created, the sqliteopenhelper class seems to be a bit messy since there are a lot of functions.
Welcome to any suggestions and criticism.
Thanks all.
Does your data really need an entire SQL Database? From your question I understand that you store data (gender, height) for a single user. If it so, you can use Android's SharedPreferences. SharedPreferences are a simple Key-Value store system where you have functions for both setting and getting you values based on a key (similar to a single SQL Table with two columns, key and value).
Iam following this tutorial :- http://azure.microsoft.com/en-us/documentation/articles/partner-xamarin-mobile-services-android-get-started/
to use mobile services with Azure.
Currently when I add items to the table, the data gets stored randomly. I want it to store the items in a such a manner that the latest record comes at the top of the list.
How can I do it?
Thanks
From the looks of that tutorial, the table in the database which has been created is using a UniqueIdentifier (equivalent to a GUID in code) as the Id. (presumably PK).
GUIDs are generated "randomly" and don't sort nicely in chronologically created order. It's not that the data is getting stored randomly. The Guid is randomly generated, and the table/index stores it in exactly the correct place based on it's Id value.
At the end of the day, for such a small amount of information, the order it's stored in the table isn't really important so long as you can retrieve it in the order you want.
From the looks of the demo, the data table also has a _createdAt column on each data entity. Have a look in the TodoItem & TodoAdapter code to find where it actually executes the query against the data store. It should be quite easy to add an OrderBy to that call to force the returned order to sort by _createdAt
I'm working on an Android app for homework management. I'm a senior in college, so my experience on larger projects is very limited, but I'd like to design all parts of this app well instead of just throwing something together. This includes the way data is stored.
We have two main objects/entities: Task and Subject. Even if someone uses the app for the whole time they're in college and never deletes anything, I'm guessing there would be a maximum of a few thousand tasks and a couple hundred subjects (not all subjects would be shown at once). The initial version of the app won't sync data with a server, but this is a definite possibility in the future, so I'd like to design with that in mind. We might also have an option for users to send tasks to each other.
Here are my questions:
Would a SQLite database be the best option for storing the amount of data we're likely to have, or would something like serializing it to XML or JSON then loading it into memory when the app starts work?
I'm used to thinking in terms of objects. This means that if I use a database and it has a Task table and a Subject table, my first instinct is to convert each database table row into a corresponding object for viewing/editing. (The objects' setters would contain validation logic.) Is this a good/helpful/necessary way to think? If not, what is the alternative?
Thanks for your help!
This question is broad so may comments below may not be 100% correct as I don't have all the information about your system.
SQLite is better suited for storing thousands of records than files (be it JSON or XML). This is especially true if your data is not static, i.e. will be changed during the usage of your app (which is the case for you, I believe). You can take advantage of existing functionality for records inserts, updates, deletions, using indexes, etc.
Yes, you generally create objects similar to your database. But you don't usually need to convert each and every record from the database into your objects. You usually query the database for a limited number of objects, depending on what you want to show in the UI. Of course, if you need to show all, let's say, tasks, you need to get them all.
1. Would a SQLite database be the best option for storing the amount of data we're likely to have, or would something like serializing it to XML or JSON then loading it into memory when the app starts work?
Yes SQlite will be the option for you.It will give you a structured format and in future if you want to access data from remote end the same structure of tables can be used without much change in the code.
2. I'm used to thinking in terms of objects. This means that if I use a database and it has a Task table and a Subject table, my first instinct is to convert each database table row into a corresponding object for viewing/editing. (The objects' setters would contain validation logic.) Is this a good/helpful/necessary way to think? If not, what is the alternative?
you can simply execute queries to manipulate data.
But dont forget to encryt your database if you storing it in mobile itself.
I am trying to create multiple database tables in android where each table will represent an account. I am struggling to get more then one table per database
Would anyone have any sample code they could show me? Or any suggestions?
Thanks
I don't know anything about your app, but the way you're designing your database schema sounds a little questionable. Does creating a table for every account (whatever an "account" might be) really make the most sense?
Regardless, creating tables in SQLite is pretty straightforward. In your SQLiteOpenHelper class, you can call db.execSQL(CREATE_TABLE_STATEMENT) to create a table, where CREATE_TABLE_STATEMENT is your SQL statement for a particular table. You can call this for every table you need created. This is typically going to be called in your SqliteOpenHelper's onCreate method when the database is initialized, but you can call it outside of the helper as well.
If you are going to use a fair amount of tables and data, including a prepopulated database in your assets folder is another way to go.
When I started to use databases on android I found this very helful.
http://developer.android.com/resources/tutorials/notepad/index.html
ps now that you mentioned that there are only 2-3 accounts, creating one table/account sounds much more reasonable than first expected.
But it really depends on what you are planning to do with the data and where your performance requirements are. One could even use one single table or as well multiple tables for each (fixed) type of transaction - if the data for transaction types have very different structure.
Creating database table in Android is pretty straghtforward:
db.execSQL(CREATE_TABLE_STATEMENT);
where db is SQLiteDatabase object and CREATE_TABLE_STATEMENT is your create table sql statement
As in your question you did not explain clearly the requirement of your app, but I can see a few cons in your approach of creating one table for each user
If there are many users created, u will have many tables in ur database
If later on you have some information, settings that would be shared across some users or all user, you will have to replicate them in every user single table.
My recommendation would be you have one table for users, and another table for transactions with one column is user_id to link back to the user table. It would be easier to expand or maintain your database later.
Hope it helps :)