Translation of tricky ER Diagram - sql

I'm doing a project for my Database exam, and I'm stuck at a tricky point. This is an excerpt of my ER diagram:
As you can see, the entity Employee is generalization of Waiter and Cook. Head waiter and Chief cook are specializations of respectively Waiter and Cook. Only chiefs can fullfill an Order (non included in this excerpt) to the supplier. Obiously only one Chief at a time can Fulfil an order (I've made a single Fulfilment relationship to make the diagram less messy).
After remodeling the ER diagram (sorry if I'm not using the correct words, I'm translating in English), this is the result:
So an Employee must have a Role (Waiter, Cook or whatever else), and for each role there could (obviously) be only one Chief. I really don't know if this is correct, the double generalization confuses me a lot.
Next step is the logical diagram (tables), and this is a total mess!
This is a possible solution:
This is a possible translation to the relational model (with an Unique Not Null constraint on FK2 in tblChief) , but it has a weakness: if you change Employees role in tblEmployee, tblChief won't see this error and integrity will be broken. Could adding a FK between tblEmployee(Role) and tblChief(Role) be a good solution? Or would it be ugly/messy?
I've thought of a second possible solution. I prefer it, but still I don't know if it's OK:
Here I've merged the entity Role with the entity Chief in a single table. The field Chief references IDEmployee, again it must be Unique and Not Null.
Are these solutions correct? I'm sure that this will be a big mess when inserting and updating Employees and Roles (AFAIK it can't be done without temporarily removing the integrity checks). Could be this done in a different way?
Sorry for the long post (and for the image links, but I can't post them directly) and many thanks if you'll answer me :)

The last diagram does not make sense.
Each employee has 1 role (this is a FK relationship)
Each role can have one superior role. This is a nullable FK relationship back to the role table. (Itself). Not to employee as you have it.
To find all employees that are managers you would have a select statement like this:
SELECT *
FROM employees
WHERE roleID in (SELECT roleID
FROM role
WHERE superiorID IS NULL)
or
SELECT *
FROM employees E
LEFT JOIN role R ON E.roleID = R.roleID
WHERE R.superiorID IS NULL

Related

Should I use many to many relationship?

I am working on a university project for a library and I have a table USERS with a column
ROLES ( possible values: member, librarian, admin).
I've always heard that I shouldn't use many to many relationships. The reason such a relationship exists here is because a LOAN has user_id for the borrower and Id for the Librarian that was working at the time. (Table LOAN connects to table BOOK with other relationships as authors and genre etc. not needed for this question)
QUESTION
I don't see a way or a point to split this relationship in a many-to-one and one-to-many. Is what I am doing wrong for some reason?
Edit*: Forgot to add FK in my diagram for Librarian_borrowed, Librarian_returned, but they are FK's. Also a librarian can also borrow a book.
Thank you for your time.
P.S. I've thought about splitting the table USERS or using generalization, but I don't see any real benefits and I quite like it this way, keeps things easier for my project. This is not my question but I'm sure someone might comment on it.
No need for m2m relationships. You need to add multiple FKs to LOAN table, one for each relationship to the USER table e.g. borrower_id, librarian_id, etc.
They will each reference a different user record (unless, of course the librarian also borrows a book)

Designing database with entity relations

So I am new in designing databases and I'm trying to represent a db diagram for a system where students can rate professors and school. Also Students and Professors can have their account to login.
Is this a proper presentation and am I missing anything as of entity relations ?
And I wasn't sure if i need to use any inheritance as well ..
Enumerated columns are good indication for bad design.
You need an additional table for values.
Once that done, there is no need to separate school rating from professor rating -
use a general rating table containning the id of the rater (which is always a student in your case) and the id and type (school/professor) of the rated element.
I don't see any reason to put students and professors in different tables.
Think of it as a person table with a role attribute.
If a person can be both, than instead of the role attribute add 2 flags columns - is_student and is_professor.
It looks okay but are you sure the relatioship between SchoolRating and Student should be many to many? Wouldn't a rating just have one student (the student who did the rating)?
Also it's not clear to me why SchoolRating and ProfessorRating have so many value attributes.
Initial Review: Seems solid, may require another table or an expansion of SchoolRating.
When you are designing, focus on what your objects accomplish, the questions of facts they answer.
SchoolRating has values that represent the reviews or are they aggregates of a set amount of teachers? How are these reviews rectified with professor rating...or do they have no relation? (They clearly do in a school...so how does your design accomplish this?)
Why does a student have any direct relation with SchoolRating? Should not this table be a true FACT table for the values scored from the professors and/or some rating system?
Why can a student not have multiple teachers or multiple reviews? If a student fails a class but leaves a review...how does your structure rectify a new review from the same student?
Lastly, do not use the inheritance theory in your relational design. It is utterly incompatible with the relational set theory and the sooner you learn to purge that from your system, the better.
Think on terms of DIMENSIONS and FACTS. Think about cardinality, or how you plan to deal with slowly changing dimmensions, whether database columns will provide efficiency.
Concepts like Star-Schema, Snowflake design, of durable keys, natural keys probably should be consulted whenever you question your design.
At the end of the day, what questions your tables can answer and how the system will access these tables are as important, if not more, to the design methodology as it relates to normalization.

