How to design primary key for DynamoDB with 3 attributes - android

I am new to DDB, but from what I understand, The DynamoDBHashKey is the same as the partition key, and the DynamoDBRangeKey is the same as the sort key. However, I have 3 values that I need to make a unique key. This is for a mobile application. The use case is storing records. See below:
#DynamoDBTable(tableName = "foo")
public class Foo {
private String userID; // Set on a per-device basis by AWS Cognito
private String name; // The user's name. There can be many users on a device
private long time; // The time the record is created
}
So my original though was to make userId the partition/hash key and name the sort/range key, but each of those combinations will have multiple records, thus the addition of the time attribute. Is there a solution here that I am missing?

Here you go..
Parttionkey userid-name
rangekey time
Key point here is that partition key is a concatenated key consisting of two identifiers

Related

Android Realm primary key value performance

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.

Migrating auto generate primary key

How can I migrate a primary key field, which was not set to Auto generate before?
From
#PrimaryKey
private int id;
To
#PrimaryKey(autoGenerate=true)
private int id;
Since Sqlite does not support altering columns, my only guess is to migrate the whole table as is and resetting the constraints.
Do I even have to migrate the database during the development process or can I just rebuild it, since my database will change rapidly, so I don't have to migrate every time?
I suggest you to change your approach: add an unique identifier (UID) as alternative way to identify records.
You can define a UID with annotation Entity on your POJO.
#Entity(indices={#Index(value="uid", unique=true)})
publi class Pojo {
..
public String uid;
..
}
When you insert a record in your database, you can define uid field using:
String uuid = UUID.randomUUID().toString();
You can use the UUID field to identify your records, in absolute way. When you migrate to a version to another, you don't work with the old ids, you can always work with UID.

Android Room: auto Increment field

Is there any way to set a field auto increment with android Room?
There is a table which contains 3 fields: id, name, order. And I want the field order to be an auto increment field.
#PrimaryKey(autoGenerate = true)
private long id;
private String name;
private int order;
Set field as primary key can achieve this, but there is already one id.
I can handle the order by myself, maybe set the field order as unique is much safer. But I prefer letting the db do it automatically. How can I do that?
Currently, Android doesn't support auto increment. Even for primary key, its not auto-increment, its auto-generate. It won't be serial numbers. It will generate a random hash numbers.
Auto generate is supported only for primary key but not for any normal column
#PrimaryKey(autoGenerate = true)
Annotate your Entity class with the code above.

Preset object Id when pushing to Firebase

I'm using a SortedList to sort my items inside the RecyclerView.
So I need to compare them by some unique Id, and Firebase provides awesome generated keys for that.
To push new value to a database I need to run:
public void addAdvert(Advert advert, String userId) {
String id = reference.child(NODE_USERS)
.child(userId)
.child(NODE_ITEMS)
.push()
.getKey() //execute this to just get the id
advert.setId(id);
getCurrentItemNode().child(advert.getId()).setValue(advert);
}
now my Advert item in database is fully equiped with Id and node key.
But I' curious, can I just write something like
reference.child(NODE_USERS)
.child(userId)
.child(NODE_ITEMS).push().setValue(advert);
And achieve the same result: both key and ID are set in database.
If you want to store the key in the item, you'll either have to perform two write operations or first generate the key and then write it.
But why do you want to store the key in the item to begin with?
As a side note, this code:
String id = reference.child(NODE_USERS)
.child(userId)
.child(NODE_ITEMS)
.push()
.getKey()
Is exactly the same as this:
String id = reference.push().getKey()
Firebase's push IDs are client-side generated, statistically guaranteed to be unique values. They're not dependent on the path and there is no round-trip to the database needed to determine these values.
See this blog post for more information: The 2^120 Ways to Ensure Unique Identifiers.

ORMLite not loading child foreign fields

I'm using ORMLite 4.42 for an Android app. I have an entity which has foreign fields. These fields have foreign fields too. The problem is that when I get an element of the root entity, only the first level of foreign fields are loaded. The others levels are null.
On the database every seems ok. The id is correct. Any help?
Edit with models.
The Equipment model is always null when I query by ID. But if I query the whole table, then it gives me access to everything.
TABLE INCIDENT
#DatabaseField(generatedId=true)
private UUID id;
#DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=false)
private UserEntity user;
#DatabaseField(dataType = DataType.DATE, canBeNull=true)
private Date date;
#DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=true)
private EquipmentEntity equipment;
TABLE EQUIPMENT
#DatabaseField(generatedId=true)
private UUID id;
#DatabaseField(canBeNull=false, unique=true)
private String serial;
#DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=false)
private EquipmentTypeEntity type;
TABLE EQUIPMENT TYPE
#DatabaseField(generatedId=true)
private UUID id;
#DatabaseField(canBeNull=true)
private String type;
#DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=false)
private EquipmentModelEntity model;
TABLE EQUIPMENT MODEL
#DatabaseField(generatedId=true)
private UUID id;
#DatabaseField(canBeNull=false)
private String model;
I'm using ORMLite 4.42 for an Android app. I have an entity which has foreign fields. These fields have foreign fields too. The problem is that when i get an element of the root entity, only the first level of foreign fields are loaded. The others levels are null.
Right, this is by design. ORMLite specifically limits the number of times it auto-refreshes a sub-element. This was done to protect against huge object trees swallowing memory and against self referential objects.
To quote the docs for foreignAutoRefresh:
NOTE: To protect against recursion, there are a couple of places were auto-refreshing has been limited. If you are auto-refreshing a class that itself has field with foreignAutoRefresh set to true or if you are auto-refreshing a class with a foreign collection, in both cases the resulting field will be set to null and not auto-refreshed. You can always call refresh on the field directly if you need it.
NOTE: If you have an auto-refreshed field that is an object that also has an auto-refreshed field, you may want to tune the maxForeignAutoRefreshLevel value. See below.
To quote from the docs for maxForeignAutoRefreshLevel:
This can be used to set the maximum number of levels to configure foreign objects. For example, if you have a Question which has an foreign field of the best Answer, and the Answer has an foreign field to the corresponding question, then the configuration back and forth can get large. This is especially a problem with auto-refreshed fields when you lookup the Question it could cause an infinite loop. By default, ORMLite only goes through 2 levels but you can decrease it to 1 (0 is not valid) or increase it. The higher the number the more database transactions happen when you load in your Question.
If you increase the maxForeignAutoRefreshLevel to be more then it will issue the extra queries to refresh the elements.
#DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=true,
maxForeignAutoRefreshLevel=3)
private EquipmentEntity equipment;

Categories

Resources