I would like to construct a database of the following nature:
There are different types of people, and each person does many jobs, example:
cleaner: clean toilet, clean kitchen
maid: do laundry, cook breakfast, cook lunch
gardener: plant flowers, water flowers
I will also have a MySQL database with all of the cleaners, maids, gardeners, etc. The user will write which job he needs into an HTML form and then the PHP file will determine who does the desired job and then select the most appropriate person for the job.
How do I structure the above database? Do I do it just as I did above?
How does PHP "put them together"? Must I use arrays?
Should I put this database directly into the PHP code or in a separate text file (or other kind of file)?
Thanks everyone!
As indicated in the other post, you need to learn basics before you dive into something complicated. There are ample tutorials on web which are easy to understands and get started with.
You may start with this tutorial to get a grasp of working with MySQL and PHP, and then you can use the following schema for your web-application.
people
people_id (PK)
name
roles
role_id (PK)
role_name
tasks
task_id (PK)
role_id (FK)
task_desc
people_roles
pr_id (PK)
people_id (FK)
role_id (FK)
people -- all the employees/people and their details
roles -- all the available roles
tasks -- tasks that each role is assigned, role and task has one to many relationship (see the FK?)
people_roles -- this is a link table that makes may-to-many relation ship between people and roles, so that a gardener can be act as a cook. If you wish to assign so.
Hope this helps.
You need to learn to walk before you can run.
I would do some basic PHP/MySQL tutorials first to get yourself familiar with the very basics of data manipulation. Then maybe to speed up production use a framework, CakePHP would by my recommendation based on it's powerful auto-magic CRUD (Create, Read, Update, Delete - something else to read up on :) ).
Related
i want to create a platform by laravel 6 included classes students an masters
masters can put the student's scores and the students can see them in their profile...
there is a many to many relation between classes and masters and between student and classes too.
the masters an students are not seperated and all of them store in user table and determine by his role_id
my big issue is uploading of scores by masters... i am extremely confused
has any one any idea ?
What you might want to simplify things is an associative table of users, classes, and scores (I've drawn a diagram for you https://dbdiagram.io/d/5e9787f039d18f5553fdabb1). With this table, you can query pretty much all you could ever want.
Now all you need to do is configure privileges based on user role. A master can read from and write to all class_user_score entities where if there is a record of him being in a class, he can read and CRUD all class_user_score entities with the same classId. A student can only read class_user_score entities with his userId in them.
Unfortunately, I can't help you with the Laravel implementation (they also call an associative table a pivot table for some weird reason) since I'm more of a React, Nodejs type of guy, but I hope this at least helps you to reason about the problem.
I am building a PHP app that has 3 basic entity types: Coach, Student, Lesson, where coaches create digital lessons for students. I'm using MySQL and innoDB tables.
Requirements
Coach and student login.
Coach can deliver a digital lesson specifically for a single student.
I'm unsure what is the best DB schema to use given the requirements. Here are two options:
Option 1
User (PK id, user_type (coach or student), firstname, lastname, email, password, etc...)
Lesson (PK id, FK coach_user_id (ref: User.id), FK student_user_id (ref: User.id), lesson_name, etc…)
Pros:
- One user table
- Each user has a unique ID and email
- Makes login auth easy with single table
Cons:
- No validation of user_type when a coach or student User.id is recorded as a FK in the lesson table. This problem will reoccur in any new table where a coach or student User.id needs to be recorded as a FK.
- Potential polymorphism issues and the need to normalise down the track.
Option 2
Coach (PK id, firstname, lastname, email, password, etc...)
Student (PK id, firstname, lastname, email, password, etc...)
Lesson (PK id, FK coach_id (ref: Coach.id), FK student_id (ref: Student.id), lesson_name, lesson_text, etc…)
Pros:
- Normalised DB schema. Independent coach, students entity tables.
- No user type validation issues. Coach ID and student ID FK's point independently to Coach.id and Student.id respectively.
Cons:
- Coach and student can have the same ID. (This can be solved though with ID prefixes e.g. C1001, S1001)
- Coach and student can have the same email.
- Login auth involves querying two 2 tables for single login page, or creating 2 different login pages and auth request types.
I'm really torn which is the best way to go. Is there a better way to do this?
In my opinion, both of your approaches would work. The first one is more universal, and capable of fitting various currently unknown requirements . If you choose it, I'd recommend to add concept of Role to the model - "user_type" is a role, and one user can be associated with different roles [at the same time]. Also, "The Data Model Resource Book" by Len Silverston is a great resource .
However, you may not always want your schema to be too general. You listed pros and cons for 2 approaches on very low level; I think that practicability is more important than particular technical issues (which can be overcome ). I'd put it that way :
1) Pros :
easy to accommodate new features without major changes to schema
very flexible
easy to build cubes on top of the schema
fits long term projects
Cons :
requires more resources (experienced DBA/Data Model specialist[s], comparatively longer design time )
way more complex than (2)
2) Pros :
fast delivery of first working version
quite easy for understanding even by non-technical people (until it grows up)
fits either small projects or projects with well-defined domains which [almost] never change
Cons :
never ending refactoring of schema as new requirements come
if project lives long enough, database becomes full of "not used anymore" columns(or other db objects) nobody wants to touch
harder to enforce integrity
I hope it makes sense and helps you to make the right decision which fits your needs.
Option 1 looks better to me.
It will simplify your code when you don't care to distinguish students from coaches, and will be pretty much the same as option 2 if you want to distinguish them.
If you really need to validate the foreign keys you can use triggers to check if its a coach or not.
I'm not sure what you mean by "Potential polymorphism issues and the need to normalise down the track.".
I've done quit a bit of programming with php/mysql on small scale personal projects. However I'm working on my first commercial app that is going to allow customers or businesses to log in and perform CRUD operations. I feel like a total noob asking this question but I have never had to do this before and cannot find any relevant information on the net.
Basically, I've created this app and have a role based system set up on my data base. The problem that I'm running into is how to separate and fetch data for the relevant businesses or groups.
I can't, for example, set my queries up like this: get all records from example table where user id = user id, because that will only return data for that user and not all of the other users that are related to that business. I need a way to get all records that where created by users of a particular business.
I'm thinking that maybe the business should have an id and I should form my queries like this: get all records from example where business id = business id. But I'm not even sure if that's a good approach.
Is there a best practice or a convention for this sort data storing/fetching and grouping?
Note:Security is a huge issue here because I'm storing legal data.
Also, I'm using the latest version of laravel 4 if that's any relevance.
I would like to hear peoples thoughts on this that have encountered this sort problem before and how they designed there database and queries to only get and store data related to that particular business.
Edit: I like to read and learn but cannot find any useful information on this topic - maybe I'm not using the correct search terms. So If you know of any good links pertaining to this topic, please post them too.
If I understand correctly, a business is defined within your system as a "group of users", and your whole system references data belonging to users as opposed to data belonging to a business. You are looking to reference data that belongs to all users who belong to a particular business. In this case, the best and most extensible way to do this would be to create two more tables to contain businesses and business-user relations.
For example, consider you have the following tables:
business => Defines a business entity
id (primary)
name
Entry: id=4, name=CompanyCorp
user => Defines each user in the system
id (primary)
name
Entry: id=1, name=Geoff
Entry: id=2, name=Jane
business_user => Links a user to a particular business
user_id (primary)
business_id (primary)
Entry: user_id=1, business_id=4
Entry: user_id=2, business_id=4
Basically, the business_user table defines relationships. For example, Geoff is related to CompanyCorp, so a row exists in the table that matches their id's together. This is called a relational database model, and is an important concept to understand in the world of database development. You can even allow a user to belong to multiple different companies.
To find all the names of users and their company's name, where their company's id = 4...
SELECT `user`.`name` as `username`, `business`.`name` as `businessname` FROM `business_user` LEFT JOIN `user` ON (`user`.`id` = `business_user`.`user_id`) LEFT JOIN `business` ON (`business`.`id` = `business_user`.`business_id`) WHERE `business_user`.`business_id` = 4;
Results would be:
username businessname
-> Geoff CompanyCorp
-> Jane CompanyCorp
I hope this helps!
===============================================================
Addendum regarding "cases" per your response in the comments.
You could create a new table for cases and then reference both business and user ids on separate columns in there, as the case would belong to both a user and a business, if that's all the functionality that you need.
Suppose though, exploring the idea of relational databases further, that you wanted multiple users to be assigned to a case, but you wanted one user to be elected as the "group leader", you could approach the problem as follows:
Create a table "case" to store the cases
Create a table "user_case" to store case-user relationships, just like in the business_user table.
Define the user_case table as follows:
user_case => Defines a user -> case relationship
user_id (primary)
case_id (primary)
role
Entry: user_id=1, case_id=1, role="leader"
Entry: user_id=2, case_id=1, role="subordinate"
You could even go further and define a table with definitions on what roles users can assume. Then, you might even change the user_case table to use a role_id instead which joins data from yet another role table.
It may sound like an ever-deepening schema of very small tables, but note that we've added an extra column to the user_case relational table. The bigger your application grows, the more your tables will grow laterally with more columns. Trust me, you do eventually stop adding new tables just for the sake of defining relations.
To give a brief example of how flexible this can be, with a role table, you could figure out all the roles that a given user (where user_id = 6) has by using a relatively short query like:
SELECT `role`.`name` FROM `role` RIGHT JOIN `user_case` ON (`user_case`.`role_id` = `role`.`id`) WHERE `user_case`.`user_id` = 6;
If you need more examples, please feel free to keep commenting.
Let us say I have two different entities on a site.
Teachers and Students.
They both login to the website.Right now I have the following tables
**Users**
- id
- email
- password
**Students**
- GPA
- SAT
- ACT
- user_id references Users ID
**Teachers**
- user_id references Users ID
- classroom_no
- salary
- average_class_size
So when a Student registers I add a row in both the Users and Teacher table.
When a Teacher registers, I add a row in both the Users and Teacher table.
Is it better to just have ONE table Users with the following fields?
**Users:**
- id
- ACT
- GPA
- SAT
- average_class_size
- salary
- classroom_no
- role (0 = teacher 1 = student)
even though some rows would refer to teachers (and thus not use the ACT, SAT, GPA fields)
??
Thanks!
If you are not familiar with database normalization, please read this.
Unless performance is a serious issue, I would not look at using a single table for this structure. As your project goes one, you will more than likely add more fields to each role and possibly add more roles as well. It will become increasingly more difficult to maintain this.
I would actually go a step further and introduce another concept called role into your application, along with the appropriate data model to persist it.
Your tables should be:
users:
- id
- email
- password
roles:
- id
- type
user_roles:
- user_id
- role_id
role_teacher:
- user_id
- classroom_no
- salary
- average_class_size
role_student:
- user_id
- GPA
- SAT
- ACT
Having a separate role table will let you separate your authentication table (users) from the rest of the data. This might become important if a user can be both a teacher and a student.
This should give you a basic understanding of how to structure your database.
You may find that you will begin to model some of the other concepts like classes in your system. So adding the appropriate tables may look something like:
role_teacher:
- user_id
- salary
classroom:
- id
- capacity
class:
- id
- name
- teacher_id
- classroom_id
- start_date
- end_date
class_enrollment:
- class_id
- student_id
- enrollment_date
- grade
Items like the teachers class room now moves to the class, allowing for the teacher to teach multiple classes (maybe you need to re-add the concept of "home room"). The teachers average class size then just becomes a calculation (though you may want to still store it for the sake of efficiency).
Hope this helps guide you in the right direction!
You should to go with Teachers and Students tables. Tables in database should reflect real world model (whenever it's possible of course). Merging everything into single User table brings very little value and introduces following issues:
redundancy (teacher doesn't need ACT, GPA and so forth fields as you mentioned)
complexity (you'll need extra logic to determine whether user is student or teacher)
ambiguity (is user a system user, or real world person data, or just login information...?), term is far too generic
On top of that, I'd rename Users table to UserLogins - it indicates its purpose more clearly.
My feeling is that it's better the way you have it - you have to maintain both tables so that they're in sync, but you've better encapsulated the role of "User", "Student", and "Teacher" this way. It also leaves you a better maintenance footprint - what if you want to allow a "Parent" to log in with a reference to their child? What about a "Principal"? These are all users, but would quickly gum up the unified table.
There are a couple of ways to do this, but I think one table for users is the right way to go. You could have the empty columns - it doesn't look the greatest, but if it works for you, it would allow minimal coding to get the values you need.
Another option might be to have an attributes table { UserId, Attribute, Value }, then for example, you could have: User1 GMAT 710, User1 ACT 30, etc. So you could then get a list of all attributes for a user by select * from attributes where UserId = user.UserId or some such. More code overhead, much cleaner. This would also allow you to add more attributes in the future for whatever purpose, and keep your database the same.
If one teacher can take multiple classes, then your design fails, as the teacher table will have a multiple entries..
Instead Create one Teacher Table where we can store Teacher Table, create one intermedite table, where we can store the Teacher and His classes.
Similarly, Teacher and User table should be separate..
Let a separate User Table exists where we can store the Use details..
I am developing a social network for an intranet, and I came across a problem [?]. I have the entities User and Business as main entities of the network.
Note: A Business does not have, necessarily, a relationship with a User.
Following this idea, I have a group table, and a group can be created either by a user or by a business, there comes a question, how can I make the author field in this table?
I did the following, I created a table type, with the following data:
id | name
1 user
2 business
And my table groups like this:
id
name
description
tid (FK -> type.id)
author (INT)
Thus, if a group has a tid equals to 1, means that the author is referring to a User, if it have tid equals to 2, it is referring to a Business.
What do you think about this implementation? It is correct?
What can I do to improve it?
I'm using PHP 5.3.6 (Zend Framework and Doctrine2) + MySQL 5.1.
Per request:
The terminology for this is "polymorphic". Bill Karwin had a good answer that I can't find at the moment about it. From a database design perspective, I've been told the logical model term for this is an "arc" relationship. Either way, I see no issues with what you posted, other than supporting multiple authors.
The bad thing about this is that you cannot use the foreign key constraints to check and verify your data if you do this.
I would recommend using 2 tables instead. one to store the relationship between user and group, and one to store the relationship between business and group.
This will allow you to use all the fk benefits like cascading deleted when the group or business or user is deleted.