Relating an entity to two entities or to one relationship between the two entities - relational-database

Suppose I am modeling a many-to-many relationship between a user and a project. That is, a user can be part of multiple projects and a project can have multiple users. This would look something like this:
Project
id: pk
name: string
User
id: pk
name: string
Membership
id: pk
project: fk
user: fk
Here, membership reflects the set of users that are part of the project. So anyone who requires access to information related to the project (e.g. tasks) is added to the project through a membership.
Now I want to add a task to this project that can be assigned to a user. When should one relate this task to a user and project individually? And when to the relationship, which is Membership in this example?
These are the three options I can think of:
Task1
id: pk
name: string
project: fk -> Project.id
assigned_to: fk -> User.id
Task2
id: pk
name: string
project: fk -> Project.id
assigned_to: fk -> Membership.id
Task3
id: pk
name: string
assigned_to: fk -> Membership.id
Task1:
Similar to Task2 except when the user is no longer a member of the project. In that case the user can still have a task assigned. Also, application level logic must prevent a task from being assigned to a user that is not in the same project as the task.
Task2:
Similar to Task1 except when the user is no longer a member of the project. In that case, the reference to membership is lost and a task is left unassigned. Application level logic must prevent a task from being assigned to a membership that is not in the same project as the task.
Task3:
When the user is no longer a member of the project, the task is no longer part of a project. A user can assign a task to any membership since it then automatically is part of a project of which the user is a member.
Edit: I added a few options to explain the trade-off I am trying to understand. I would really appreciate it if someone could validate/invalidate the points I raised or add some points to consider.

Related

Am I allowed to define both many-to-many and one-to-many relationships between User and Server models in Sequelize?

I have 2 models called User and Server and my verbal description of their relationships is something like this:
A User can create Servers and is therefore their owner. Following this logic, I need to implement a one-to-many relationship between these 2 models. That means the Server should have a userId column which will contain the id of the User/Owner.
Users can join many servers and a Server can be joined by many users, so I need to implement many-to-many relationship between these 2 models and have a junction table as well.
So my question is can I apply 2 relationships between the models like this:
let User = require('./models/User');
let ServerUser = require('./models/ServerUser');
let Server = require('./models/Server');
User.hasMany(Server)
Server.belongsTo(User)
User.belongsToMany(Server, { through: ServerUser });
Server.belongsToMany(User, { through: ServerUser });
What makes me think this won't work is this - once a relationship is created, Sequelize offers you some magic methods which you can use. For example in my case I have this:
let name = req.body.name;
let thumbnail = req.body.image;
let userId = req.body.userId
let user = await User.findByPk(userId)
let socketServer = await Server.create({
name: name,
thumbnail: thumbnail
});
user.addServer(socketServer)
Since I've defined a relationship between User and Server, I can use addServer() which does one of two things depending on whether the relationship between the models is one-to-many or many-to-many.
If I've defined many-to-many relationship, executing user.addServer(socketServer) will create a record in the junction table that will link the userId and serverId.
If I've defined one-to-many relationship, executing user.addServer(socketServer) will update the userId column of the server to the id of user
So now that I've applied both relationships between the models, when I execute user.addServer(socketServer), I only update the userId column of the server with the id of the user BUT I don't get a record in the junction table that creates the many-to-many relationship.
This leads me to believe I can only use one relationship at a time but how am I to achieve what I'm trying to achieve without the 2 relationships?
opinion
Your logic you addressed seems to me that User creates server and user within the server creates server on and on. Is the consequence correct?
shouldn't the one user create servers and other users go in to the servers
my suggetion is create one to many among user and server and have privillage table so the one user created the server have the authority to the what ever he or she wants.

Storing Multiple choice answers of a Module Options Form in a Microsoft Access Database

