At my app I am using a string value with a length of 50+ characters as my "Primary Key" of each object (around 10,000 objects), is there any performance difference in fetching one or many objects where there primary value contains a string of 50+ characters vs object that contain primary key value of lets say a string with 10 characters?
Thank you for the help
There is definitely a big difference in query writing. Because your main key is a long string and the search base in Realm based on Primary Key. You can have a better solution. Consider the following example.
I have a table called product that has the following fields.
ID (Primary Key) // user can't not access it. for backend Logic
product Code // user can access it.for front logic
Product Name
And etc ...
Now I consider the main key as an ID for myself, but I only use the productCode to display to the user.
This method solves both the indexing speed problem (because the length of the main key character is shorter) and my program performance and structure are correct.
Related
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
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).
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.
Firstly I want to say, I really liked Stackmob.
But I've got some little problems because I'm a newbie on stackmob.
I'm developing on Android sdk
I have created a schema called "level" and it has 2 unique indexes (facebook_id and level_no)
My question is how to insert, update and delete (crud) the rows by facebook_id and level_no.
(ps: I can update a schema if it has 1 unique index but when index counts are greater than 1, I dont know how to do it.)
An index isn't like a primary key; it doesn't enforce uniqueness, it just speeds up querying on those fields. You still have to think in terms of level_id as your primary key. It's not hard to do CRUD operations in terms of other fields though. For insert, if you leave out the primary key, one will be generated for you. For the other operations, you can query by the field you want:
Level.query(Level.class, new StackMobQuery().fieldIsEqualTo("facebook_id", "foo"), new StackMobQueryCallback<Level>() {...});
then once you've got your Level object, simply resave or delete
myLevel.setSomething("bar");
myLevel.save();
// or
myLevel.delete();
If you're using the datastore api, it's the same idea, you're just making the REST API calls directly.
I am developing an Android application that supports Arabic and English, but I am still confused about the database design:
The approach I am following is
creating a language table that holds two records (Arabic and English)
creating a table that holds normal data (not language specific)
creating a translation table that holds language specific content
For example to implement (Help) I created the following tables:
Language (int id, text Code)
Help (int id)
Help_translation(int id, int Help_id, int Language_id, text Question, text Answer)
I have read this solution so many time, but I still don't know why do we have a separate table for (Help) that does nothing!
Is there something wrong about my approach?
On the face of it, the Language table will appear once in the system. I suggest using the 'll_tt' notation for language and territory based on the ISO country codes (ISO 3166) and ISO language codes (ISO 639-2). Thus, you might have en_gb for British English, en_us for US English, and ar_sa for Saudi Arabian Arabic, and ar_eg for Egyptian Arabic. This may be more powerful than you currently need, but gives you a direction for the future.
Thus, the Language table might have columns:
id integer (autoincrement) Primary key.
code char(5) — Unique.
The Help table in your design is for 'documentation' purposes. It records the valid help numbers that the application can use. A fuller version of the table might include information about the message: where it is used in the application; which version it was introduced in; which version it became obsolete with (or maybe not — we have internationalized message files that have to be good for use with releases over a period of about 10 years); dates associated with the version — or dates instead of the version; and 'notes to the translator' (guidelines for how to translate the message, if any special guidelines are needed).
The minimalistic version of the Help table with just the Help ID number will do for the time being:
id integer (autoincrement). Primary key.
The Help_Translation table stores the strings that the application will display. The id column is of minimal value here; I would omit it (but you can keep it if you wish). The Help_ID column is a foreign key reference to the Help table; the Language_ID column is a foreign key reference to the Language table. For your chosen application, there appears to be both a question and an answer for each help item.
Therefore, the Help_Translation table has the columns:
id integer (autoincrement, optional, not sure when you'll use it).
Help_ID integer — foreign key references Help(ID).
Language_ID integer — foreign key references Language(ID).
Question text — the question in the appropriate language for the given Help_ID.
Answer text — the answer to the question in the appropriate language for the given Help_ID.
Primary key: Help_ID and Language_ID.
An alternative design would have simply a translation table with a 'Message ID' and a 'Language ID' and the translated string (primary key on Message ID and Language ID). There would be a table of Messages, identifying the valid Message IDs plus supporting data of the type outline previously. This might include the default message to be used (untranslated) when there is no translated version of the message for a particular language/territory (or you can make up more complex schemes for handling missing messages, so that when Arabic is requested but the translation for, say, Libya (LY) is incomplete, it falls back onto ar_sa and only then onto en_gb). Your Help table might then contain a Help ID, plus two Message ID values, one for the Question and one for the Answer. The advantage of this scheme is that all translated messages are in a single table.
There are undoubtedly other schemes that could be devised.