Properly structuring scriptDb for and Inventory System - google-apps-script

We have built a Inventory and Inspection Manager for our gear, each item type can be on a different schedule and can have multiple of the same item. We serialize all items for tracking. My question is how can I structure the scriptDb to only have one object per serial number. Currently I'm storing every inspection and movement separately and just iterate through by serial number. Is there a proper way to have it structured like the following with out overwriting a previous entry inside the inspHx section of the object?
{serialNumber, itemType, manufacturer, expDate, inspHx{multiple entries}}
if I get the item by serialNumber.inspHx and save a new record into it deletes the previous object in the inspHx. How can you continue to add new records to the inspHx of one serialNumber?
Thanks for the advice.

Database design can be a bit of an art and there is usually more than one way of reaching your goal. That said:
Instead of trying to store everything in a single object you might have two object types. There might be two buckets, so to speak, one for each data type. You would need to add an additional parameter to each object identifying its type or bucket. Type: meta or Type: inspHx
Meta data object that contains the information about the item that rarely changes. There should be only one of these per serial number.
2 Inspection objects, one for each inspection with date, status, etc.
Each type needs a common element or KEY which in this case would be the serial number.
When querying you would do two queries using the serial number for meta data and serial number plus any constraints on the inspection objects.
For a bit more see the Tables section at: https://developers.google.com/apps-script/scriptdb#tables

Related

Database design for various objects

I have application where users can create/update info about different objects (flats, rooms, houses, lands, etc.)
Every type of object has different set of parameters.
I see to solutions:
Store all info inside one table
id,title,object_type,rooms_count,house_floors_count,land_area,flat_area, description, etc..
Pros: fast search (because every column has correct datatype, rooms_count - integer, description - text)
Cons: huge denormalization
Store info inside different tables
objects: id,title,object_type,price
object_params: id, param_title, param_type(integer,text,float,etc.)
object_param_values: id_param,id_object,value (column of type text)
Pros: denormalization, frontend guarantees that when object_type='flat', then only parameters for flat are shown to user (in 1. it works like this too)
Cons: value in object_param_values has type text what is bad for speed.
There's a third option, use two tables.
One table to store the basics of the object:
id, title, object_type
Another table to store the parameters:
id, object_id (from the previous table), parameter, data

How to eliminate database table row duplication

I have a question on databases and how information is displayed in regards to Primary and Foreign keys.
For example, there are three tables; Employees, Employee_tickets and Employee_comments.
Each employeecan have multiple tickets and also multiple comments. A foreign key is placed in the Employee tickets and Employee Comments table. My application is built in vb.net with Visual Studio and it is a desktop application. How can I query say.. Employee Name ('Jon Doe') and display all of his tickets in a grid as well as all of the comments people have made on him over time? I have created a View on the sql database which returns all of the information I require but for each ticket listed under ('Jon Doe') the View displays and Employee Name for every single ticket. Is there a way to display the employee name only once and then every ticket listed under that particular individual without displaying the Employee Name again or do I have to make Separate windows to segregate all of this?
This seems like a really dumb question and I cannot for the life of me figure out how to correctly display what is required in this situation.
Here is an example of what I am trying to explain:
So for troy there is one employee name entered in the Employee Names table, There is one CWB ticket entered in the CWB table but there are TWO PQ Cards entered in the PQR Ticket table. How Can I Display only one row for Troy and one Row for his CWB because there are only one of each entered in the tables then the two rows for the PQR Cards under his name?
I have created a view which gathers this information all into the one single view itself then bound the datagridview's to this View.
Your problem has nothing to do with databases. Rather, the issue is that you have an entity (the employee) that has two separate collections associated with it (tickets and comments) and you want to show the contents of both collections.
Doing this in a datagrid is difficult because in its simplest incarnation it's intended to show one collection of like items.
I can think of a number of possibilities:
In your code, convert each collection to a single string value and display that single string value on the row with the employee's name. This conversion could be to comma-separate a stringified version of each item in the collection (as suggested by BS123 in the comments) or could simply be a summary (eg "5 Tickets").
Put the basic employee information in one data grid and then have two additional data grids below it, one bound to the Tickets collection and one to the Comments collection.
Embed data grids directly in the main data grid, one in the Tickets column and one in the Comments column, and bind each one to the appropriate collection in the employee.
Your database structure is correct so don't change that, you simply need to solve the issue of presentation.
What you're missing here is a controller between your view and your model. Your view is presenting exactly what it was given to present - it's up to you to format it.
There are several possible solutions to this, and the correct one partially depends on needs and infrastructure.
If you infrastructure is solid and your needs are near real time, consider dropping separately querying to fill your second and third tables based on what is picked in the first. This will increase the load on the database, but your data will almost always be correct, and the data will come from the database the way you want to see it.
If the database-centered solution is not good for you, LINQ provides some good ways to filter your data into typed collections that would present exactly what you want the user to see.
To get the users:
Dim users = From l In data.lines
Group By FirstName = l.firstName, LastName = l.lastName
Into Tickets = Group, Count()
You can then present this object to your grid. While dynamic typing works here, I think it would be easier to manage view interactions with defined classes. I'll leave that part up to you. Do some searching on LINQ to fill in the rest of the blanks. It's pretty neat stuff.

