phpmyadmin foreign key problems - mysql

here's my situation:
I have this 3 tables:
Material(commercial_name,family,composition) (commercial_name is PK)
Chemical(commercial_name,CAS) (commercial_name is PK)
Compatibility_test(Chemical,Material,result) (Chemical and Material are foreign keys and refers to the PKs of the previous table).
EXAMPLE
I have these materials
M1,M2,M3
I have these chemicals
C1,C2,C3
Now no problem if i wanna instert a test of C3 on M2 or any other combinations with those elements. But if i do a test with a new C4 chemical on for example M2 , that is not allowed cause C4 is not in the Chemicals table yet.
The question is:
Is there a way to insert a test and if the elements of that test are not already in the Materials and Chemicals table they gonna be added , otherwise non changes to those table will be made?
Thank you in advance

The only way to do that by removing the relations between these tables. And already in like these cases 'by logic' you don't need these relations.
Relation to link to table with each other, when you delete 1 row you may delete the related rows or you forbidden deletion if there are related rows and so on. But in you case you don't need that.

Related

Makine a composite foreign key that refers to two differnt tables

I'm making a schema for a hospital data base. I have 4 tables, candidate details, hospital details, position details and interview details. The interview table has a foreign key referring to the candidate table, one to the position's table and I also want it to have one referring to the hospital table but I noticed that it is possible then to have a tuple where the combination of the position id and the hospital id is not the same as the combination that occurs on the position tables (the position table has a foreign key referring to the hospital table) So in other words is makes it possible to enter the incorrect hospital id or position id in the interview table. So for instance on the interview table I could enter a tuple where the position id is 01 and the hospital id is 02 but if you go the positions table, the position id that is being refereed to could easily have a hospital id that is different (eg 03).
I was thinking that there might be away of creating a composite foreign key that refers to two different tables at the same time. If that's not the case, is the only way of resolving the issue, just removing the hospital id column from the interview table completely?
I've been using mySQL workbench so I don't have any of the SQL code on hand but if any extra information (eg ERR image) is required to answer this question I'll try my best to source it.
Short answer :
No, a foreign key constraint always references exactly one parent table.
However, If I understand your situation well, you have 4 tables
candidate details. id
hospital details. id
position details. id, hospital_id
interview details. candidate_id, hospital_id, position_id
The problem is the relation between postion and hospital is many to many
simple way EAV add another table call it hospital_postition, that has all the positions in all hospitals then link each hospital_postition to the condidate in the interview
candidate details. id
hospital details. id
position details. id
hospital_postition. id, hospital_id, position_id
interview details. candidate_id, hospital_position_id
Less is more!
You have this problem because the table isn't in 3rd normal form. hospital_id isn't dependent on the interview, it's dependent on the position, and position_id is not the KEY for this able.
Ask yourself, do I really want to record hospital_id in the interview table? All the information you probably need is already stored in the positions table. The only reason I can think of for wanting that column would be where you were conducting interviews in hospitals other than the one where the position is based. If that is the case then your schema is already correct but your question implies otherwise.
Drop the hospital_id column from the interview table and your problem will magically disappear.
On the subject of getting table definitions (SQL code) out of MySQL Workbench, try this:
Right-click the table name in the schema browser
Select "Send to SQL Editor"
Select "Create statement"

Composite primary key in MySQL on existing table

