I have a bit of a theoretical question for which there is no code yet as I am still just in the thinking stage. I want to update an app to allow users to share their data with others through DropBox Datastore or something like that. However, when a user creates data which get populated into multiple sqlite tables on the device, each table has an auto-incremental integer as a primary key that is used as a foreign key in other tables to link the data.
If there is more than one user actually creating the data and sharing it then the primary key columns are obviously going to be an issue. If I download the data and store it locally I obviously can't insert user 1's key value in user 2's data table, firstly because of the auto-increment and secondly because user 2 might already have data that is not shared saved with that key value.
I have thought about a few options but nothing is particularly appealing or robust. I was thinking about creating a UUID to identify the device, that value would have to be stored in each of the tables and the primary key would be a combination of that column and the current primary key integer which would obviously have to have the auto-increment removed. So to pick up all related data from each table the id column and UUID column would both have to be used.
I feel like there must be a more robust method of achieving this though, any one have any better suggestions?
If I'm understanding well you need some sort centralised database in the cloud to communicate with your local app, is that right?
A client should never create the ids for such a system. A usual practice on these cases is to always have a remote id which is created by your DB in the cloud, and whenever you don't have this value yet, you can have a fallback value (local id created locally - which is different from the remote one).
So, to illustrate my words we could set the following example. Your app stores messages in database. Say you create messages with a local id 1,2,3. Those ids will never be meant to be unique in your central database in the cloud. Instead, you'd just use them as a local fallback. As soon as you can send those 3 messages to your centralised database, it'll give them 3 new remote ids you'll use for unique means (ie.: 35, 46, 54).
Note that when you have multiple requesters/users accessing one same database there's not such way to assure uniqueness unless you follow the explained approach, or you query a certain number of unique ids in advance and on demand to your database in the cloud.
Keep in mind, that the actual truth can be only delivered by the databases in your servers.
Related
I have an Android app and i want to allow my users to sync their local sqlite db with server.Since i have thousands of user's how should i set up my MySql database on server?As i see it there are two approaches,
1) One database per user plus one database to store user's credentials.Is this even possible since there will be thousands of different databases on server?
2) One database that holds all user's data.I was thinking i could add a field (user_id) on each table that identifies a user.I don't like though the idea that all user's data will be on the same table!!!
What's the best approach for my case?Is there something different i could try?
One database that holds all user's data.I was thinking i could add a field (user_id) on each table that identifies a user.I don't like though the idea that all user's data will be on the same table!!!
I'm using Virgil Dobjanschi's Option B (from this talk: http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html) to implement a web service on my Android App to connect to a Google Cloud Endpoints RESTful service (hence, my URLs are abstracted over).
The local SQLite database requires a Primary key (which must be called _id so it can link with a ListView). The AppEngine service also requires a unique ID per record. The resources in the service are shared between multiple clients, so their IDs need to be maintained unique on the server. The resource ID is generated, derived from two other IDs, and in the form of a String.
By design, these resources are never created locally on the Android app, they are only read and updated - creation and deletion happens elsewhere, and then those created are sent via Google Cloud Messaging, complete with their REST Ids, and inserted into the SQLite table.
If I ever do create them locally, I'll be able to generate the unique ID from the REST resource locally as well.
Should I have the ID on the SQLite database be a separate unique id, maintained locally, and store the REST id in the record, or should I set the SQLite ID to be the same as the REST id?
ie:
My REST Resources are of the form:
String id; // unique, derived from two other ids
String data;
My SQLite options are:
create table myResource (
_id INTEGER PRIMARY KEY AUTOINCREMEMT,
restId TEXT,
data TEXT);
Or:
create table myResource (
_id TEXT PRIMARY KEY,
data TEXT);
In the first option, I could make restId UNIQUE as well. I'm leaning towards the second option, but am wondering if I'll run into unforeseen problems with this approach.
I also have another similar situation with some different resources where the REST key is a Long rather than a String, but I still question whether I should maintain a local primary key separate to the REST resource ID.
It seems that it's best to use Integers for the _id field in SQLite, which means that they necessarily won't match the String Keys in AppEngine.
The http://developer.android.com/reference/android/content/ContentUris.html refers to id as "A unique numeric identifier", and provides helper methods that require it to be a long.
It may be possible to work around this, but given that this assumption is built in to ContentUris, I expect that it will also be built in elsewhere, so it would be easier to do this with numeric ids kept internal to the App, and enforce uniqueness of the AppEngine keys separately.
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 am currently using PHPmyadmin to store data in my mySQL database. The android application I am developing requires the user to select some data and this data along with its attributes need to be stored in my mySQL database. I know I have to create a unique table for every user who downloads my application but how do I go about doing this without having access to the program which the user downloads ?
For eg: let us say there are two phones which download my application. I would want to create two tables in my database which the particular phone knows and can access
Creating one table for every user is a terrible approach. Instead you should create a users table, with a unique ID set to auto_increment, to generate those unique IDs. Then use separate tables to store the data you might need, referencing the user ID from the users table.
It might sound a little confusing, but there are lots of good reads about this on the Internet.
You can generate unique user id in php using uniqid(”, true) function.
I have an application that syncs with a web server. When I update I want the row ID's to match with the ones in the web server, because other data depends on correct mapping of row ID's. I have thought of just clearing the table each time, but I don't think that is a efficient way especially when the data gets very large. What is an efficient method for this?
I'll make it easy for you:
1) Add an extra column to your android db table, lets call it web server id.
2) When you first create the android table, insert the web server row id into this column.
3) Whenever you synch with the server, use that id to find the proper web server row to synch with.
This is all Database 101 stuff. You should really read up on foreign keys. It is clear the relationship is preserved even when data is changed, unless you are changing the key fields. However, the key fields should never be altered so the relationship will always be preserved.