Sqlite Database Optimization, replacing deleted entries - android

I created a database in android for my App with columns ID, channels, name
I can create fine and everything works.
My ids are attached to commands specific to that channel.
When I have 15 channels and I go to delete channel 4, it creates channel 16 instead of replacing channel 4 first.
Is there a method that I can use that would search for "empty" RowIds first before adding the values?

If the ID column is Auto-Increment then you can't replace 4. The column value is advancing by 1 with each insert.
you can remove the auto-increment take care of the IDs your self. but for that you'll have to search for the missing number in each insert (not very efficient). maybe you can also save the deleted IDs in some auxiliary table. That can help you avoid the lookup. But not sure if it's worth it...

a row will be updated if a unique constraint violation occurs for the insert. So the ID column in your example would need to have a PRIMARY KEY constraint in the database schema for the row to be updated
contentValue c;
SQLiteDatabase db=getWritableDatabase();
db.replace("table_name", null, c);

Related

How exactly SQLite database update primary key id?

Suppose I have a table contacts
id Name Contact_No
-----------------------------------------
1 abc 12345
2 lmn 56784
3 pqr 83654
4 uvw 17637
5 xyz 98345
If I delete row 3 from database, what would be the id of rows following the deleted row?
And if I update row 4, will it be given a new id or the id of row 4 will remain same after updating database?
What is the difference between autoincrement and autoincrement not null? Official documentation says that it will degrade the performance and database will work slow. Is it mandatory to write it along with integer primary key?
I have read many stackoverflow answers and also read SQLite Official Documentation but I couldn't get it.
Assuming id is the name of your INTEGER PRIMARY KEY column.
If you update a row, it will never change its id, since it is still the same row. (that's the whole point of update).
Regarding the creation of new ids, everything is in the doc your linked:
Relevant sections :
Without AUTOINCREMENT
On an INSERT, if the ROWID or INTEGER PRIMARY KEY column is not explicitly given a value, then it will be filled automatically with an unused integer, usually the one more than the largest ROWID currently in use.
There is no strict rule, it can be implementation dependent. Usually it will be equal to select max(id)+1. In you case 6, but if you delete row 5, the id 5 can be reused. (But don't rely on this).
With AUTOINCREMENT
If a column has the type INTEGER PRIMARY KEY AUTOINCREMENT (...) the ROWID chosen for the new row is at least one larger than the largest ROWID that has ever before existed in that same table. If the table has never before contained any data, then a ROWID of 1 is used.
Adding NOT NULL to AUTOINCREMENT is therefore pointless.
In your case, the next id is 6, no matter how many rows you delete before that.
If you just use integer primary key then any insert will use the current maximum ROWID (for which id is effectively an alias) plus one. Thus deleting row 3 and inserting a new row will use 6. However, if you were to delete row 5 (leaving the maximum ROWID at 4) a newly-inserted row would get an id of 5.
If you care about id's not being reused, then you need autoincrement. The reason this is slower (and advised against unless you need it) is that the largest ever value is kept in an internal table. Inserts then have to read/update this internal table as part of their operation. If autoincrement was used, then an insert after deleting either 3 or 5 would create a row with id 6.
A normal update of row 4 would leave the id the same, unless you used insert or replace which effectively deletes the row and inserts a new one. Such an insert would follow the same rules as above.

Android SQLite insert 2 rows with same id

I insert 2 records in the table at the same time, which has the ID field AUTOINCREMENT. can be assigned to the second record id before? so that when I delete a record using the id are deleted both?
If want two different rows with the same ID and the ID field has AUTOINCREMENT enabled you cannot give them the same ID. That'd be a bad idea for several reasons.
I think what you should rather do is rethink your database and/or table structure. I'd propose you put the rows in different tables and make one of the rows depend on the other. Then you can make them have the same ID in their tables and have one ID to delete both rows in the different tables.

Android SQLite database removing a record

I am now building an android phone book app and employing the method of SQLite database to store records. In my database, there is _id column which is a primary key and will increase automatically. A strange thing is that when I delete records, the removed _id number is not re-used.
E.g. Originally the database is
_id name
1 Peter
2 Mary
After deleting 2 (Mary), when I add a new record (John), I found that John is placed with an id = 3.
So my question is: is Mary still there? Is it just flagged to be "deleted" but not really deleted? If so, would this be a wastage of memory and should I do something to remove it completely?
The row is deleted. Generating the auto increment ID is implementation specific. It is upto to the autoincrement algorithm to assign the new id or reuse the deleted ID. Please refer sqlite tutorial : http://sqlite.org/autoinc.html
This is a quote in the mentioned in above link:
With AUTOINCREMENT, rows with automatically selected ROWIDs are guaranteed to have ROWIDs that have never been used before by the same table in the same database. And the automatically generated ROWIDs are guaranteed to be monotonically increasing.
Note that "monotonically increasing" does not imply that the ROWID always increases by exactly one. One is the usual increment. However, if an insert fails due to (for example) a uniqueness constraint, the ROWID of the failed insertion attempt might not be reused on subsequent inserts, resulting in gaps in the ROWID sequence. AUTOINCREMENT guarantees that automatically chosen ROWIDs will be increasing but not that they will be sequential.
No, after deleting row id 2, the record is completely deleted. The incrementing counter will continue from where it left off, so it is correct to see John with an id of 3.
You need to make your ID column an INT primary key and add auto increment to it.

How do I keep my SQLite Database organized? Android

Say my SQLite Databate has 2 columns, the first being an auto-incrementing ID and the 2nd being some string. Say right now it's
1 random
2 jellybean
3 ImTired
if I were to delete entry 2, it would then be
1 random
3 ImTired
What I want is a way to make it so when you delete entry 2, it turns it into
1 random
2 ImTired
I thought about updating the entries to shift them all down one and delete the last one, but even if it worked(in my case, it deleted all of my entries, but whatever...), and even if I did get it to
1 random
2 ImTired
the next time I create a new entry, it'll be entry 4. I don't think this necessary to my app, but it seriously bugs me.
The ID column on your DB is working as a Primary Key, which is a column or group of columns used to uniquely identify a row. Once you set a Primary Key on a row you shouldn't change it, else you risk losing the consistency of the DB. For instance, suppose you later create another table that references the rows in your first table. That reference will be made using the Primary Key, and if you later change it your data won't make sense anymore.
If you wanted the ID column to keep changing just to reflect the number of rows in your table you can solve that problem with other methods. For instance. SQL offers a COUNT operator that will return the number of rows in your table:
SELECT COUNT(*) FROM Table_name;

Conflict resolution in Android's SQLiteDatabase

How does Android's SQLite library resolve conflicts if I insert duplicate rows? I am building my app for API level 7, which unfortunately does not have the SQLiteDatabase.insertOnConflict() method that was included starting in API level 8.
You can specify a UNIQUE index in the table definition which will allow rows to be REPLACED:
CREATE TABLE mytable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
UNIQUE (id) ON CONFLICT REPLACE
)
If a row an INSERT or UPDATE statement tries to add a row with an id which already exists, the existing row is replaced with the new one.
There's a ON CONFLICT clause in SQLite that you can say INSERT INTO ... ON CONFLICT....
Read the documentation please. http://www.sqlite.org/lang_conflict.html
By default i you have unique index exception will be thrown on duplicated index insert. Common solution is check record existence before execute insert - pseudo-code:
select * from people where name = 'Smith';
//if resultset is empty then perform insert
insert into people values 'Smith'

Categories

Resources