Best DynamoDB Structure for Implementation

I am working on a save application, basically the user could go to an article and click save to store it in his profile. Instead of using a relational database the Application currently is using dynamodb. Each article has a specific type of article. The way the structure is currently used for this application is:
user-id [string][DynamoDBHashKey]
type-of-article [string] [DynamoDBRangeKey]
json [string]
user-id is the unique identifier for the user, type-of-article is well.. the type of the article, and the json is all the articles saved in a json format. the json format being:
[{article-id: timestamp}, {article-id: timestamp}]
Article #1 ^ Article #2 ^
article-id is (again) the article unique identifier and timestamp is the timestamp for when that article was stored .
Note This was done before dynamodb started supporting for json documents as Map and Lists. And the code is not mine.. It was already done..
So when the application needs to remove an article from saved It calls dynamo to get the json modify the json and then stores it again. When is going to add a new article it does the same thing. Now a problem appeared when I wanted to display all the articles ordered by the timestamps. I had to call to get all the types and merge them in a dictionary to sort them. (In the user profile I need to show all saved articles, no matter what type, sorted) Now the application is taking more than 700 or 900 ms to respond.
Personally I don't think this is the best way to approach this. So i'm thinking on rewriting the previous code to implement the new features from dynamodb (List and Maps). Now my idea for the structure in dynamodb is like this:
user-id [string] [DynamoDBHashKey]
saved-articles [List]
article-type_1
article_1 [Map] {id: article-id, timestamp: date}
article_2 [Map] {id: article-id, timestamp: date}
article-type_2
article_1 [Map] {id: article-id, timestamp: date}
But i'm relatively new to dynamodb, I made some test code to store this in dynamo using list and maps. I did it using the low level api and with the Object Persistence Model.
Now, my question is: is this a better approach or if is not why ? and what would be the better approach.
This way I think I can use the low level Api to only get the saved-articles of article-type #2. Or if I need them all I just call it all.
I would stick with a solution that is a bit more NoSQL-like. For NoSQL databases, if you have nested data models and/or updating existing records, those are often indicators that your data model can be optimized. I really see 2 objects that your application is using, 'users' and 'articles'. I would avoid a nested data model and updating existing records by doing the following:
'user' table
user id as hash key
'article' table
article id as hash key
timestamp as range key
user id (used in global secondary index described below)
article type and any other attributes would be non-key attributes
You'd also have a global secondary index on the article table that would allow you to search for articles by user id, which would look like something (assuming you want a user's articles sorted by date):
user id as hash key
timestamp as range key
article id as projected attribute
With this model, you never need to go back and edit existing records, you just add records that are 'edited' as new records, and you take the one with the most recent timestamp as your current version.
One thing to remember with NoSQL is that storage space is cheap, reads are cheap, but editing existing records are usually expensive and undesirable operations.

