I am creating a db for my android app which requires different tables for different types of users. Basically, if user type A logs in he will use Table A, user type B logs in he will use Table B and similarly Table C.
Should I go ahead and create 3 tables and use only the table which the user type has logged in? Would this have any significant memory implications (size of the db)? That is, if the table doesn't contain data, would the sqlite db still allocate some space (other than for definitions of the columns).
The other way would be to check the user type and dynamically create the table at runtime once user logs in. I prefer the first method if there isn't much space used.
Any pointers or suggestions would be very useful.
The SQLite DB will occupy some space to store the table structures and the constraints/indexes. Why don't u just create the database tables (w/o any data) using SQLite Browser and check the size of the database file.
Would help you decide.
I think instead of creating all tables at one go use SQL queries to create tables as and when needed. If its not needed anymore you can even drop the table.
Related
Why sqlite database has the limitation of "not to drop a column from a table"
in a single command?
Are there any chances it would be added in future versions?
ALTER TABLE DROP COLUMN is now supported, as of 3.35.0 which was released 2021-03-12.
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE
command in SQLite allows the user to rename a table or to add a new
column to an existing table. It is not possible to rename a column,
remove a column, or add or remove constraints from a table.
https://sqlite.org/lang_altertable.html
No, you can't.
Are there any chances it would be added in future versions?
Well, we can't tell you that. And even if they will add it, there are still a lot of Android devices out there which have an older version of SQLite without that feature.
However, you can delete a column like this from this answer:
https://stackoverflow.com/a/5987838/5457878
The ALTER TABLE statement supports exactly those operations that can be implemented easily without having to rewrite the entire table. (When adding a new column, that value is missing in all rows; it gets replaced with the column's default value when read.)
The ability to drop columns (or other things, like reordering columns) would add lots of complex code to the SQLite library.
However, SQLite is designed as an embedded database, so it must take care to conserve resources. It is very unlikely that such a large amount of code will ever be added.
http://www.sqlite.org/faq.html#q11
SQLite has limited ALTER TABLE support that you can use to add a column to the end of a table or to change the name of a table. If you want to make more complex changes in the structure of a table, you will have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
So you can't just delete the column
I have an app published in the play store.
The app uses a database which holds a table which has a column of type int.
I'm doing a new change where I need to change the column type to long.
How do I go about handling it in the DatabaseHandler I'v created.
I want to preserve the data stored in the older apps database, so what should ideally be the code in the onUpgrade() function???
You don't need to change the database column type. An INTEGER column will happily contain all the bits needed to represent a Java long.
In fact, there's no long column type in sqlite.
I think using SQLite, the best way is to create a temporary table, copy all your table content, drop the old table and recreate the table with the right type on your column, then you can just copy the content from the temporary table and drop it...
I know this don't fell like the best approach, but I don't think SQLite have some alter table function.
As far I know you can t do this . But You can drop your table if it exists and create it again . Maybe you can find out some useful information here SQLite Modify Column or here Modify a Column's Type in sqlite3
In my Android app, I need to temporarily store some data in a form of table such as follows:
id | column 1 | column 2 | ... | column n
The data are downloaded from a server whenever users press a button. However, the data table doesn't have a fix number of column (as well as row) every time user downloads it from the server. For example, the server may send data with 3 columns the first time. Then it might send data with 5 columns the second time, etc...
Given this scenario, I think the database is probably the right data structure to use. My plan is to create a database, then add and delete tables as necessary. So I have been reading various tutorials on Android database (one example is this one http://www.codeproject.com/Articles/119293/Using-SQLite-Database-with-Android#). It seems to me I cannot create new table with variable number of columns using the sqlite database. Is this correct? In the onCreate(SQLiteDatabase db) method, the "create table" command must be specified with known number of columns and their data types. I could provide several "create table" commands, each with different number of columns but that seems like very crude. Is there a way to create database tables with variable number of columns on the fly?
Another alternative probably using several hash tables, each storing one column of the data table. I'm seriously considering this approach if the database approach is not possible. Any better suggestion is welcomed.
There is no such thing as a variable number of columns in an SQLite data base. Also, adding and deleting tables dynamically seems like a horrible hack.
It sounds like you want to store an array of values associated with an id. I suggest you think in terms of rows, not columns. Use a table structure like (id, index, value); each array of values returned by the server results in as many rows as necessary to store the values.
this is more of a question of theory than anything else. I am writing an android app that uses a pre-packaged database. The purpose of the app is solely to search through this database and return values. Ill provide some abstract examples to illustrate my implementation and quandary. The user can search by: "Thing Name," and what I want returned to the user is values a, b, and c. I initially designed the database to have it all contained on a single sheet, and have column 1 be key_index, column 2 be name, column 3 be a, etc etc. When the user searches, the cursor will return the key_index, and then use that to pull values a b and c.
However, in my database "Thing alpha" can have a value a = 4 or a = 6. I do not want to repeat data in the database, i.e. have multiple rows with the same thing alpha, only separate "a" values. So what is the best way to organize the data given this situation? Do I keep all the "Thing Names" in a single sheet, and all the data separately. This is really a question of proper database design, which is definitely something foreign to me. Thanks for your help!
There's a thing called database normalization http://en.wikipedia.org/wiki/Database_normalization. You usually want to avoid redundancy and dependency in the DB entities using a corresponding design with surrogate keys and foreign keys and so on. Your "thing aplpha" looks like you want to have a many-to-many table like e.g. one or many songs belong/s to the same or different genres. You may want to create dictionary tables to hold your id,name pairs and have foreign keys referencing these tables. In your case it will be mostly a read-only DB so you might want to consider creating indexes with high FILLFACTOR percentage don't think sqlite allows it to do though. There're many ways to design the database. Everything depends on the purpose of DB. You can start with a design of your hardware like raids/file systems/db block sizes to match the F-System's block sizes in order to keep the I/O optimal and where to put your tablespaces/filegroups/indexes to balance the i/o load. The whole DB design theory/task is really a deep subject which is not to be underestimated nor is a matter of few sentences in the answer of stackoverflow. :)
without understanding your data better here is my guess at what you are looking for.
table: product
- _id
- name
table: attribute
- product_id
- a
The Android app that I am currently working on dynamically adds columns to an SQLite database. The problem I have is that I cannot figure out a way to remove these columns from the database.
If I add column A, B, C, D, and E to the database, is it possible to later remove column C?
I have done a lot of looking around and the closest thing I could find was a solution that requires building a backup table and moving all the columns (except the one to be deleted) into that backup table.
I can't figure out how I would do this, though. I add all the columns dynamically so their names are not defined as variables in my Java code. There doesn't seem to be a way to retrieve a column name by using Android's SQLiteDatabase.
SQLite has limited ALTER TABLE support that you can use to add a column to the end of a table or to change the name of a table.
If you want to make more complex changes in the structure of a table, you will have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
For example, suppose you have a table named "t1" with columns names "a", "b", and "c" and that you want to delete column "c" from this table. The following steps illustrate how this could be done:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
SQLite doesn't support a way to drop a column in its SQL syntax, so its unlikely to show up in a wrapper API. SQLite doesn't often support all features that traditional databases support.
The solutions you've identified make sense and are ways to do it. Ugly, but valid ways to do it.
You can also 'deprecate' the columns and not use them by convention in newer versions of your app. That way older versions of your app that depend on column C won't break.
Oh... just noticed this comment:
The app is (basically) an attendance tracking spreadsheet. You can add
a new "event" and then indicate the people that attended or didn't.
The columns are the "events".
Based on that comment you should just create another table for your events and link to it from your other table(s). You should never have to add columns to support new domain objects like that. Each logical domain object should be represented by its own table. E.g. user, location, event...
Was writing this initially. Will keep it if you're interested:
Instead of dynamically adding and removing columns you should consider using an EAV data model for that part of your database that needs to be dynamic.
EAV data models store values as name/value pairs and the db structure never needs to change.
Based on your comment below about adding a column for each event, I'd strongly suggest creating a second table in which each row will represent an event, and then tracking attendance by storing the user row id and the id of the event row in the attendance table. Continually piling columns onto the attendance table is a definite anti-pattern.
With regards to how to find out about the table schema, you can query the sqlite_master table as described in this other SO question - Is there an SQLite equivalent to MySQL's DESCRIBE [table]?
As per SQLite FAQ, there is only limited support to the ALTER TABLE SQL command. So, the only way you can do is that ou can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
Also you can get the column name from the database using a query. Any query say "SELECT * FROM " gives you a cursor object. You can use the method
String getColumnName(int columnIndex);
or
String[] getColumnNames();
to retrieve the names of the columns.