Getting started with SQLite (Android) - android

I have limited SQL background, basically a small amount of manipulation through HTML and mostly with pre-existing databases. What I am trying to do is set up a database that will store time information for bus routes. So basically I have different routes with stops for each route and then a list of times that the bus arrives at each stop. Here is an example of a table of times from their website: Link.
I am wondering what would be the best way to layout my database/tables?
Also what is the purpose of the _id field in each table?
Thanks,
Rob!
P.S. Sorry if my lack of knowledge on the subject has caused me to post a duplicate question.

The id field provides a unique id to each row, that can be referenced by other tables in the database. When it is referenced this way, it is called a foreign key. This allows you to have one table with detailed information about say a student (name, address, etc) and then uniquely reference that student in another table that talks about members of a class.
There are generally many different ways to lay out a database, which is best really depends on what you want to do with the data. Most of this design is not unique to SqlLite, so reading up on relational databases in general might be worthwhile.
One way to lay it out your specific example:
Route table: id, name
Stop table: id, name
Time table: id, foreign key to route, foreign key to stop

You asked two questions:
The 'id' field is a good convention as a unique row identification. It is not strictly required, and some data that has its own unique serial number for each row will use that serial number instead. Programs often want to look up the entire record by the unique row identification so the field should be a primary key. The commonly used clause for creating the id is "id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id)". A unique id will be assigned automatically whenever you add a new record. See Tizag's MySQL Tutorial for a verbose breakdown. Personally, some name these "_id", e.g., "route_id", "bus_id", and your style may vary.
Laying out your data depends a bit on what you want to do with it. My guess is that for each bus route, you want to find the next bus at a particular stop after some time and then when that bus arrives at some next stop. Each route has many stops; a stop might be shared among routes; a route varies during the day by skipping some stops; routes go in two directions; etc. I would add the abstraction of a 'run' which one bus run through the stops from start to finish.
My first guess at laying it out would be:
A bus route has a bus name, number, and other info: "#1 Red", "South And West", "SF Muni", "map://..."
A stop has a unique name and other info: "North Grand Mall". "South", "Under the cherry, west of grand avenue."
A run has a route number, days of the week, a direction, maybe a sequence number of the run in that direction that day, maybe a start/stop time for the run: "63 (route_id for #1 Red)", "reverse direction", "MTWRF" (weekdays), "2" (2nd run), "7:00", "7:36".
Then you have a schedule table of "Run_id", "Stop_id", "Stop Sequence Number", "Time".
Write out your planned schema, and then start trying to write schemas against them. Don't be surprised by a couple multiple joins "SELECT * from Schedule as S, Run as R, Bus as B for B ... WHERE B.id == R.bus_id and S.run_id == R.id and B.id = (requested bus) and S.time >= now() and ...." You denormalize for performance after it works.
That's all my free advice. :)

Related

Saving a changing amount of Values in a SQL-Database

