Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
So I need to design NoSQL Schemas (Mongoose) from next SQL Database.
Image of SQL database
So I have a few questions about how to make those Schemas:
There is a field in table course_student called entryDate. In what Schema do I store this field and how do I connect it to other? (Refers to entry Date of one student to specific course) (Also the case for startDate in course_teacher table)
In Admin, Teacher and Student Schemas, how do I inherit all properties from PersonSchema (is this the case for Discrimantors?), or do I store all of their fields in PersonSchema (the case I don't like, because in case of "admin", teacher and student fields would be all NULL)
(Optional) Also, how to handle non-normalized case of many-many relationship? (Let's say there is no course_teacher table, and teachers & courses are connected with many-many relation)
In Mongo, like in SQL, there are many ways you can structure your data. The key to consider in Mongo, is how do you need to access the data. Try to group data in ways that it matches queries you expect to perform. Using that context, I'll try to answer some of your specific questions:
1) Your asking where to store the entryDate of a student into a class. Do you often pull students independently? Or do you always grab them with their classes? Do you need classes independently?
One option would be to nest classes inside of your students:
Student =>
{
firstName: "John",
lastName: "Smith",
classes: [{
classCode: "EN101",
entryDate: "10/10/2017"
}]
}
You could also have a class object with a list of students if you access it all it once usually:
Class =>
{
classCode: "En101"
students: [{
studentId: 12345,
firstName: "John",
lastName: "Smith,
entryDate: "10/10/2017"
}]
}
If you often reference things separately, you could have a flat table like in your SQL that just has classCode, studentId, studentEntryDate
These objects are all stored together in one table? If so that sounds like a great use of discriminators. like if you just have a People collection. However, I would guess that they are stored separately? Teachers and Students are stored in different collections? In that case you can just have them inherit the same class in code, and they will serialize fine into mongo without any discriminators.
There's multiple ways to handle this. You could create collections for each table and maintain a linking table, but not usually the best way. I would think Teachers and Courses would be one-many not many-many? So each course would have a teacher. If courses do have many teachers, you can just have a list of teachers instead of a field called teacher.
Hope my answers are clear, feel free to comment for more information.
If your pretty new in Mongo, I recommend signing up for some of there free courses. There pretty useful and get you a good foundation.
Good luck on your switch to mongo. It's worth it!
Below are two good resources with comparisons between RDBMS and NoSQL Databases.
https://www.mongodb.com/compare/mongodb-mysql
https://docs.mongodb.com/manual/reference/sql-comparison/
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I have to implement a role system in my app for authorization. We have around 5 kind of roles in our system.
To maintain these roles we have 2 options,
Alternative #1
1.Create an enum in rails Role model,
enum role: {super_admin: 1, translator: 2, approver: 3, sales_admin: 4, marketing_admin: 5, guest: 6}
2.In the Roles table , now we will have ID user_id role_id
Alternative #2
1.Create 2 models Role and Role_User.
Role table will only contain ID | role_name and Role_User will contain ID | user_id | role_id
Which should be preferred?
I would suggest to go for second approach as if in future there is any possibility of additional role there will be no burden for you to create that additional role. With first approach you have to edit your enum for additional roles which you might want to add in future
It depends how baked into your code the roles are. Some systems have a very rigid concept of "admin" or "moderator" or "user" and introducing roles that don't fit those slots can cause chaos. In those cases they're better off left hard-coded. You might have a table simply to convert the internal name into a label, something especially important when translation's involved. "admin" becomes "Administrator", or whatever that means in the other languages your system employs.
If you've got a system that's a lot more adaptable, where the roles table can define arbitrary permissions, then it makes a lot more sense. You can create custom roles that will work within the structure of the system because the system was deliberately engineered for it. A "role" in this cases is just a set of permissions.
An added benefit of the separate table is that users can have multiple roles, if that is something your system requires. Also, storing the different roles in the database should be better for enforcing database-level data integrity, i.e. you can't add nonexistent roles to users.
If you do end up using a separate table for roles and a join table, be sure to add proper indexing to the join table.
Other than that, it really depends on the context and use case. If the system is simple enough, nothing wrong with going the enum way.
In an app like StackOverflow (nothing really related but it's a good example), we have Questions. Each Question in our mongodb collection has an array of Answers, and an array of Votes (either upvoting or downvoting).
In each Answer, it is possible for a User to upvote or downvote it.
So the schema would look something like this:
Question
-> Answers []
-> Votes []
-> value (-1/1)
-> username
-> Votes []
-> value (-1/1)
-> username
-> question_text, etc.
Coming from a MySQL background this schema feels "icky" but I've been assured it's an industry practice.
Now I'm currently required to show each User what they have voted on, both in terms of Questions and Answers.
So if I have to find the Answer that a user has voted on, I would query thusly (in node):
question_collection.find(
{'question.answers.votes.username': username}, function(e,d) {
/* do stuff */}
);
That query goes 4 levels deep. Is this a normal way to do it or should I introduce some normalization in the schema?
One of the strengths of MongoDB is that you can put all relevant information about a Question inside one document, so you need only 1 database query and no joins to get all information to render the Question.
However, if you want to find everything a user has voted on, things get a bit more complicated. You can do what you do, certainly, although it won't win any performance awards.
Alternatively, you can duplicate the data in a smart way to access it in an easier way. For example, you could add two arrays to the User model:
QuestionsVoted: [{ id1: +1}, {id2: -1}, {id3: +1}],
AnswersVoted: [{ id4: +1}, {id5: -1}]
This means you need to keep this data in sync: when a user votes on a question or answer, you need to update both the question and the user. This is not that bad, because the data is written rarely and read often.
If you have other requirements that deal with votes themselves, for example statistics of votes over time, or by geographical region, you might want to create a Vote collection. And yes, you would have to keep the data in sync across 3 collections then.
It is technically possible to create foreign keys in MongoDB, but I would not recommend it in this case. You would lose some of the benefits of MongoDB, because it is not good at joins (it would require 2 separate queries).
You can read more about how to design relationships in MongoDB on their blog.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
About the Program
Excuse the vague title, but I'm rather new to mySQL and databases. I'm a developer in VB.NET and need to create a program that connects to a database. The program is a guide for a game, and part of the program gives you directions to your next objective when you select a mission. For example, from the application (made in WinForms), you select a "mission" from a combo-box control, and a Textbox will populate according to the objectives in the database. A further example could be displayed as this:
You Select "The First Misson" from the Combo-Box control.
The Textbox Control now contains a numerical list of objectives in order, like so:
Locate John.
John asks you to find a weapon
Give the weapon to John
Help John fight off the monster
John asks you to heal him with a potion
Help John reach the portal at the end of the tunnel
Speak to John about your rewards
Now, the question is how may I display a list like the one above using a database? I was reading up on normalization; however, I still do not see how this may be done.
This is an example of the application (just a mock up, but very similar):
Now say the user selected a misson from the Combo-box located at the top of the application. The application would populate like so:
Ideas via Normalization
I understand I could create two seperate tables containing data relating to the misson. For example, I might be able to create a table called "Stages", and a table called "Missons", but I see this as inefficient, not to mention populating the database itself would take ages. I quickly found that you could not (obviously) store a list in a single cell. So being just a programmer, and not someone who works with databases, I this is very frustrating.
(If it may help, I can also alter the application in which is retrieving data from the database to allow a list to be displayed a different way.)
The Overall Issue
There may be "work-arounds" to address this problem, but I don't know what to do. I do not understand how you could display such data using a database. I understand how you connect to the database and retrieve data using queries, just not with a list. Also, an elaborate answer would be much appreciated for a newbie at this like me.
From what I read, you seem to be primarily stuck up on database relationships. No worries! When you want a "list" in a database, this means you are looking for a one-to-many relationship, or a many-to-many relationship. Here is a brief tutorial that explains the differences between these types of relationships.
One of the first steps in database design is to define your entities (i.e. your tables.) In general, your entities will typically be major nouns from your business problem. In this case, you clearly have the following entities (tables): Mission and Objective. The only other data present on your form is a textbox for mission location and a textbox for mission requirements. Both of these fields can be single properties of the Mission table.
The next step is to define your entity relationships. You might define your relationships as follows:
A Mission has one-to-many Objectives
An Objective belongs to one Mission
Finally, lets list out our known properties:
A Mission has a name (text)
A Mission has one location (text)
A Mission has one requirement (text)
Now we can create a basic database schema. So. What would this look like?
Each table has it's own primary key, denoted by the key image in the picture above. The primary key is a unique identifier for a row of data and is usually represented by an integer. The Objective table also has a foreign key, the missionID field. This is how the one-to-many relationship is defined between these tables.
This way, if we create a Mission with missionID 1, we can assign this missionID to many Objectives. Just like a list, but in the syntax of a relational database. See the images below:
In order to retrieve information about both entities at once, you might use a JOIN query. Hope this helps!
You probably should read up on entities and relationships.
Entities are database parlance for things like a game, a mission, a requirement, and a player (a person).
Relationships are database parlance for statements like
each game has one or more missions in it
each mission has one or more requirements in it, displayed in order
zero or more players can be playing each game.
Each table in your rdms is a collection of instances of a particular entity. So, you'll have a requirement table, for example, that will record the following information for each requirement, each in its own row of the table, for example
game_id the game for which this is a requirement
mission_id the mission for which this is a requirement
requirement_ordinal 1,2,3,4 etc for which requirement in sequence this one is.
description the text describing the requirement: "Speak to John about normalizing your rewards."
You may declare that a particular combination of the first three items uniquely identifies each requirement, which is to say that (game_id,mission_id,requirement_ordinal) is the primary key for the requirement table.
Desktop apps like MySQL Developer and MS Access have graphic design tools that let you draw this stuff in a charts. Here's a writeup. http://docs.oracle.com/cd/A87860_01/doc/java.817/a81358/05_dev1.htm This business of entity-relationship modeling can get very elaborate and abstruse, so be careful not to dive in too deep.
Working this all out is what database design is about. I can't design this whole thing for you, but I can offer you some jargon and a conceptual framework to help you figure out how to search for it.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am in the process of converting a database from mysql to mongdb. My question is in regards to lookup tables. Say I have a recipe that can have multiple categories. In mysql, this is achieved with a many-to-many lookup between the recipes and categories tables. In mongodb, I could simply have a recipes collection with a field of categories that contains an array of categories. Text is actually stored in that field, not referenced, like so:
recipe: {
_id: xxxxx,
title: "a recipe title",
categories: ['catone', 'cattwo']
}
So, is this best practice? I prefer this method as it seems easier to maintain than a separate collection and referencing it. But I see two drawbacks. One, if a category name changes, you have to update all records, instead of just updating a single lookup record as in mysql. Second, it would seem inefficient to get a list of available categories to use on say a list of checkboxes on an interface.
I know many others have had to deal with this issue, so I was just trying to find what is considered best practice.
What you are saying is correct. You have to update (find and modify) the embedded categories whenever the name of a category changes. It's your call. You have to decide based on facts like
How many times in production the category names will change
How many categories you have
Based on your scenario, in production I think there won't be frequent change in the name of the category. It should only happen rarely, so I suggest you to embed it and have mechanism to update it, but instead of directly embedding the categories alone, I would embed with Id like below. Otherwise, it will be a performance problem when you want to update and you have to do a string search in order update. If you have id, you can have index on this as well.
So have it like this
recipe: {
_id: xxxxx,
title: "a recipe title",
categories: [{ id: 1,'catone'}, {id:2,'cattwo'}]
}
Also, you have to see how are you going to handle when you have several millions or few billions of records to update. In some cases, you have to update several millions of records not just in one collection but in multiple collections. If you have such a situation, then you have to handle that using a separate update service or something like that. Because if you try to do synchronously it will take a lot of time and you don't want your user to wait this all to complete.
Also remember the embedded array can't be very long like having several hundreds/thousands of items. Mongo will still allow it, but you'll face problems. One more thing to consider is whether additional categories will be added to array after it's created. If so many additional items can added in update, if it's going to many then you many want to read about Padding Factor. Hope this helps.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have 3 types of users:
Admins
Suppliers
Employees
Each user type will have different user interface and access different types of data. Their only similarity is they are using one web application but they access totally different things. Is it better to put them all in one user table like tbl_users or is it better to create tbl_admins, tbl_suppliers, tbl_employees?
What you need to consider when designing tables is not necessarily what they'll have access to and how that is similar/dissimilar, but rather how the user levels themselves are similar/dissimilar.
For example, if the user types will have the same attributes (name, email, birthdate, etc), then they belong in one table together with a column indicating their privilege level.
This also facilitates changing privilege levels for a user, whereby you can make an ordinary Employee into an Admin, for example, by just updating the record in the user table.
If Suppliers are a different type of object with different attributes than the other two, Suppliers may belong in their own table.
Or, one more thing to consider: You might use a users table that holds only very limited information about users of all three types, and if the types have extended attributes that don't relate well to one another, you can store those in other tables with a foreign key back to the main users table.
There is also a third choice: put the columns that all users have in common into tbl_users, and create three tables for tbl_admins, tbl_suppliers and tbl_employees joining to tbl_users as 1 to 0..1. You should consider this choice as an alternative when the number of shared columns is significant.
It depends on how similar their data structures are. If they are similar, then perhaps you could put them all in one table. But, if they have a lot of different fields and you'll end-up with lots of NULL values...and then it's better that they're all in separate tables.
Best to keep all your login info in one place. If you were ever to make a change to your login process, having 3 different tables would mean having to change the code in 3 separate places.
If a user can belong to more than one role, consider making a UserRoles table. Otherwise, adding an additional field to the existing table - such as RoleType - would help differentiate the different types of users.
You should just include them in one table and create a field/attribute that would be an indicator of whether the user is an Admin, Supplier or Employee.
It's simpler if you centralize it that way.
The concern on how/what they access would be under the software you develop. You can either fetch/constrict the UI[or whatever they access in the software system] basing from the type of user you have.
I usually just hide and show stuff according to the type of user I have
Hope this helps..