What is the best practise in choosing a table's primary key - android

I used to create a column called 'id' which is auto incremented in any table I create. While in some cases I found that this column is useless while another column like 'citizen_ssn' is a better candidate to be the primary key.
So, what is the best practice in choosing the table's primary key ?
Should I use what will fit the need or create the auto-increamented column or another opinion ?

Any attribute which is unique and not null can be used as a primary key. Generally id is used as a primary key by many developers. But there's no such rule except mentioned above.

What is a Primary Key?
Apart from Auto-Incrementing it, a primary key is used to Identify a row. As every row is unique, so is the Primary key. Two or more rows with a column number n can have the same value, let's say "Australia" but the column with Primary Key constraint will have the unique value.
So, it's not important to use the id column as a primary key.
One can use phoneNumber as a PK too.
Depends on the usage.
I hope I've made myself clear.

In Realm there is no real reason to have an auto-increment primary key. (although if your server returns primary key info, then it's useful to know that you're referring to the same object).
In SQLite (or any relational database) the reason you need them is that that is the only way you can link two objects together (through JOINs) - for example, a many-many relationship is done with a Join Table that contains the primary key of both linked tables as a foreign key.
In Realm, you can link objects together as a field like private OtherObject otherObject;, and many relation as private RealmList<OtherObject> otherObjects. So you don't need primary key to create relationship.
What you might need them for in Realm is if you want to use insertOrUpdate() method to update an existing object in Realm by its primary key, overwriting it with an unmanaged object. You can also edit objects by calling the managed object's setters, so this is not entirely necessary.

Related

Get/Return the autogenerated id (as primary key) generated by Android Room database

For an android room interface, I want to get the autogenerated id (as primary key of a record just inserted), so that I can put it in the object without executing a select after insert, where the select might return the wrong record if there is no other unique attribute, or set of attributes for those record types.
For example, for 2 people having the same name being inserted into the same table. You might say generate a composite key to make a unique set. However that might involve the addition of new fields that are otherwise not required.
I've seen various links, including those below. Some mention that it is the row id that is returned if the insert method is declared to return integer (or long), and succeeds.
However it is my understanding that the row id cannot be assumed to be the same as the primary key. (Refer Rowid after Insert in Room).
I cannot comment on any posts because I don't have enough reputation points.
I appreciate any comments regarding what might be a good/typical approach to this problem.
These are the posts I have looked upon:
Android Room - Get the id of new inserted row with auto-generate
https://developer.android.com/training/data-storage/room/accessing-data
https://commonsware.com/AndroidArch/previews/the-dao-of-entities
Late answer just for anyone seeing this question in the future
from SQLite docs it says :
The PRIMARY KEY of a rowid table (if there is one) is usually not the
true primary key for the table, in the sense that it is not the unique
key used by the underlying B-tree storage engine. The exception to
this rule is when the rowid table declares an INTEGER PRIMARY KEY. In
the exception, the INTEGER PRIMARY KEY becomes an alias for the rowid.
therefore it's correct to assume that the rowId returned by insert query is the same as the autoincremented-primary-key

Do you need both primary key AND autoincrement for creating table in SQLite?

Or can you just use one or the other? I'd like to avoid redundancy while ensuring uniqueness by just using PRIMARY KEY but am wondering whether the added rows will AUTOINCREMENT by default.
Yes, added rows will have automatically generated values for primary keys if you don't supply an explicit non-null value yourself. The algorithm for generating such values is slightly different with and without AUTOINCREMENT keyword.

Does sqlite "insert or replace" work with AUTOINCREMENT primary key?

I have a database in which i have created one table with name "SectionDetails".
In this table i have set "id" as a primary key with AUTOINCREMENT property.And i am inserting my data into this table.
However, i came to the scenario where i need to check if record i am inserting is already present or not(if record is present then replace it with same values or skip it,And if record is not present then insert new one ).
But when i tried to insert record with same column values, it increases the primary key and insert the same row again instead of replacing.
So, my question is-
Does sqlite "insert or replace" works with AUTOINCREMENT primary key?
I am using following query:
insert or replace into SectionDetails(Name,Month,Title,Url)values('Deepak',"August","None","www.dd619.com")
here column "id" is not appearing because its a primary key with AUTOINCREMENT property.
You will need to add some unique constraints to your other columns to make this work and even then you will have your IDs change.
insert or replace is really an insert with on conflict replace conflict resolution strategy. That is, when the insert would violate some constraint, all conflicting rows are first deleted and the insert takes place only then. The autoincrement mechanism will then generate a new ID value for you.
For more information: http://www.sqlite.org/lang_conflict.html
Short answer: no it does not.
The "insert or replace" only works well when you also specify the primary key. With the autoincrement in a setup that you describe, this cannot work.
Probably the quickest way to do that is by creating a custom insert/update method for your use case.

Implementing Content Provider: compound primary key

I'm implementing my own Content Provider because I'm gonna synchronize my database with a server. My data is stored in a SQLiteDatabase, and some of my tables have a compound primary key (2 columns, each one a foreign key to another table).
I just started working with Content Providers and I don't know much how they work, but as I could see googling a bit I need to define the name of the tables and their primary key:
uriMatcher.addURI(PROVIDER_NAME, "books", BOOKS);
uriMatcher.addURI(PROVIDER_NAME, "books/#", BOOK_ID);
As I understand it, if I use the URI .../books/1 it would access the Book with primary key "1". The thing is, does it work with a compund primary key? If it does, how would the URI be?
Thank you!
I'm implementing my own Content Provider because I'm gonna synchronize my database with a server.
You do not need to use a ContentProvider to synchronize a database with a server.
The thing is, does it work with a compund primary key?
Not readily. Quoting the docs:
Table data should always have a "primary key" column that the provider maintains as a unique numeric value for each row.
You could to add a separate column (typically named _id) that you will use for the ContentProvider as the primary key. If you use an AUTOINCREMENT column, you will not ever have to assign a value yourself, meaning that you can ignore this column in pretty much all respects except where ContentProvider wants an instance Uri.
You are welcome to attempt to avoid this, and use a Uri that looks like content://your.authority.goes.here/table/key1/key2 or something like that. However, it will not work with CursorAdapter and various other places in the framework may assume the numeric ID pattern.

Android composite primary key?

Can anyone tell me how to declare a composite primary key in Android 1.6 which includes an autoincrement _id column? I'm not sure of the syntax. I've ended up just enforcing it in Java when I try to add values (where registrationNumber + date has to be unique in the table):
Cursor fuelUpsCursor = getFuelUps(registrationNumber, date);
if(!fuelUpsCursor.moveToNext())
{
//add registrationNumber and date
}
I don't really need the _id column but it can make life tricky if tables don't have one.
Cheers,
Barry
Your question does not make much sense. Your subject line asks for a "composite foreign key", your first sentence asks for a "composite primary key" with an AUTOINCREMENT that your sample code then ignores.
I am going to interpret your question this way: You want an _ID INTEGER PRIMARY KEY AUTOINCREMENT column in your table to be able to use Android's CursorAdapter, but you want to also make sure that the combination of two other columns is unique.
In that case, I think that you want to use a UNIQUE constraint:
Multiple Unique Columns in SQLite
SQLite table constraint - unique on multiple columns
http://sqlite.org/lang_createtable.html

Categories

Resources