So I'm making a simple app to practice backend and I'm trying to create an app where users can create a list, and then add locations from a map interface to said list.
This layout seemed sensible, but I had a few reservations. As it stands, each location would belong to one list - but a feature I'd like to add is the ability to take a location and add it to another list. I imagine this could still be done as so, by giving it a new location id, but it would create a duplicate location.
Would that be an acceptable tradeoff to keep things simple?
Related
Background
I'm creating a layered .net core application to handle tracking campaigns for a board game. Because of this there is a lot of data that comes from the game itself, for example:
Characters
Weapons
Equipment
Missions
Objectives that belong to a mission
Rewards that belong to objectives
Etc
The application is not to manipulate this data. This data is typically printed on cards that come with the board game so it won't change. The only changes it may have are when I manually add new characters or something due to a new expansion being released.
As far as the app is concerned, these are similar to how you might have a lookup table of States in the US. The app needs to list them so you can select them, entities in the domain hold references to them, but their actual data is irrelevant to the application itself. It's just lookup data.
Except there is a lot of this data and some of it is related. For example an objective belongs to a specific mission and a reward belongs to a specific objective.
The Problem
If my application was being designed to manage this data there would be no problem. However this is not the case. It is designed to manage "Campaigns", which are 2-5 players sitting down to play a game with these cards. It is managing "instances" of this data that have additional properties.
For example a new campaign is created and a row is added to the Campaign table. Now a mission must be added to it.
I can't just add a reference to the Mission data because I also need to store the outcome of the mission specific to this campaign. So I create a CampaignMission entity that references the mission data, the campaign id, and has a column for the mission outcome.
But that Mission data had related Objective data. The data just holds things like objective name, description, rewards etc, but in the campaign I also need to store the outcome of this objective specific to this CampaignMission. So again I create a CampaignObjective that references the Objective data, the CampaignMission, and has a column for the objective outcome.
Before you know it I am doing this for everything. CampaignCharacter, CampaignWeapon, CampaignReward. I feel like I'm just replicating the structure of the game data, relationships included.
Where the game data has relationships, my Campaign entities feel like they're mirroring the relationships to the point where, from the same object, you can access the same piece of game data by following two separate paths, the original game data relationship or the Campaign entity "replica" relationship.
For example if I want the name of the first reward for the first objective in the first campaign mission, you can access it in two ways:
Campaign.CampaignMissions[0].Mission.Objectives[0].Rewards[0].Name
Campaign.CampaignMissions[0].CampaignObjectives[0].CampaignRewards[0].Reward.Name
Both of these point to the same piece of game data. I really feel like there should only be one path:
Campaign.Missions[0].Objectives[0].Rewards[0].Name
Where I'm Stuck
I'm not sure if this is normal but it all just feels wrong. Almost as though the game data shouldn't even be part of the application. I mean the game data could be hosted on some 3rd party API and it wouldn't make any difference to my actual application. It's just data I need to read but I feel it's impacting my app structure in ways it shouldn't be.
My application doesn't really need to know the difference between Mission game data and a Mission in a campaign. All it needs to care about is that a campaign can have missions, and those missions have a name etc and an outcome. It doesn't feel like the Mission game data itself needs to be an entity in my domain.
What I've Tried
I tried keeping single entities in my domain and keeping them separate in my database. So for example a Mission in the domain would include both the game data fields like mission name, the mission outcome and a list of domain Objectives.
When a domain Mission for a campaign is requested from the data layer, the entry is retrieved from the CampaignMission table, along with its game data from the Mission table, then flattened via AutoMapper and returned to the domain as a single Mission entity containing everything.
This just caused a bit of a nightmare with Entity Framework and handling the mappings back and forth between data layer and domain because the CampaignMission in the database also had CampaignObjectives which linked to Objectives that also had to be flattened etc, and I had to keep track of the primary keys for all of these throughout my domain so everything could be unflattened and mapped back again when I want to persist something. It just didn't make sense, in terms of tracking primary keys/identity, for a single domain entity to be represented by entries in multiple tables.
What I'm Now Considering
I'm considering just moving all of the game data into a totally separate project, completely unrelated to my application. My application could then query project as though it was some third party API or something and get any data it needs and I can keep it all out of my solution.
Since the game data would no longer have IDs in my application, when I add a mission to a campaign it would simply have a column for "name" which would hold the mission name. When I want to use that mission I would grab it from the db and map it to a domain entity, so at this point it contains the campaign-specific data such as mission outcome, and also the name. Then I'd query the game data project using the mission name and map all the returned data back on to the entity as well, leaving me with a complete entity.
This is essentially replicating the behaviour of what I already tried but removing the need to track identity for the game data by simply using a name that I can query. It removes the concept of backing game data from my domain and leaves me with a single entity, Mission.
The Question
I've wasted a lot of time on this so far and I'm sure it must be a common problem in similar types of applications. I was wondering if anyone had a better solution for dealing with this kind of situation before I go ahead and try completely separating the data.
I have to admit, typing out the "What I'm Now Considering" section has clarified a few things for myself but I would still love to hear if there is a better way.
Thank you in advance if anyone reads all of this.
Here's what you should be doing. First, add the game data entities to the DbContext as DbQuery<T>:
public DbQuery<Campaign> Campaigns { get; set; }
This will allow you to query it, but will not allow changes. Then, since the game data is static, you might want to actually just persist it on a singleton, which you can then inject where you need it.
In either case, on the actual campaign data that's being persisted, you should only store the id of the game data concept. For example, MissionId, not CampaginMission.Mission. When you need the actual Mission info, just look it up based on the MissionId, either directly from your DbQuery<Mission> property on your context or your singleton class.
I'm creating a prototype group list application. I want the following objects:
User
List
Item
Comment
I think that I should structure this as follows:
http://myapp.firebase.io/user/
http://myapp.firebase.io/user/uid/lists/
http://myapp.firebase.io/list/
http://myapp.firebase.io/item/listid/
http://myapp.firebase.io/comment/itemid
where http://myapp.firebase.io/user/uid/lists/ points to list unique id's, http://myapp.firebase.io/item/listid/ points to all item objects for a given list, and http://myapp.firebase.io/comment/itemid points to all comments for a given item.
Does this structure make sense? The reason I did it this way instead of nesting further (i.e. http://myapp.firebase.io/list/listid/item/ for items and http://myapp.firebase.io/list/listid/item/itemid/comment for comments) is because it says in the documentation that whenever you fetch an object you fetch all children. Sometimes (perhaps even most of the time) I want to fetch a list's items, but not each item's comments. I might only want to do that when a user clicks on the item.
In a NoSQL database you should model your data for how you intend to use it. I highly recommend reading this article on NoSQL data modeling.
The top-level structure seems fine and does not violate Firebase's recommendation to limit nesting of data. But there are many other places where you might still make mistakes (which is one of the reasons this question is a bit too broad for Stack Overflow, but I'll try to answer some of it anyway).
I'd separate out the user's lists into a separate top-level node:
/userlists/$uid/$listid
That way the /users/$uid nodes would just contain the user's profile information and you could cheaply show a list of users. You might even consider splitting the most visible aspect of the user profile into another top-level node, to make the showing of such a list even cheaper.
/usernames/$uid
You'll be duplicating data in this case. But storage is (relatively) cheap, and optimizing for the more common reading of data is one of the reasons NoSQL databases can scale so well.
As you may notice, I focus on showing a list of user names, retrieving the lists for a user and accessing the profile for a specific user. These are use-cases and we're modeling the data to fit them.
In a NoSQL database you should model your data for how your app accesses it. I highly recommend reading this article on NoSQL data modeling.
After that, write out your list of use-cases and see how you can most easily access the data for it. Liberally denormalize and occasionally duplicate the data, to fit the use-cases. Use multi-location updates to keep denormalized and duplicated data in sync with its main entity.
I am new to databases and so am having a little trouble thinking in terms of DB design. If this is not the correct place or way to ask this question, I will be happy to move it to the correct place if told.
I am working on a problem where I go through multiple drives on multiple user machines and store a list of directories I want to use and another list I don't want to use for each volume. These directories can be quickly ascertained/verified so these will be modified over time. This is just a starting point to the actual problem I have to solve, which is doing more stuff on the files in the "to use" list above. The code that actually acts on these directories is a different service and so needs this list to use from somewhere.
I am kind of stuck coming up with a way to store this in a DB on the backend. Since these directory lists are different for different users/volumes I do not know how long or how short this list will be. So do I store these in a DB or somewhere else?
EDIT: To make the question a little more generic, if you have a variable number of data (strings) to be shared between two services during computation how do you store them? How do you create a table to store a variable number of items? In code its easy to just store them in a array you can malloc as the need changes. Its much easier to store them to a file but it does not work across services because these services can be located anywhere.
Thanks for any pointers.
I have custom object 'Subject_c' with 3 fields and I have created those objects by uploading a CSV file. Subject_c has a lookup relationship with Leads (Its general for the same user regardless of what lead he is viewing). I am able to insert a related list and I can see that the objects are created under Data Management/Storage Usage. But it shows blank under related list.
You're saying that the custom object has lookup to Lead but then you say Subjects are generic and somehow should be displayed on every Lead page? I don't think it'll work.
Stuff appears on related list only when field Subject_c.Lead_c will be populated with "this" Lead's Id. (please note I've made best guess at the field name). So you'd need to insert separate data for each Lead which can quickly blow your storage usage and will be a pain in the a$$ to maintain later. Is it only for displaying? Or do you plan to later capture some kind of survey results for each Lead?
If it's just for display I think you'll need to embed a Visualforce page in the Lead page layout to achieve that in a saner way. The subjects are specific to current viewing user? Or it's more like a general list, just 3 subjects for whole organisation?
P.S. "object" is like a table in normal database. I think you mixed a bit the difference between table and records / rows of data stored in it.
I'm creating a text-based browser game and need some advice for django model structure. All the examples are from the same project, therefore I will not repeat the same information assuming you've read all the questions from the top to the bottom.
First question
I have an auth app which contains user profile (Player model), alliance app which holds information about all the unions players join and medals app which represents rewards for both players and alliances.
Both users and alliances can have medals assigned so one of the options is to create a M2M field in Player and Alliance models linking to Medal.
Another option would make medals app usable in any other project of mine. This approach includes the use of generic relations in Medal model which links to either Player or Alliance.
Which solution is more django-like or can I do however I want to?
Second question
There will be tasks for players to accomplish. The scenarios of tasks vary greatly, therefore I need some kind of approach to write unique task progress checking code for each task.
Tasks are held in the database containing information about rewards (which are pretty much the same). Where should I write unique code for each task? Maybe I should add some fields and eval() them later? Then all the information will be held in the DB.
Moreover, tasks demand some tracking, for example, imagine a simple task of going to the manual section (just to make sure the player knows where it is). Then I need to register somewhere whether the player has visited manual page or not. I think about creating another model TaskTrackers in task app. Then another question arises. If I should add OneToOne field from Player to TaskTrackers or vice versa?
To sum up, the main question is whether should I add OneToOneFields/M2M fields to user profile model or add OneToOneFields/Foreigneys from target models to User model? The latter would make my apps more reusable, but the first approach may be more logical.
Waiting for answers.
One your first question, you could do either an M2M to Medal, or use a generic foreign key. You'll end up with a couple of join tables with M2M. With the generic foreign key, you won't have any join tables, but you will have the extra query for the content type. So, you may need to set up both ways and see which is going to impact performance more
On your second question, I might take the approach of using a "Task" model with one or more "Step" models that can be set up as an inline formset. Then you'll need a table like "CompletedPlayerTasks" or something like that, which contains the Player ID, Task ID and Step ID. If a Step ID exists in that table, the task has been completed.
It sounds like you need to be able to create custom fields and forms for the Steps of each Task, which isn't terribly hard to do in Django. There are some off the shelf solutions to do this, but you might need to write your own.
Lastly, I wouldn't name the app that holds your user profiles "auth", which could cause a namespace problem with Django's contrib.auth app. I would name it "profiles", just so it's more obvious what that app does and contains.
Hope that gives you some ideas.