Normalizing database tables

I am quiet new in database designing, I am trying one test case to track students.
In below image, student can either be in school or club. For this I have create on LocationId which act as a global id for where ever the student is.
But the problem is I am depending on TypeId to determine if its Club or school.
So in my data access query I have to make cases. Pseudo code is :
if TypeId == 1
search in club for the LocationId and get the clubId.
else if TypeId == 2
search in school for the LocationId and get the schoolId.
How can I get rid of these cases and still be maintaining the normalized rule.
Thanks a lot for reading. Any comments are welcome.
Good day!
This seems to be a case of table inheritance and there is more than one way to solve it. Your solution with LOC_CONTAINER doesn't work (as you have noticed) as it requires outside code to do the checking.
Take a look at this comprehensive answer about inheritance. You could for example unify SCHOOL and CLUB tables into one table called PLACE or alternatively have both SCHOOL and CLUB columns in the table STUDENT with a constraint that one of them has to be NULL.

Joining 2 primary key columns to 1 foreign key column in the same table

I have a jobs table with a projectmanagerid and a projectdirectorid e.g
jobs
----------------
pk jobid
pk projectmanagerid
pk projectdirectorid
Both these id columns need to link to an employees table using the employeeid pk as the link. Is this good practice or is there a better way?
employees
------------------
pk employeeid
other stuff
This seems OK as long as you're only going to have those two types: Manager and Director. But think about whether you might need to add another employee type, for example Coordinator, in the future. If that's a possibility then you've got a many-to-many relationship between jobs and employees that you should resolve by using an intermediary junction table, perhaps also adding a third table to describe the employee's role on the job (Manager, Director, ...).
Nothing wrong with it and it's perfectly acceptable. The field names are descriptive and thereby signify that you do actually need to have two different FKs pointing at the users table. if it was x and y, then it'd look weird.
Seems quite reasonable -- and common in many heirarchies -- to have two relationships to the same table. As with all foreign keys, but perhaps even more so in this case, use cascading carefully. I'm guessing that deletion of the manager or director should not result in deletion of the job record.
There is a rule of thumb that states a table models an entity/class or the relationship between entities/classes but not both. Therefore, consider creating two relationship tables to model the two relationships, project managers and project directors respectively. I don't recommend Joe Stefanelli's employee_role_id approach. I think you will find that the attributes for each role (yes, relationships do indeed have attributes too) will be too different to make the generic table approach to add value.

Relational Database Design (MySQL)

