Is this relation in BCNF? - relational-database

I have a relation
Competitor(PID, EventName, Pname, TeamName, TeamCoach,EventDate, TeamRating).
and I have my FDs
PID -> Pname
PID --> TeamName
TeamName --> TeamCoach
EventName --> EventDate
TeamName, EventName --> TeamRating
which will form into my relations
Competitor(_PID_, Pname, TeamName*)
Team(_TeamName_, TeamCoach)
Event(_EventName_, EventDate)
Rating(_TeamName_*, _EventName_*, TeamRating)
Entry(_PID_*, _EventName_*)
However, since my candidate key is {PID, EventName}, how can the Team relation be in BCNF if TeamName is not even part of the key?

A set of FDs as written down in your question, applies to a single relation schema. The set of FDs as they apply to a given relation schema, determines what the keys will be to that relation schema.
For example, your set of 5 FDs corresponds to the 7-column relation schema that you started with. And that set of FDs allows to determine that the key to your 7-column relation schema is indeed {PID EventName}.
But if you split that 7-column schema in parts, then this has its consequences for which FDs are still applicable, and to which of the parts.
For example. Suppose you single out
Team(_TeamName_, TeamCoach)
and leave
Competitor(PID, EventName, Pname, TeamName, EventDate, TeamRating).
For each of the individual FDs, you now have to decide to which of the two new relation schemas that individual FD applies.
In the example at hand :
Team(_TeamName_, TeamCoach)
TeamName --> TeamCoach
Competitor(PID, EventName, Pname, TeamName, EventDate, TeamRating)
PID -> Pname
PID --> TeamName
EventName --> EventDate
TeamName, EventName --> TeamRating
You now have not only two relation schemas, but also two distinct sets of FDs that apply to them, respectively. The teamname->teamcoach FD now no longer applies to the (revised) Competitor relation schema, but only to the Team schema. This allows you to conclude that TeamName will be a key to the Team schema.
BTW it will not always be possible to retain all the FDs that you started out with. An FD whose overall set of attributes (left-hand side plus right-hand side) is such that after the schema split, there no longer is any relation schema that includes all those attributes, such an FD can simply no longer be expressed, and must be reinstated in the resulting design as a database constraint that does not take on the form of an FD (/key). That is the issue of "dependency preservation".

Related

Is this table in 1NF or 2NF?

Supposed i have a relational table:
FinalYearProject(supervisor, researchTopic, consultationDay, student)
and the following functional dependencies:
student -> researchTopic
student, researchTopic -> supervisor
researchTopic,supervisor -> consultationDay
From there i determined my minimal superkey is: student where
student -> researchTopic,supervisor, consultationDay
Is it right for me to say that there is partial dependency as supervisor do not depend solely on student based on the functional dependency:
student, researchTopic -> supervisor
Any help will be greatly appreciated.
Since student is the candidate key, supervisor depends on it.
In fact, consider that, given student -> researchTopic, the research topic depends on the student: so in the dependency student, researchTopic -> supervisor the attribute researchTopic is superfluous (the depedency student -> supervisor holds). It is easy to show this by using the Armstrong’s Axioms.
And since a relation is not in 2NF when a non-prime attribute is functionally dependent on a proper subset of a candidate key, there is no such case in this example, and the relation is in 2NF.

Efficient SQL Schema Design with Odd One-to-Many Relationship

I am trying to figure out an effective and efficient way to implement the following relationship between two tables, Lists(ListID, ListName) and Items(ItemID, ItemName, Cost, Description, QuantityNeeded, QuantityPurchased), in a MySQL database:
A list can have many items. However, the Description, QuantityNeeded, and QuantityPurchased attributes in the Items table are specific to a list. For example, say one item has the attributes 1, Paper Towels, 5.99, NULL, 4, 2, and another is 2, Paper Towels, 5.99, NULL, 7, 0. Even though these have the same ItemName and Cost, they are from different lists.
What is the best way I can go about implementing this? I have thought about adding an attribute ListID to the Items table so that every item "knows" which list it is a part of, but this could result in really lengthy WHERE executions (correct?), and I want this to be as efficient as possible.
Application relationships are not between tables, they are among values (or entities so identified) and are represented by tables.
Add
-- list ListID has member ItemId
-- UNIQUE/PK (itemID)
-- FK (listID) references Lists
-- FK (itemID) references Items
Member(ListID, itemID)
Or replace Items by
-- list ListID has member ItemId and item ItemId ...
-- UNIQUE/PK (ItemID)
-- FK (ListID) referencing Lists
ItemsX(ListID, ItemID, ItemName, Cost, Description, QuantityNeeded, QuantityPurchased)
The former is difficult to constrain in SQL to also have the equivalent of FK Items (ItemID) referencing Member, ie every item must be a member of some list. So typically the latter would be used.
Note that
ItemsX = ListID, i.* from Member m join Items i on m.ItemID = i.ItemId
Items = select ItemID,... from ItemsX
Member = select ListID, ItemID from ItemsX
If you don't know the options for straightforward models, you don't know enough to worry about "efficiency". You need more design (including constraints) & querying experience. Your situation is addressed in practically any intro to information modeling via orders & order (line) items instead of lists & items.

Query for generate a tree in UI

