I have a a database with more than 6000 entries. I am using this example http://eshyu.wordpress.com/2010/08/15/cursoradapter-with-alphabet-indexed-section-headers/ to display the contents. But now the activity isn't able to handle it. I get a ANR dialog every time. How do I efficiently handle this circumstance?
It doesn't make sense to go through each entry and ask the indexer on wich section that entry belongs to. In your case, the Indexer might be doing 6000 binary searches. Then puting that result in a map that will have below 30 entries and doing many overwrites.
It's also not a good idea to abuse the sectionToPosition Map to create a section starting postion.
A. You either prepare a table containing the stats, which would be the best way to handle so much data.
B. You can use the database to count number of entries for each section and build your own section starting pos map.
SELECT UPPER(SUBSTR(LTRIM(side_a), 1, 1)), COUNT(*) FROM cards GROUP BY 1 ORDER BY 1 ASC;
Related
Suppose, In my app I have a sqlite table that can contain at most 20 row. Each row has 2 column(id, name). Where I frequently need to search by Id to get Name. For this frequent need I have two solution:
Solution 1: Get rows in a arraylist<model> and then find name from array.
Solution 2: Every time search on sqlite table.
Now please give your opinion which one is better?
Remember again, I need this search in my recycleView item, so it call so frequently.
Thanks
I don't really get what is your real intent, but if your task is to search by id often, I would use
LongSparseArray<String> idsToNames; // or LongSparseArray<Model>
Which will map primitive long to Strings in a more memory-efficient way than Map and will have a better performance than ArrayList when searching.
The advantage over querying SQLite here is that you can do it in a blocking manner instead of having to query database on a background thread every time the lookup runs.
The disadvantage is that whenever data changes in SQLite, you will have to rebuild your idsToNames map. Also, if the number of entries in SQLite will eventually grow, you will end up in a large collection. So I would recommend this approach only if the updates to the database during this session will not happen, and if the data size is always predictable or fixed.
I need help to design DB/table for Restaurant Ordering System.
1) Captain will take order on Android device and after Placing an order from Customer, he (captain) will Print Order.
2) Captain can alter/add order based on Customer's demand
3) Finally based on customer's demand captain will finalised bill and Print the bill
Some Cases for Placing Order
1) Place Order and not cancelled and finalised bill
2) Place Order - say 4 Burgers , after finish, again customer Place order - say 3 Burgers, not cancelled, and finalised bill
3) Place Order - say 4 Burgers , after finish , again Place order - say 3 Burgers, and Customer asks to Cancel 1 Burger, then finalised bill
4) Place Order - say 4 Burgers, then, Cancel 2 Burger, then after sometime, Place Order 4 Burgers then finalised bill
5) Place Order - 4 Burgers, after sometime, Cancel 2 Burgers, after sometime, Place Order 4 Burgers, after sometime Cancel 2 and then finalised bill
i have already created , menu_card (i.e item), table_info
Billing Table :
id
table_no
bill_no
item_name
quantity
repeat_quantity
print_status (Printed/Not Printed)
ongoing (Yes/No(if no -then finished) )
date_time
Which field should i add in case 3,4,5 for Placing an order
I am confused what if Customer ask for "Cancel Order" , after finish current Order, he asks for same Item.
New EDIT :
I am showing the List of Ordered Items, where captain can touch to update the order,
I m thinking to add cancelled_items_quantity in table and for every new order i will make new entry to database to add those order,
E.g. Customer has ordered 4 Burgers, then it will add to the DB, now after finishing it off, if he asks for 3 burgers, again new entry will be made rather to modify existing 4 to 7, and even if he cancels the order, suppose 2 from 3 Burgers, then update will be made on same entry i.e. it will update cancelled_items_quantity to 2 from default 0
Pls Help
I'd start with making a separate table for items, orders and bills. Since one bill can contain multiple orders and an order multiple items.
As for your example cases, only write finalised data to the database. Keep non-finalised orders in memory on the app. Once the user clicks 'Ok' or 'Finish' the order is finalised and you can write it to the DB.
If you would change the order every time in the database, you'd do way too much transactions which isn't good.
You probably will want separate tables.
1) billing_info
2) table_info
3) item_info
Then correlate to each other as your requirements. Add a 'status' field or similar in item_info so you can easily update its value whenever user request changes.
EDIT
How about for item_info table, for each individual item that customer has ordered, create an entry. Then any changes, update the status.
I visualize on the android tablet, i can see a whole list of every items that customer has ordered.
Eg.
1 steak
1 ice tea
1 steak
1 coffee
1 coffee
So for each item there can be 2 options.
1) to remove the entry before confirmation
2) to change the status after confirmation
Before confirmation, changes are just on the UI only. So we can use option1 to update the UI. I supposed the complications come after confirmation and customer wants to change the order. So we use option2.
2 steak ordered. Now customer wants to cancel 1. So waiter just change the status of 1 steak to 'cancel'.
Thanks in advance.
I am developing a Car Review Application, where user can log in and displayed all the review from the Database. All the the data is being stored in MYSQLdatabase first. I am using json to connect to the MYSQLdatabase and SQLiteDatabase. But the problem is that, after log in the application screen huge no. of data is coming from the server and it is being inserted in our SQLite Database.
After that it is being retrieved from database and displayed in the Application Screen in a list view, it is taking a longer time to displayed all the data in list view. In that case, I am using a SimpleCursorAdapter to retrieve all the data from database.
So is there any way like pagination or something like that to make the data retrieval faster.
Please help me by giving some source code.
You can use something like:
Page 1:
SELECT * FROM YOUR_TABLE LIMIT 20 OFFSET 0
Page 2:
SELECT * FROM YOUR_TABLE LIMIT 20 OFFSET 20
Reference: http://sqlite.org/lang_select.html
You can use the concept of Asynchronous tasks along with SimpleCursorAdapters.
"AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers."
Here's what you can do:
1) Retrieve only 1st 10/15 items in the 1st query.
2) Fire another query as a background task, while user is checking out first 10/15 items.
This will certainly make the User experience faster
Using the LIMIT keyword from MYSQL you can achieve pagination.
LIMIT allows you to control the number of rows returned by query:
Example:
to show first 10 records
SELECT * FROM Student LIMIT 10 //for first time
to show rows between 10 and 20
SELECT *FROM Student LIMIT 9, 10 //after showing the records first time
LIMIT works for SQLiteDatabase also
I successfully used the following BEFORE INSERT trigger to limit the number of rows stored in the SQLite database table locations. The database table acts as a cache in an Android application.
CREATE TRIGGER 'trigger_locations_insert'
BEFORE INSERT ON 'locations'
WHEN ( SELECT count(*) FROM 'locations' ) > '100'
BEGIN
DELETE FROM 'locations' WHERE '_id' NOT IN
(
SELECT '_id' FROM 'locations' ORDER BY 'modified_at' DESC LIMIT '100'
);
END
Meanwhile, I added a second trigger that allows me to INSERT OR UPDATE rows. - The discussion on that topic can be found in another thread. The second trigger requires a VIEW on which each INSERTis executed.
CREATE VIEW 'locations_view' AS SELECT * FROM 'locations';
Since an INSERT is no longer executed on the TABLE locations but on the VIEW locations_view, the above trigger does no longer work. If I apply the trigger on the VIEW the following error message is thrown.
Failure 1 (cannot create BEFORE trigger on view: main.locations_view)
Question:
How can I change the above trigger to observe each INSERT on the VIEW - or do you recommend another way to limit the number of rows? I would prefer to handle this kind of operation within the database, rather then running frontend code on my client.
Performance issues:
Although, the limiter (the above trigger) works in general - it performs less then optimal! Actually, the database actions take so long that an ANR is raised. As far as I can see, the reason is, that the limiter is called every time an INSERT happens. To optimize the setup, the bulk INSERT should be wrapped into a transaction and the limiter should perform right after. Is this possible? If you like to help, please place optimization comments concerning the bulk INSERT into the original question. Comments regarding the limiter are welcome here.
This type of trigger should work fine in conjunction with the other one. The problem appears to be that the SQL is unnecessarily quoting the _id field. It is selecting the literal string "_id" for every row and comparing that to the same literal string.
Removing the quotes around '_id' (both in the DELETE and in the sub-SELECT) should fix the problem.
What is the best way to maintain a "cumulative sum" of a particular data column in SQLite? I have found several examples online, but I am not 100% certain how I might integrate these approaches into my ContentProvider.
In previous applications, I have tried to maintain cumulative data myself, updating the data each time I insert new data into the table. For example, in the sample code below, every time I would add a new record with a value score, I would then manually update the value of cumulative_score based on its value in the previous row.
_id score cumulative_score
1 100 100
2 50 150
3 25 175
4 25 200
5 10 210
However, this is far from ideal and becomes very messy when handling tables with many columns. Is there a way to somehow automate the process of updating cumulative data each time I insert/update records in my table? How might I integrate this into my ContentProvider implementation?
I know there must be a way to do this... I just don't know how. Thanks!
Probably the easiest way is with a SQLite trigger. That is the closest I know
of to "automation". Just have an insert trigger that takes the previous
cumulative sum, adds the current score and stores it in the new row's cumulative
sum. Something like this (assuming _id is the column you are ordering on):
CREATE TRIGGER calc_cumulative_score AFTER INSERT ON tablename FOR EACH ROW
BEGIN
UPDATE tablename SET cumulative_score =
(SELECT cumulative_score
FROM tablename
WHERE _id = (SELECT MAX(_id) FROM tablename))
+ new.score
WHERE _id = new._id;
END
Making sure that the trigger and the original insert are in the same
transaction. For arbitrary updates of the score column, you would have to
have to implement a recursive trigger that somehow finds the next highest id (maybe by selecting by the min id
in the set of rows with an id greater than the current one) and updates its
cumulative sum.
If you are opposed to using triggers, you can do more or less the same thing in
the ContentProvider in the insert and update methods manually, though since
you're pretty much locked into SQLite on Android, I don't see much reason not to
use triggers.
I assume you are wanting to do this as an optimization, as otherwise you could just calculate the sum on demand (O(n) vs O(1), so you'd have to consider how big n might get, and how often you need the sums).