Well I have a database with few tables and I do not have any id. The fake id that I am using is datetime field (yyyy-mm-dd-hh-MM-ss) and this field is string. It works perfectly and it is great for sorting...BUT it is slow :), very slow I mean I do a very big mistake my 'primary' key is string, and the connection between the tables is made according this filed. That is because the datetime field is the only unique filed I had...
How should I make this faster, I mean it would be very easy if this is SQL database I would create foreign key and that it.
someone might say 'why don't you just use integer', well I have a lot of creation and deletions and if I use int it will be very complicated to keep the tables ordered and because of the frequent deletions the ids will look like 1,22,55,79...
I mean I do not know what is the right way to do it , that is why I am asking
Related
Not sure if this has already been answered, and this is kind of a dumb question, but I'm kinda new to using SQL in android and I've made a simple task app using the language. In the app, I added a feature to delete all tasks. When I create a new one, the primary key keeps counting up. Now, there's nothing wrong with the app or the code or anything, but if all the tasks are deleted, should I reset the primary key, or is it bad practice to do so? If not, will it ever become large enough to provoke a crash?
I would generally keep it increment because it can simplify certain things like database backup/restores, and replication to other database nodes. It makes things more predictable when your rows are always unique by id.
From the SQLite documentation:
Except for WITHOUT ROWID tables, all rows within SQLite tables have a 64-bit signed integer key that uniquely identifies the row within its table.
How big is the largest 64 bit number? It is 9,223,372,036,854,775,807. This number is so large, that it is probably doubtful you will ever exceed it, unless you are doing very frequent and massive inserts. Actually, you might run out of storage space before you insert so many rows to even come close to this number.
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
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.
My app needs to get synced with other app users (on there own devices). I also want to support offline editing, that are synchronized to the other collaborative users when the user gets connected to the internet.
So the User A changes (while he is offline) some data (in ohter words he would update database entries) or add new records to the database. When User A gets connected to the internet, all changes and new records are delivered to the other collaborative Users. So User B will get the changes/updates and can insert/update them into User Bs local device database.
But I need to ensure that the ids of the database entries are unique along the whole system. Therefore I need to use something like UUID.
My question: Is it a bad idea to use a UUID (String / Varchar) as primary key in a android sqlite database table instead of an integer that would be auto incremented?
I guess there would be performance issues by using strings (a UUID has 36 characters) as primary key.
I guess indexing uuids instead of integers takes longer (comparing string vs. comparing integers). I also guess that when Im using UUID, every time a new database record/entry has been inserted the database needs to reindex the primary key column, since they primary key index is not in a sorted order anymore (which would be when I would use integer auto increment primary key, because every future record is added at the end, because the new auto incremented primary key is always the greatest number so far, so the index will automatically be in sorted order). What i also need to do is JOINS over 2 - 3 tables. I also guess that comparing strings on JOINS instead of integer would slow down the database query.
However I cant see any other possibility to implement such a collaborative syncing system, so I must use UUID, right?
Another possibility would be to use a integer auto increment primary key and to use a second column uuid. So to work on the users local device, i would use this primary key (integer) for JOINS etc., while I would use the uuid column for syncing with the other users.
What do you guys think about that approach or is it in your opinion to much work, since you wont expect a big significant performance issue by ussing UUID directly as primary key?
Any other suggestions?
Is it a bad idea to use a UUID (String / Varchar) as primary key in a android sqlite database table instead of an integer that would be auto incremented?
The only for-certain problem that I can think of is that you will not be able to use CursorAdapter and its subclasses for displaying the results of queries on that table. CursorAdapter requires a unique integer _id column in the Cursor, and presumably you will not have one of those. You would have to create your own adapter, perhaps extending BaseAdapter, that handles it.
I guess there would be performance issues by using strings (a UUID has 36 characters) as primary key.
Possibly, but I will be somewhat surprised if it turns into a material problem on device-sized databases.
However I cant see any other possibility to implement such a collaborative syncing system, so I must use UUID, right?
You need some sort of UUID for your network protocol. Presumably, you will need that UUID in your database. Whether that UUID needs to be the primary key of a table, I can't say, because I don't know your schema.
Another possibility would be to use a integer auto increment primary key and to use a second column uuid. So to work on the users local device, i would use this primary key (integer) for JOINS etc., while I would use the uuid column for syncing with the other users.
Correct. You would have a UUID->local integer ID mapping table, use the UUIDs in your network protocol, and keep the local database mostly using the local integer IDs. Whether or not this will be a significant performance improvement (particularly given the increased database schema complexity), I can't say.
What do you guys think about that approach or is it in your opinion to much work, since you wont expect a big significant performance issue by ussing UUID directly as primary key?
IMHO, either run some performance tests so you get some concrete comparable data, or only worry about it if your database I/O seems sluggish.
One set of performance results for UUIDs as binary and text can be found in somewhat related UUID/SQLite question: https://stackoverflow.com/a/11337522/3103448
Per the results, both binary and string UUIDs can be efficient in SQLite for Create and Query when indexed. A separate trade-off is whether a human readable string is preferred to the smaller data size of binary file size.
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.