Problem:
A student has mother, father, elder sister and elder brother. If the student's parents occupation is teacher, the I want to generate tree in UI by getting data from backend table. For this, I have created a table to store student information like, student id(pk), name of student, gender, address, father,mother, father_occupation, mother_occupation, etc., Also I added one option (checkbox) in UI to find student's relative occupation is teacher or not. If checkbox is true, then occupation column will be update a value true or 1.
For this, one table is enough or more than one table needed? Also how the query should if all in one table and how the query should be if need to maintain in separate tables.
You have a bunch of options for this schema, but for future scale, I would go with a hierarchy type table, and then attribute table(s) for the folks involved in the hierarchy. This would allow you to track student/teacher relationships (with the right attributes) within the same structure.
Table1 would hold your hierarchical information, which would be the relationships between your people:
id | parent_id | other_relationship_attributes
Table2 would hold information about the individual:
id | occupation | gender | etc..
You can then write queries that can traverse your hierarchy and pull relevant info from the individuals table.
If your student info is very different then your parent info (probably), then that second table would make sense to break up into two tables. 1 for your student and one for the parents.
An example of what this might look like in SQL, answering the question "Show me all students where their parents are teachers:
SELECT
student.id,
student.name,
CASE WHEN student.gender = 'F' THEN 'Daughter' ELSE 'Son' END as child_relationship
parent.id,
parent.name,
parent.occupation,
CASE WHEN parent.gender = 'M' Then 'Father' ELSE 'Mother End as parent_relationship
FROM
person as student
INNER JOIN hier on student.id = hier.id
INNER JOIN person as parent on hier.parent_id = parent.id
WHERE
parent.occupation = 'Teacher'

mysql single query for a single database table

i need to specify following in one query: It should include the Activity_name and Child_ first_name and last_name for each child registered for the specified Activity. There is (Football/Art/IT) activities in Activity Table(which has primary_key for each activity). What would be the query that would list children registered for Art activity? Children name's should be displayed in one column. Thanks.
Without providing your table structure, I cannot provide an accurate query.
However, if I were to design a set of tables that store a list of children, a list of activities, and a correlation between the two, it would consist of three tables named "children," "activities," and "linktable" in this example.
children
id
first_name
last_name
activities
id
name
linktable
child_id
activity_id
children stores the names and information of every child, and a unique id. activities stores the names and relevant information about activities, as well as a unique id. Finallly, linktable may be something like "schedule" or "signups" in your system, and should link children to activities and allow for what is called a many-to-many relationship. In other words, one child may participate in many activities, and any activity may be engaged by many children.
The following query is an example of how to see which children are signed up for Art:
SELECT
a.name, CONCAT(c.first_name, ' ', c.last_name) AS child_name
FROM
children c, activities a, linktable
WHERE
linktable.child_id = c.id
AND
linktable.activity_id = a.id
AND
a.name = 'Art';

How do I join multiple tables in SQL whose objects will be modeled using inheritance?

For my university assignment I have to design some basic managment system for sicknesses and all for a school. I have decided to model some basic inheritance in the form of
Person --> Student
Person --> Staff
Person --> Guardian
Person (PersonID, FirstName, LastName)
Student (StudentID (Which references the PersonID), ... )
The reason i decided to do this as I modeled this first in UML and had the inheritance in this.
I have another table which stored Incidents which have both StudentID, StaffID and GuardianID. However I was wondering how I would create a join in mysql which would display all three inherited people's names?
e.g.
Student.FirstName Student.LastName, Staff.FirstName, Staff.LastName etc...
How would I do this?
Or am i doing this completely wrong this way?
Thanks in advance.
http://pastebin.com/m263dd7 - Link to my DDL for the tables.
I have no problem with the database design you've described. It's always a bit awkward to model inheritance in SQL, but you've used the least problematic solution.
Here's a query to answer your question about retrieving the names of a student and staff member for a given incident:
SELECT ps.FirstName, ps.LastName, pf.FirstName, pf.LastName
FROM Incidents i
JOIN Students s USING (student_id)
JOIN Persons ps ON (s.student_id = ps.person_id)
JOIN Staff f USING (staff_id)
JOIN Persons pf ON (f.staff_id = pf.person_id)
WHERE i.incident_id = ?;
I'm assuming the Incidents table looks includes columns such as:
CREATE TABLE Incidents (
incident_id SERIAL PRIMARY KEY,
student_id INT NOT NULL,
staff_id INT NOT NULL,
FOREIGN KEY (student_id) REFERENCES Students(student_id),
FOREIGN KEY (staff_id) REFERENCES Staff(staff_id)
);
Realistically, I'd expect some kind of many-to-many relationship between incidents and each of staff and students. Otherwise, an incident can involve only one student and one staff member?
This is not right. You should have a Person class, and other classes would determine that a certain Person is a Student, Staff, etc. What happens if you have a staff person that is also a student? What happens if the Student graduates?
It is a classic example of impedance mismatch between the relational model and the OO model.
You could have for example three tables:
PERSON
PersonId
LastName
FirstName
STUDENT
StudentId
PersonId
STAFF
StaffId
PersonId
I dont know what the real usage, but it is not a good idea to use inheritence just for reusability.
At first sight, having a Person class in a university management system (something similar) does not seem right.
It would be better you mention the objective/purpose of the assignment - what is is supposed to do.