I am using MySQL workbench to manage my a database that was handed down to me for a development task. Unfortunately, the schema is a nightmare: no primary keys for numerous tables, lots of column duplication, etc.
First off, I wanted to add some uniqueness so that I can begin normalizing somehow. I have a 'students' table where a student (with an ID) works on a project that belongs to a specific term (Fall 2014, Spring 2015, etc.)
Since the same student can work on the same project two semesters in a row for whatever reason, that only way to tell them apart would be to have a (student ID, term) PK. So I actually do need that composite PK.
How might I alter the existing tables and set a composite PK?
EDIT:
To clarify: the schema contains a users table with actual student information (First/Last name, Email, Term). The students table would more aptly be named projects, as it references only the students by ID and then lists the project they worked on, in the semester that they worked on it. So at the very least, students.id would also be a FK from users.
I know the above doesn't quite make any sense; I'm just trying to keep this to one step at a time because the application depends on the schema and I don't want to introduce any new bugs at this point.
To clarify even further, here is how the users and students tables look like:
students
id project termInitiated ...
20 XYZ Summer 2013
20 XYZ Fall 2013
23 ABC Fall 2013
24 ABC Fall 2014
...
users
studentId firstName lastName termInitiated
20 A AA Summer 2013
20 A AA Fall 2013
23 Z ZZ Fall 2013
24 Y YY Fall 2014
...
Unfortunately, due to the way it is setup, I cannot have studentId be a PK by itself as the same student could be working on the same project multiple semesters in a row.
The best fix to this would be a globally unique identifier that could refer to the same student in different terms, but this would introduce a huge amount of bugs right now that I do not have the time to fix. Thus, I think that a composite PK would be the best solution given my limitations.
You may need to grant yourself the alter privilege if the composite key is not being added take a look at this: https://kb.mediatemple.net/questions/788/How+do+I+grant+privileges+in+MySQL%3F#dv
Here is adrian's link :ALTER TABLE to add a composite primary key
My suggestion is that, add a new field in your table for primary key with the unique combination of two fields.
For example in your case, add a field suppose pid in students table:
ALTER TABLE students
ADD pid VARCHAR(100) UNIQUE PRIMARY KEY;
And then update this table:
UPDATE students SET pid=CONCAT(id, '-', termInitiated);
So you will have unique combination of id and termInitiated in pid field.
You can use it as primary key and if you want to select it or join it with other table, you can reference it with combination of two field.
For example,
If you want to join student table with users, you can join it like:
SELECT * FROM users
INNER JOIN students
ON CONCAT(users.studentId, '-', termInitiated) = student.pid);
I hope this will work for you.
Please correct/suggest me, I am wrong.
Thank you.

MySQL - Should every table contain it's own id/primary column?

I'm putting together a question and answers application - the answers are only going to exist as long as there is a question that relates to it.
So I've decided not to give the answers table it's own id column and have made the primary key a foreign key that relates to the question_id.
Questions table:
id | title
Answers table:
question_id | title
Should I keep it this way or give the answers table it's own id column?
If there is possibility of multiple answers for a single question then it will be better to have a primary key on answer table too to identify each row uniquely if we get duplicate answers as follows
id | question_id | title
1 1 5
2 1 5
3 2 true
But, in case you are anticipating only a single answer for each question then it is better to merge it to the question table as both question and answer are directly dependent on a single primary key.
id | question | answer
1 quest 1 ? 5
2 quest 2 ? 5
3 quest 3 ? true
4 quest 4 ? null
I hope, this clarifies your doubt.
To expound a bit on the two valuable comments that have been made, in my experience, the following is the most effective set of rules to follow when defining a database schema (I will give reasons after):
Create a Primary Key for each table
Create a surrogate key to be that Primary Key
When you have a one to many relationship (as you do in your questions & answers tables) include the PK from the one table (your questions table) in the many table (your answers table) NOTE: this is exactly as you have done it... except the answers table doesn't have it's own PK & surrogate key
When there is a many to many relationship between two tables create a linkage/join/relationship table which has a one to many relationship to your two tables (meaning you put the Primary Key of each table into the relationship table as a foreign key to the two tables, respectively)
REASONS (in the same order):
Primary key columns guarantee uniqueness for each row within the scope of the table itself (no other database object has to be involved & every row will be required to be unique). They also provide a default index in most databases, which speeds up table scans/queries. As, mentioned this effectively meets first normal form.
I've found surrogate keys to be a powerful & effective way to simplify both database design & relationships between tables. If you aren't familiar please read here: http://en.wikipedia.org/wiki/Surrogate_key
You have done this already, so I'm assuming you understand the benefits.
This is here simply to provide an example of how using surrogate keys as primary keys in every table can help you as a database schema grows. If you need to add other tables in the future you won't have to spend as much time & effort figuring out how to join them you already have all the keys you need to easily create a join table (for instance, if you later add users to the mix... users can be the author of either a question or answer OR both... this could get a little harry if you attempt to associate the SAME value to both the question & answers tables independently... in fact it won't work)

