This is a theoretical question. I'm creating an app which downloads a list of events around the city from a MySQL DB and displays them in a RecyclerView.
Users should be able to select an event and add to their own list of events they are interested in. At that point, I'm not sure what are the best practices.
So when a user selects an event item from the RecyclerView, what's the best solution, I can only think of that:
Method 1: Add the chosen event to a List<Event> which is then saved in SharedPreferences as a JSON string. Upload the list to the online MySQL DB at a later point.
Any other suggestions?
About the query:
Also, could you give me a pointer on how to do the complex query to the database.
I have these tables Events,Accounts, GuestList. So, GuestList holds the ID of the event and of the account so that I keep track of which events a specific user wants to attend. I'm guessing I'd have to use some kind of JOIN?
You can see that if I want to get the data to display (the event information only for the user who is requesting it) I'd need to first query the GuestList table to get the list of events. Then query the Events table to get the information for all the events with the IDs we grabbed a moment ago. An example SQL statement anyone?
When user select event from your RecyclerView that he wants to attend, you should pass a query to the database storing the event to the user’s private event list. The optimal way is doing it asynchronously…
It seems that you have many to many relationship between your models.
Events, Account and the middle table is GuestList that stores the relations between your models. The best practice is to name it Events_Account and this convension means that this is the connection table.
The examples I will show are on MS SQL but they are pretty much the same and the concept is same too.
So basing on your models description the relations should be looking as something like that.
You can select your data using a basic query like this
When a user wants to grab info for a particular event you can simply add another where clause like this
You can pass a parameters in your method and do it with a pure query. Let's pretend that these are your variables #CurrentUserId and #Particular event. You can pass a values into the method and use them to select your item
This is the WORST practice – to use it as a pure query. The PHP as other languages are giving you prerequisites to shoot yourself in the leg. Using a pure db query in your code and relaying that the user will use properly the application is totally wrong. This way the user can simply send a SQL injection and dump your database. Here comes the ORM /Object Relational Mapping/ Like EntityFramework for .NET. The PHP equivalent is Propelorm. It maps your database and makes you access to the object very easy with the fluent syntax.
The query and also the ORM that is very simpler to use and saves you from SQL injection will both be transpiled into SQL language. The query that they will execute in SQL will be close to the one on the pictures but a bit uglier for a human. Don't worry about the query it will be very fact because this operations are executed on the database level and they will be very fast.
I hope that this will be useful and enough for you and solves your theoretical problem
Related
In my chat application, I store the participants of a chat as their UIDs in a Map so I can so I can do queries like this:
.whereEqualTo("participantUIDs.$currentUserUid", true)
.whereEqualTo("participantUIDs.$partnerUid", true)
The problem is when I try to use this with orderBy
.whereEqualTo("participantUIDs.$currentUserUid", true)
.orderBy("lastMessageSentTimestamp")
I have to create a custom index. But this index will contain that specific user UID and I can't create an index for every user in my app. How can I circumvent this problem?
You can order the documents on the client after an unordered query. This should not be very taxing on the client app when the number of documents is less than 10,000.
Regarding:
I can't create an index for every user in my app.
That's definitely not an option, as there are some limitations when it comes to Cloud Firestore indexes:
https://firebase.google.com/docs/firestore/quotas#indexes
However, even if you manage to stay below these limits, that's not an option to manually create an index for each and every user that joins your app.
In my opinion, for your particular use-case, you should consider augmenting your data structure to allow a reverse lookup. Meaning that you should create a participantUIDs collection where you should keep the lists for each user. This technique is called denormalization and is a common practice when it comes to NoSQL databases like Cloud Firestore or Firebase Realtime Database.
But remember, there is "no perfect database structure":
What is the correct way to structure this kind of data in Firestore?
It's a little old, but I think this video might also help:
https://www.youtube.com/watch?v=u3KwKQddPoo
More info regarding why you need an index:
Why does this firestore query require an index?
P.S. You can also rely on Firebase Realtime Database when Cloud Firestore may become a little expensive. Both work really well together.
Info:
Array or Subcollection for storing events user uploaded
I've written for the beginning basic, very simple app in Android Studio which just fetches data from various REST methods and presents them in a table.
However, I would like to extend the functionality and offer user possibility of filtering data, for example, to get data from a different time. Let's assume, the user clicks and chooses data from Monday to Tuesday, fast SQL and data are refreshed, then user chooses data only from the previous week, fast SQL and data are refreshed.
I would like to ask first - is it better to load sometimes very huge amount of data and then somehow just filtering them or to execute every time REST method and just refresh grid?
For the time being, the user chooses an option from the menu, I call the REST method and present data in the second activity. Now I would like to execute almost the same SQL, but with different WHERE clause, depending on the user what he wants to see.
Should I call the whole mechanism to execute the REST method or is there some library which allows me to modify SQL and "in the fly" execute REST method with different parameters?
It depends on how large the original data is.
If the data is really big then the best option is to add filtering in the request and receive the filtered data from your backend.
In case your data is pretty much static and would probably stay the same you can fetch it all and save it to your local DB and then query it locally
but if the data is not that big you should just request it all
Anyway you should read about Pagination
The Android team also created a paging library as part of the architecture components
Assume that I want to update dirty flags of some contacts linked to a group.
To do this,
From 'data' table, records having the group ID should be queried.
Should update using contact ID in the fetched records.
But if I can use SQL, it can be done with one SQL statement.
Is it possible?
Thanks in advance.
No, I don't think so.
See, Android API doesn't let you access the SQLite database behind the contacts (although it is there) but rather abstracts data access by means of ContentProviders (And there's a good reason for that: giving developers access to the SQLite db would be way too insecure -- any app with proper permissions could e.g. drop the contact tables and thus cause major malfunctions of other apps)
It's not much more complex to run update statements on those though (well, apart from the fact that SQL statements are kind of broken down into methods and parameters), the ContentProvider class has .update() method for just that, the tricky part is the WHERE part of the call, you'll have to take a good look at the ContactsContract class.
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 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.