I am starting a new Project for a website based on "Talents" - for example:
Models
Actors
Singers
Dancers
Musicians
The way I propose to do this is that each of these talents will have its own table and include a user_id field to map the record to a specific user.
Any user who signs up on the website can create a profile for one or more of these talents. A talent can have sub-talents, for example an actor can be a tv actor or a theatre actor or a voiceover actor.
So for example I have User A - he is a Model (Catwalk Model) and an Actor (TV actor, Theatre actor, Voiceover actor).
My questions are:
Do I need to create separate tables to store sub-talents of this user?
How should I perform the lookups of the top-level talents for this user? I.e. in the user table should there be fields for the ID of each talent? Or should I perform a lookup in each top-level talent table to see if that user_id exists in there?
Anything else I should be aware of?
before answering your questions... i think that user_id should not be in the Talents table... the main idea here is that "for 1 talent you have many users, and for one user you have multiple talent".. so the relation should be NxN, you'll need an intermediary table
see: many to many
now
Do I need to create seperate tables to store sub-talents of this
user?
if you want to do something dynamic (add or remove subtalents) you can use a recursive relationship. That is a table that is related to itself
TABLE TALENT
-------------
id PK
label
parent_id PK FK (a foreign key to table Talent)
see : recursive associations
How should I perform the lookups of the top-level talents for this
user? I.e. in the user table should
there be fields for the ID of each
talent? Or should I perform a lookup
in each top-level talent table to see
if that user_id exists in there?
if you're using the model before, it could be a nightmare to make queries, because your table Talents is now a TREE that can contain multiple levels.. you might want to restrict yourself to a certain number of levels that you want in your Talent's table i guess two is enough.. that way your queries will be easier
Anything else I should be aware of?
when using recursive relations... the foreign key should alow nulls because the top levels talents wont have a parent_id...
Good luck! :)
EDIT: ok.. i've created the model.. to explain it better
Edit Second model (in the shape of a Christmas tree =D ) Note that the relation between Model & Talent and Actor & Talent is a 1x1 relation, there are different ways to do that (the same link on the comments)
to find if user has talents.. join the three tables on the query =)
hope this helps
You should have one table that has everything about the user (name, dob, any other information about the user). You should have one table that has everything about talents (id, talentName, TopLevelTalentID (to store the "sub" talents put a reference to the "Parent" talent)). You should have a third table for the many to many relationship between users and talents: UserTalents which stores the UserID and the TalentID.
Here's an article that explains how to get to 3rd NF:
http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx
This is a good question to show some of the differences and similarities between object oriented thinking and relational modelling.
First of all there are no strict rules regarding creating the tables, it depends on the problem space you are trying to model (however, having a field for each of the tables is not necessary at all and constitutes a design fault - mainly because it is inflexible and hard to query).
For example perfectly acceptable design in this case is to have tables
Names (Name, Email, Bio)
Talents (TalentType references TalentTypes, Email references Names)
TalentTypes (TalentType, Description, Parent references TalentTypes)
The above design would allow you to have hierarchical TalentTypes and also to keep track which names have which talents, you would have a single table from which you could get all names (to avoid registering duplicates), you have a single table from which you could get a list of talents and you can add new talent types and/or subtypes easily.
If you really need to store some special fileds on each of the talent types you can still add these as tables that reference general talents table.
As an illustration
Models (Email references Talents, ModelingSalary) -- with a check constraint that talents contain a record with modelling talent type
Do notice that this is only an illustration, it might be sensible to have Salary in the Talents table and not to have tables for specific talents.
If you do end up with tables for specific talents in a sense you can look at Talents table as sort of a class from which a particular talent or sub-talent inherits properties.
ok sorry for the incorrect answer.. this is a different approach.
The way i see it, a user can have multiple occupations (Actor, Model, Musician, etc.) Usually what i do is think in objects first then translate it into tables. In P.O.O. you'd have a class User and subclasses Actor, Model, etc. each one of them could also have subclasses like TvActor, VoiceOverActor... in a DB you'd have a table for each talent and subtalent, all of them share the same primary key (the id of the user) so if the user 4 is and Actor and a Model, you would have one registry on the Actor's Table and another on the Model Table, both with id=4
As you can see, storing is easy.. the complicated part is to retrieve the info. That's because databases dont have the notion of inheritance (i think mysql has but i haven't tried it).. so if you want to now the subclases of the user 4, i see three options:
multiple SELECTs for each talent and subtalent table that you have, asking if their id is 4.
SELECT * FROM Actor WHERE id=4;SELECT * FROM TvActor WHERE id=4;
Make a big query joining all talent and subtalent table on a left join
SELECT * from User LEFT JOIN Actor ON User.id=Actor.id LEFT JOIN TvActor ON User.id=TvActor.id LEFT JOIN... WHERE User.id=4;
create a Talents table in a NxN relation with User to store a reference of each talent and subtalents that the User has, so you wont have to ask all of the tables. You'd have to make a query on the Talents table to find out what tables you'll need to ask on a second query.
Each one of these three options have their pros and cons.. maybe there's another one =)
Good Luck
PS: ahh i found another option here or maybe it's just the second option improved