Can a foreign key act as a primary key?

I'm currently designing a database structure for our team's project. I have this very question in mind currently: Is it possible to have a foreign key act as a primary key on another table?
Here are some of the tables of our system's database design:
user_accounts
students
guidance_counselors
What I wanted to happen is that the user_accounts table should contain the IDs (supposedly the login credential to the system) and passwords of both the student users and guidance counselor users. In short, the primary keys of both the students and guidance_counselors table are also the foreign key from the user_accounts table. But I am not sure if it is allowed.
Another question is: a student_rec table also exists, which requires a student_number (which is the user_id in the user_accounts table) and a guidance_counsellor_id (which is also the user_id in the user_accounts) for each of its record. If both the IDs of a student and guidance counselor come from the user_accounts table, how would I design the student_rec table? And for future reference, how do I manually write it as an SQL code?
This has been bugging me and I can't find any specific or sure answer to my questions.
Of course. This is a common technique known as supertyping tables. As in your example, the idea is that one table contains a superset of entities and has common attributes describing a general entity, and other tables contain subsets of those entities with specific attributes. It's not unlike a simple class hierarchy in object-oriented design.
For your second question, one table can have two columns which are separately foreign keys to the same other table. When the database builds the query, it joins that other table twice. To illustrate in a SQL query (not sure about MySQL syntax, I haven't used it in a long time, so this is MS SQL syntax specifically), you would give that table two distinct aliases when selecting data. Something like this:
SELECT
student_accounts.name AS student_name,
counselor_accounts.name AS counselor_name
FROM
student_rec
INNER JOIN user_accounts AS student_accounts
ON student_rec.student_number = student_accounts.user_id
INNER JOIN user_accounts AS counselor_accounts
ON student_rec.guidance_counselor_id = counselor_accounts.user_id
This essentially takes the student_rec table and combines it with the user_accounts table twice, once on each column, and assigns two different aliases when combining them so as to tell them apart.
Yes, there should be no problem. Foreign keys and primary keys are orthogonal to each other, it's fine for a column or a set of columns to be both the primary key for that table (which requires them to be unique) and also to be associated with a primary key / unique constraint in another table.

mysql - It is ok to have n amount of columns?

I know it's possible to have n amount of columns, but is it proper mysql "coding standard"?
Here is what I'm doing:
I am a table student which includes all the students info including testScores:
student
-------
studId
name
age
gender
testId
Instead of putting each individual test answer within the student table, I made a separate table called testAnswers that will hold each students test results:
testAnswers
-----------
testId
ques1
ques2
.
.
.
quesN
Each entry in the testAnswers table corresponds to a specific student in the table student.
Of course, there will be an admin that will be able to add questions and remove questions as each year the test questions may change. So, if the admin were to remove an answer, than that means one of the columns would be removed.
Just to reiterate myself, I know this is possible to edit and remove columns in a table in mysql, but is good "coding standard"?
The answer is a simple and clear: No. That's just not how you should do it except for very few corner cases.
The usual way to approach this is to normalize your database. Normalization follows a standard procedure that (among other things) avoids having a table with columns names ques1, ques2, ques3 ....
This process will lead you to a database with three tables:
students - id, name, and other stuff that applies to one student each
questions - id and question text for each question
answers - this is a N:M relation between students: student_id, question_id, answer_value
Use two tables!
What you are describing is a one to many relationship as there can be one student to many test scores. You would need to have some id as a foreign key to the student_id and put this id in the testAnswers table. You can then set constraints, which tell the database how to handle removal of data.
As one commenter has mentioned, using one table would result in breaking 1nf or first normal form which basically says that you cannot have multiple values for a single column given a particular record - You can't have multiple test scores for the same user in a given table, instead break the data up into two tables.
...of course 2 tables, also could use 3, just remember to insert a studId column also in the testAnswers table (with REFERENCE to the student table) and an INNER JOIN testAnswers ON student.studId=testAnswers.studId at the SELECT query (to read the data).