Strategy to map multiple filed in a single table to a single field in another table

I am creating a database where different properties of a single object are measured via different sources. I have a table containing list of sources along with source description and source ID. I want to create a table which will list which source I am going to use for which particular measurement for a particular object. So in this table I will have a field for objectID and the propertys which I am going to measure. For each property I want to map a sourceID. The following diagram describes my design
I would like to know what kind of mapping will I have in this case?
It appears to me that I will have to map each individual property column in Object table to sourceID in source table. With this I will have multiple 1:n mappings. Is that alright?
I am using MySQL workbench. Please tell if this can be designed in a better way.
EDIT#1
For each object I would like to query which is the source for a particular "property" field. After getting this info, I will log data for that particular property in a different table using the given source.
If you look at your first statement
"...properties of a single object are measured via different sources..."
you can actually see straight away that you are probably looking for 3 tables. The Source table you propose looks fine. I suggest that Object table though look more like
ObjectId
ObjectName
ObjectDescription
... other object details (except measurement)
Your third table is your Measurement table, which could conceivably look like this
MeasurementId
ObjectId - reference to Object table
SourceId - reference to Source table
DatePerformed
MeasurementValue
Success
Notes etc
The benefits here are
That you don't need to have a specific column in your Object for a specific Source. This becomes very difficult to maintain if you suddenly have more sources.
Not all Objects need a value for each Source, although with this structure you can still determine if an Object is missing Measurement from a particular source easily as well.
You can have multiple measurements stored for an object (separated via the DatePerformed), and using Max(DatePerformed) you can retrieve the latest measurement.
Then you can get a list of results, if you then do
SELECT ObjectId, SourceId, DatePerformed, MeasurementValue
FROM Measurement
WHERE ObjectId = <your Object>
[AND/OR] SourceId = <your source>

Couchbase - Splitting a JSON object into many key-value entries - performance improvement?

Say my Couchbase DB has millions of user objects, each user object contains some primitive fields (score, balance etc.)
And say I read & write most of those fields on every server request.
I see 2 options of storing the User object in Couchbase:
A single JSON object mapped to a user key (e.g. user_555)
Mapping each field into a separate entry (e.g. score_555 and balance_555)
Option 1 - Single CB lookup, JSON parsing
Option 2 - Twice the lookups, less parsing if any
How can I tell which one is better in terms of performance?
What if I had 3 fields? what if 4? does it make a difference?
Thanks
Eyal
Think about your data structure and access patterns first before worrying if json parsing or extra lookups will add overhead to your system.
From my perspective and experience I would try to model documents based upon logical object groupings, I would store 'user' attributes together. If you were to store each field separately you'd have to do a series of lookups if you ever wanted to provide a client or service with a full overview of the player profile.
I've used Couchbase as the main data store for a social mobile game, we store 90% of user data in a user document, this contains all the relevant fields such as score,level,progress etc. For the majority of operations such as a new score or upgrades we want to be dealing with the whole User object in the application layer so it makes sense to inflate the user object from the cb document, alter/read what we need and then persist it again if there have been changes.
The only time we have id references to other documents is in the form of player purchases where we have an array of ids that each reference a separate purchase. We do this as we wanted to have richer information on each purchase (date of transaction,transaction id,product type etc) that isn't relevant to the user document as when a purchase is made we verify it's legitimate and then add to the User inventory and create the separate purchase document.
So our structure is:
UserDoc:
-Fields specific to a User (score,level,progress,friends,inventory)
-Arrays of IDS pointing to specific purchases
The only time I'd consider splitting out some specific fields as you outlined above would be if your user document got seriously large but I think it'd be best to divide documents up per groupings of data as opposed to specific fields.
Hope that helped!