Each Player has 50 items [saving that in SQL] - javascript

I have two issues that both resemble each other.
Each player has access to 50 inventory slots. 1 slot holds 1 item.
I figured that I can make a table of items. Items have qualities and ID's.
I have come to this solution:
Each character table can have a textbox that holds json data that is key value pairs of item slots [0-49] and item id's, since every item has a unique id.
However I am not sure this is the most elegant solution.
And then this problem, that should be solved the same way? [I think]
Each player has access to 50 skills. Each skill can grow 100 levels.

I wouldn't encode JSON data in a database -- you want a separate table to link things together.
So, maybe player_item_map which would have fields item_id, player_id (and maybe an internal id if you ever need to refer to the map itself). Then you link arbitrary numbers of items to users (you can use constraints in item ownership is unique, and enforce the item limit somewhere else). Alternatively prepopulate an inventory table with the slots, using the fields player_id, slot, item_id (can be null). Then you don't need to insert or worry about missing rows.
You can do similar for skills, but had a skill_level field as well.

Related

How to create an item with an index in DynamoDB?

I have been looking everywhere on AWS docs for any information on this and can find absolutely none. The only answer I keep getting everywhere I look is how to query or scan using a secondary index, on already-indexed data. But how do you add a value to the index-attribute of an item in the first place? I am using AWS SDK for JavaScript so JS-specific info would be most helpful, but any info on this would be so much better than what AWS has provided.
I tried to add an item with params like the following, where I simply used the names of indexes as attributes (date and timestamp):
const params = {
TableName: 'Posts_Table',
Item: {
'username' : user,
'image_id' : uuid(),
'date' : date,
'timestamp' : timestamp
}
}
But what ended up happening is date and timestamp were simply added as normal attributes that aren't able to be queried.
You've got some fundamental misunderstanding going on. You don't give enough code or examples for me to guess what you're really attempting. For example, I don't know what your table's keys are. So here's a primer:
You only write items to the base table (never directly to an index). Items can have a variety of attributes. Each item must have unique key attributes in the base table.
You can create a GSI against the table, including after the table has data. When constructing the GSI you select what its key attributes will be.
When you want to use the GSI you must specify it in the query as your Scan or Query target.
Are you trying to write to the index? You can't.
Are you trying to query the index by pointing at the base table? You can't.
Are you trying to write an item to the base table without specifying its primary keys? You can't.
How to create an item with an index in DynamoDB?
You can not create an item without an index in DynamoDB.
When you create a table, you specify the Primary Key which is your index.
When you add an item, you have to provide the Primary Key.
You can also make use of Global Secondary Indexes which technically create a new table with that index under the hood.
But what ended up happening is date and timestamp were simply added as normal attributes that aren't able to be queried.
If you want to be able to query an attribute, that attribute has to be a Primary Key (Partition or Composite) or a Global Secondary Index.

Firebase: best way to order and filter multiple childs

So as we know firebase won't let order by multiple childs. I'm looking for a solution to filter my data so at the end I will be able to limit it to 1 only. So if I won't to get the lowest price it will be something like that:
ref.orderByChild("price").limitToFirst(1).on...
The problem is that I also need to filter it by dates (timestamp)
so for that only I will do:
.orderByChild("timestamp").startAt(startValue).endAt(endValue).on...
So for now that's my query and then I'm running on all results and checking for that one row that has the lowest price. my Data is pretty big and contains around 100,000 rows. I can changed it however I want.
for the first query that gets the lowest price but all timestamps causes that the returned row might be the lowest price but not in my dates range. However this query takes ONLY 2 seconds compared to the second one which takes 20 including my code to get the lowest price.
So, what are your suggestions on how to do it best? I know I can make another index which contains the timestamp and the price but those are different data values and it makes it impossible.
full data structure:
country
store
item
price,
timestamp
just to make it even more clear, I have 2 inner loops which runs over all countries and then over all stores. so the real query is something like that:
ref.child(country[i]).child(store[j]).orderByChild("timestamp").startAt(startValue).endAt(endValue).on...
Thanks!

AngularJS ng-repeat manipulate ID