i am really stuck at this point of my android app development.
What i need is a way to save a changing amount of int or string-values (in a sql database). Yet im not even sure if this is the right approach, but let me explain:
In the app i am currently working on, you are able to create certain "events". Users should be able to apply for such events.
I have an external database with 2 tables:
first one for users - every user has a unique ID
second one for events - every event has a unique ID
I need each event to know what users applied for it. And i need each user to know what events they applied for.
I was thinking to save the Event-IDs in the User-Table and vice versa.
I just dont know how to do that since the amount of applicants/ID's can change. Is there a way to save Arrays in the database which can easily be edited (e.g. +/- one ID) and read?
Is this even the right way? I am very happy for any advise!
Thanks in advance!
What you seem to want is a many-to-many relationship. A user can be part of many events, and an event can have many users. That requires an additional table though:
Table: User Columns: UserId, Name, ...
Table: Event Columns: EventId, Name, ...
Table: UserEvents Columns: UserId, EventId, ...
In the new table, UserEvents, you would store the UserId's and EventId's like this:
UserEvents
UserId EventId
1 1
2 1
1 2
This means that if you selected UserId 1, the query would return EventId 1 & 2. If you selected EventId 1 the query would return that UserId 1 & 2 would be attending.
This is the standard and recommended way to deal with many-to-many. It's very flexible and can easily be scaled.
You could either use a Compound key (Composite Key) for this table, or create a column specifically as a Primary Key. The code below can be used, and manipulated, to create both your table and Compound/Composite key (I'm guessing on data types).
CREATE TABLE UserEvents
(
[UserId] INT NOT NULL,
[EventId] INT NOT NULL
CONSTRAINT PK_UserEvents PRIMARY KEY NONCLUSTERED ([UserId], [EventId])
)
I would add a third table (e.g. UserEvents) to store which events a user has applied for, along with other relevant attributes (e.g. ApplicationTime, ApplicationStatus). This association would have a foreign key relationship back to the related tables and resolve the many-to-many relationship between users and events.
What you have there is called a "many-to-many" relationship between to tables which can only be resolved by the introduction of a third table between your two tables that stores the associations.
This table would contain the User-ID and the Event-ID as foreign keys (and maybe additional information).

Data synchronization between two or Android devices and website

I am building an app that allows users to insert data and synchronize with website. User can insert data on the website as well. There are two entity tables (T1 and T2) and one N-M relation table (TR).
Data Structure (it's just illustrative):
T1 (_id, name, modified)
T2 (_id, name, modified)
TR (t1_id, t2_id)
The problem I am facing is data synchronization of IDs. E.g. Device A1 and A2 are offline and record is inserted on both, with the ID = 1. After they are online sync starts and there is a conflict with IDs. I thought about introducing an extra column gid - something like global ID. So the structure would be:
T1 (_id, name, modified, gid)
T2 (_id, name, modified, gid)
TR (t1_id, t2_id, t1_gid, t2_gid)
Global ID would be assigned by website.
But I not sure whether this is a good approach or not (never done anything like this before and cannot tell if there will be any future problem).
You have to use additional ids, suppose network_id, generate all network_ids on the server and use local ids on devices (e.g. UUID). When you are sending create entity request server will generate a real id and return it to you, so you can update a local database with network_id. It is important to use network_id as main field and local_id only if you don't have network_id.

how to store Android database with variable number of attributes per row

For my Android app, I want to save data using sqlite with this format:
name, date, attr1, attr2, attr3,...
These are the requirements:
each date can only contain each name once
there can be a variable number of attributes(numbers) for each name
each specific name has the same number of attributes
The app will be used to track events throughout the day. Events can have zero or more numeric properties.
The questions are: is sqlite the best way to store things here? If so how do I design my database? What other ways are there to store this kind of data?
is sqlite the best way to store things here?
This will depend on a number of other factors, such as how the data will be queried and used, the volume of transactions, data growth and retention, etc. From what you've described, though, SQLite is a great option, offering functionality out-of-the-box that supports some of your requirements directly, and is commonly used in such cases.
If you don't have much experience with relational databases, implementing this functionality may seem difficult at first, but like learning a new language or framework, it will get easier with time.
If so how do I design my database?
Let's step through each of your enumerated requirements...
each date can only contain each name once
SQLite supports the UNIQUE constraint. For example, if your columns were named name and date, you could add the following to your CREATE TABLE statement:
UNIQUE(name, date)
(A more complete CREATE TABLE statement is in the next example below, and it includes this constraint.)
This constraint prevents the insertion of rows with name/date pairs that already exist. Using android.database.sqlite.SQLiteDatabase, if you attempt to insert a row into the table with a duplicate name/date pair, a SQLiteConstraintException will be thrown at runtime. You will need to handle this exception in your java code.
there can be a variable number of attributes(numbers) for each name
This is a textbook case for normalizing the database, putting your data into multiple tables. For example:
CREATE TABLE names (
name_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
date DATETIME,
UNIQUE(name, date));
CREATE TABLE attrs (
name_id INTEGER NOT NULL,
attr_value INTEGER NOT NULL,
FOREIGN KEY(attr_value) REFERENCES names(name_id));
Your queries that retrieve attribute data would then JOIN the two tables. Since you indicated that "Events can have zero or more numeric properties", a LEFT OUTER JOIN might be most appropriate, as it will return names and dates even if there are no attributes.
Here's an example query, by name:
SELECT n.name, n.date, a.attr_value
FROM names AS n
LEFT OUTER JOIN attrs AS a
ON n.name_id = a.name_id
WHERE n.name = 'SMITH'
ORDER BY n.name, n.date, a.attr_value;
This query would return results like the following:
name date attr_value
--------------- ---------- ------------
SMITH 2015-02-13 1027
SMITH 2015-02-13 4426
SMITH 2015-02-13 8390
SMITH 2015-02-20 4426
SMITH 2015-02-20 8152
SMITH 2015-02-20 9328
You can then iterate through and process these results in java. If your results include multiple names and/or dates, then in your loop you should keep track of the last used name and date. If the name/date in the current record is the same, the attribute belongs to the current one. If the name/date is different, then this is a new one.
Note that this approach to your database design is flexible, allowing you to query on the attributes, for instance, to see what name/date pairs are associated.
Also note that there is a FOREIGN KEY constraint on the attrs table, meaning that if you attempt to insert a record into that table with a name_id that does not exist in the names table, a SQLiteConstraintException will be thrown at runtime. You will need to handle this exception in your java code.
each specific name has the same number of attributes
You will need to accommodate this requirement in your java code, probably doing some checks in the database prior to performing an INSERT.
What other ways are there to store this kind of data?
Flat files, JSON, XML, third-party data stores (with their own libraries), to name a few.
I'm not sure but I think the best way to achieve your requirement is to use sqlite and to solve your problem you can have 3 columns only. One for the name and one for the date and the other contains a JSON array that represents the rest of the attributes.

SQLite Android: searching function for multiple tables?

I am making an app which is pretty much like this:
Register a customer;
Add different types of math calculations to this customer;
Now this customer has a list full of specific calculations.
Everything is working pretty good so far. But the thing is, how could I make a sqlite function in my db class that would list ONLY the calcs of a specific customer? e.g. when I select one specific customer, I don't want to see the calcs of other customers, only of this specific one.
I have 2 tables:
Customer (_id, name, email)
Calculations (_id, customer_id, date, value1, value2, result)
is there anyway I could like add a new column to Customer which would be like "calcs_made" and then it would call ALL "Calculations" table's columns?
I thought of searching the "customer_id" that the user is looking for and showing only the lines with that matching information, but it doesn't sound like a good practice.
The "Calculations" table is the first and only one so far, but there will be many others with different types of calcs as I update the app, therefore it would have to be really flexible.
Try using a sql selection to get what you need. It may look like this
select * from Calculations where customer_id=id;
The id is the specific customer id you choose.

How to organize sqlite database

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

Categories

Resources