I currently am trying to work out how to create a relational database for a University Module Options form. First you enter your student ID, Name, Surname and select your degree programme e.g. Human Resource Management then choose multiple modules through the form using checkboxes until the total credits for each semester for each programme is chosen.
However in choosing multiple modules and in being a relational database design i am unsure of how to store these multiple answers in the Student Options table as shown below.
I currently have the tables of
Table: Student
Field Names:
Student ID (primary key)
Name
Surname
Table: Programme
Programme (primary key)
Semester 1 Credits (different programmes allow different amount of credits )
Semester 2 Credits (different programmes allow different amount of credits )
Table: Module
Module ID (primary key)
Module Name
Credits
Prerequisite
The last table is one i am struggling with as after the modules are chosen from the form they will be stored in this table and currently have this...
Table: Student Options
Student ID (primary key)
Programme (link to programme table)
However i am unsure what fields to have to store them in without being too cluttered and still having a link to the modules table as shown below which are all stored individually.
Does my modules table need to have a relationship link to the student options table to be a relational database ?
How would i store the multiple modules chosen into the student options form?
Thanks
As for your core problem, I think the database design outlined below should be sufficient:
You should not store both, the modules a student selects and the programme he is enrolled in in the same table. Instead do it like outlined above.
The programme a student is enrolled in should just be a foreign key in the student table, therefore giving you a one-to-many-relation (This is a crucial point though, because this means any one student can only be enrolled in one programme! If your database has to be able to have one student be enrolled in more than one programme, you need a many-to-many-relation there too.).
The modules should be related to a student via a middle table (I called it StudentModule in this case), therefore giving you the desired many-to-many-relation. What you now have to do of course is check via code, if the module isn't already selected by the student (as well as all the other small and big details there are...). But this you would have to do with any database design as far as I know.
As you can see, I also inserted a middle table for the module to programme relation. This is because I assume that one module is eligible for multiple programmes. By relating modules to programmes in this way, you can then check for stuff like "can this student elect this module", ...

Keep collection in db and do a select query over records

I would like to provide some different services to my users; each service has an ID.
The question is, how to keep user selected services in the database?
Should I create a services column in my users table, then store service IDs there?
If yes, how to save them to be able later query database to select users with specific service selected?
Your experiences and advice are welcomed.
Should I create a services column in my users table
If services is plural than it sounds like that column would store multiple values. That's no good. If that's the case then this is a many-to-many relationship, which involves a linking table. Something like this:
Service
----------
ID
etc.
User
----------
ID
etc.
UserService
----------
UserID (FK to User)
ServiceID (FK to Service)
The data being stored in the UserService table is essentially the connection between a given User and a given Service. If there is information regarding that connection (such as the time when the User began using the Service, for example) it would also go on that table. The main point being that the connection itself is an element being modeled, not just the User and the Service.
(Side note: In the above design there is no explicit PK on the UserService table like there is on the other tables. If any given User can only have one connection to any given Service then the combination of those two FK columns can be the PK. If there can be multiple connections, such as subscribing to a service multiple times, then you may want to introduce an explicit PK like the other tables have.)

Laravel ORM: unique combination of fields from pivot table

This question extends the example Eloquent : Working With Pivot Tables provided in the Laravel Documentation.
The relationship here is that a User has many Role objects that it can relate to, and each Role is made up of a number of Task's.
The relationships between these models are:
User and Role:
Each Role may only relate to one User, however a User may have many Role's
A one-to-many relationship
Role and Task
Each Role can have many Task's associated with it, and each Task can belong to several Roles
A many-to-many relationship
In terms of a database schema (MySql), we therefore have:
A users table that has no foreign keys
A roles table with a user_id foreign key
A tasks table
A role-task pivot table
In plain English, the constraint I need to apply is that a user can not be associated with multiple roles that are made up of exactly the same tasks, however two role's can be made up of exactly the same task's
Is there an in-built way to apply this constraint using Laravels Eloquent ORM system? If not, what would be a tidy workaround?
edit:
Eloquent-like description:
User hasMany Role
Role belongsToMany Task
Question: How to prevent assigning to a user multiple roles having exactly the same related collection of tasks

Writing the functional dependency