I am looking for an way to easily manipulate an ID within an ng-repeat. For example lets say I have a customer within a customer table with a customerId. I am using that customerId in another table such as orders. Now when I pull the data from orders for a user to see in an ng-repeat table, I would like to change the customerId to customerName for visual purposes only not actually changing the physical value, just the displayed.
My first though, I can see this is possible when requesting a list of orders in the php script to loop request just the customerName based on the customerId from the customer table and add to the orders array, but this seems very long winded and not as friendly as something I could manipulate in the DOM. My second thought was a filter although ajax requests seem to not be viable option within a filter.
Can anyone point me in the right direction?
Cheers.
Moving to an "answer" so I can format this better.
Assuming you have two tables. Orders with a foreign key column called CustomerID and Customers table that has a primary key column of CustomerID. You would join them with all the Orders fields you want. I don't have mysql so the syntax could vary slightly but this is the idea:
SELECT Customers.CustomerName, Orders.OrderID, Orders.SomeField
FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName
WHERE Order.OrderId = 1234;
This is directly from http://www.w3schools.com/sql/sql_join_left.asp

Search list for objects valid in a time range

I have the following data structure which describes an object and the time period which it's valid. Pretend the numbers below are unix timestamps.
{
"id": 1234,
"valid_from": 2000
"valid_to": 4000
},
{
"id": 1235,
"valid_from": 1000,
"valid_to": 2200,
}
...
I want to quickly be able to store these items in JavaScript and then query for items which are valid at a certain time.
For example if I were to query for objects valid at 2100 I would get [1234, 1235]. If I were to query for objects valid at 3999 I would get [1234], and at 4999 nothing.
I will have a size of about 50-100k items in the structure and I'd like fast lookup speeds but inserts, and deletes could be slower.
Items will have duplicate valid_from and valid_to values so it needs to support duplicates. Items will overlap.
I will need to be continually inserting data into the structure (probably by bulk for initial load, and then one off updates as data changes). I will also be periodically modifying records so likely a remove and insert.
I am not sure what the best approach to this is in a highly efficient manner?
Algorithms are not my strong suit but if I just know the correct approach I can research the algorithms themselves.
My Idea:
I was originally thinking a modified binary search tree to support duplicate keys and closest lookup, but this would only allow me to query objects that are > valid_from or < valid_to.
This would involve me bisecting the array or tree to find all items > valid_from and then manually checking each one for valid_to.
I suppose I could have two search trees, one for valid_to and valid_from, then I could check which id's from the results overlap and return those id's?
This still seems kind of hacky to me? Is there a better approach someone can recommend or is this how it's done.
Imagine you have two lists: initiation/begin and expiration/end. Both are sorted by TIME.
Given a particular time, you can find where in each list the first item is that meets the criteria by binary search. You can also do inserts by binary search into each list.
For example, if there are 1000 items and begin location is 342, then items 1-342 are possible, and if end location is 901, then items 901-1000 in the termination list are possible. You now need to intersect both sublists.
Take item IDs from 1-342 in begin and 901-1000 in end, and put them in a separate array (allocated ahead of time). Sort the array. Traverse the array. Whenever the same ID appears twice in a row, it is a hit, a valid match.

Performance of an ordered list in Firebase

If I want to maintain an ordered list in Firebase, it seems like the best way to do it is to manually assign a priority to each item in my list. That means if I insert or remove an item from the list, I have to update the priorities of all the items following it. For an item at the beginning of the list, this means updating every item in the list. Is there a better performing data structure or algorithm to use in this case?
You can create an ordered list by setting the priority of elements appropriately. Items in a list are ordered lexigraphically by priority, or if the priority can be parsed to a number, by numeric value.
If you want to insert items into the middle of an existing list, modifying the priorities of the existing items would work, but would be horribly inefficient. A better approach is just to pick a priority between the two items where you want to insert the value and set that priority for the new item.
For example, if you had element 1 with priority "a", and element 2 with priority "b", you could insert element 3 between the two with priority "aa" (or "aq", "az", etc).
In our experience, most times when you create an ordered list, you don't necessarily know the position in the list you want to insert the item beforehand. For example, if you're creating a Leader Board for a game, you don't know in advance that you want to place a new score 3rd in the list, rather you know you want to insert it at whatever position score 10000 gets you (which might happen to be third). In this case, simply setting the priority to the score will accomplish this. See our Leader Board example here:
https://www.firebase.com/tutorial/#example-leaderboard
The Ruby gem ranked_model has an interesting approach to this problem. It uses a position integer like many other "acts as list" implementations, but it doesn't rely on re-writing all the integers on each position move. Instead, it spaces the integers widely apart, and so each update may only affect one or two rows. Might be worth looking through the readme and code to see if this approach could fit here.

Categories