First module is User module. Administrators, students, lecturers or guests are users who benefit from the system and they take part in this module. Administrator will assign role as student or lecturer for each user. Each role has different privileges that is lecturer can upload the assignment and course materials, create the online quiz and single upload file. Users have information such as user ID, date of registration, date of latest logon, login account, password, first name, last name, and others details needed. Just say that student ID and lecturer ID cannot be the primary key. Therefore, how am I suppose to state that assignment or quiz ID is functionally dependent on lecturer when assignment ID and my quiz ID is a primary key? Based on my functional dependency, I'm not really sure how am I suppose to relate them to functional dependency?
Entity: User
User(user ID, student ID, lecturer ID, guest ID, course ID, assignment ID, quiz ID, file upload, date of registration, date of latest logon, login account, password, first name, last name, e-mail, birthdate)
Functional dependency
user ID -> {student ID, lecturer ID, guest ID, date of registration, date of latest logon, login account, password, first name, last name, e-mail, birthdate}
lecturer ID -> {course ID, assignment ID, quiz ID, file upload}
Full dependency
user ID, lecturer ID -> {student ID, guest ID, course ID, assignment ID, quiz ID, file upload, date of registration, date of latest logon, login account, password, first name, last name, e-mail, birthdate}
First, a functional dependency in the form A->B means that, given one value for A, we can determine one and only one value for B. Both A and B represent sets of columns. (That's why they're written in uppercase letters.)
Keys really have nothing to do with how you state a functional dependency.
If "lecturer id" functionally determines "assignment id" then the FD is "lecturer id"->"assignment id". If "lecturer id" also functionally determines "quiz id", then another FD is "lecturer id"->"quiz id".
If you want to write that more compactly, you can state the two FDs like this.
"lecturer id"->{"assignment id", "quiz id"}
If you assign the letters L, A, and Q, you can state the two FDs like this.
L->AQ
Braces are usually omitted in this notation, because everyone knows they're supposed to be there.
I'm not sure what you're trying to get at with your last section. But in it, the section labelled "Functional Dependency" doesn't express any dependencies; "Full dependency" doesn't express full dependencies, but might express some partial dependencies; "Partial dependencies" doesn't express any partial dependencies; "Transitive dependencies" doesn't express any transitive dependencies.
It is not clear what you are trying to accomplish. And you don't seem to understand the steps that we go through in schema design.
First we determine what application relationships we are interested in. Eg "user [userID] has role lecturer" or "user [user ID] has first name [first name] and password [password] and ...". Each gets a base relation that holds the rows of values that are related that way.
For each relation the meaning of its application relationship determines for every column what sets of columns it is functionally dependent on. Then we find a minimal cover for that. This determines candidate keys. We can pick one candidate key as primary key.
This determines full and partial dependencies of non-prime columns on each candidate key. This allows us to normalize to 2NF by decomposing our relation to separate the non-prime column partial functional depencies on candidate keys into separate relations.
Just say that student ID and lecturer ID cannot be the primary key.
Therefore, how am I suppose to state that assignment or quiz ID is
functionally dependent on lecturer when assignment ID and my quiz ID
is a primary key?
This doesn't make sense. We can't determine the candidate keys until we determine all the functional dependencies. Also: Do you mean {studentID,lecturerID} "can't be the primary key", or do you mean {student ID} "can't" and {lecturer ID} "can't"? Also: What do you mean by "can't"?
We say assignmentID and quizID are functionally dependent on lecturerID in some relation by:
{lecturer ID} -> {assignment ID}
{lecturer ID} -> {quiz ID}
We can combine right hand sides (determined column sets) with the same left hand side set (determiner):
{lecturer ID} -> {assignment ID, quiz ID}
But there other rules like that for finding a minimal cover.
Based on my functional dependency, I'm not really sure how am I
suppose to relate them to functional dependency?
This doesn't make sense. Relate what to your functional dependencies?
If the only functional dependencies for "User" are the ones in the transitive closure of "Functional dependencies" (ie the only FDs are the ones that must be there when those ones are) then a minimal cover is
{user ID} -> {student ID, lecturer ID, guest ID, course ID, assignment ID, quiz ID, file upload, date of registration, date of latest logon, login account, password, first name, last name, e-mail, birthdate}
and the only candidate key is
{user ID}
and there are no non-prime column partial dependencies on a candidate key.