database using foreign keys - mysql

please excuse me if i'm doing things wrong, as I am new to this forum.. I am trying to figure out what columns to have for foreign keys... My teacher redid my database and i can't understand what to do. Here is my ERD: http://s1.postimg.org/3l2j6rh4v/Picture.png
I have looked up tutorials but I can't seem to find out how to use them..
Here is my MySQL code:
DROP TABLE PaymentType;
DROP TABLE ProjectType;
DROP TABLE Projects;
DROP TABLE Payment;
DROP TABLE Customer;
CREATE TABLE Customer
(
Customer_ID varchar(100) NOT NULL,
FName varchar(15) NOT NULL,
LName varchar(20) NOT NULL,
CustAddress varchar(20) NOT NULL,
CustCity varchar(30) NOT NULL,
CustState varchar(20),
CustZip char(5),
CustBal numeric(7,2) NOT NULL,
PRIMARY KEY (Customer_ID)
);
CREATE TABLE Payment
(
Payment_ID varchar(100) NOT NULL,
PaymentType varchar(15),
Date date NOT NULL,
AmntPaid numeric(7,2) NOT NULL,
PRIMARY KEY (Payment_ID)
);
CREATE TABLE Projects
(
Project_ID varchar(100) NOT NULL,
ProjectType varchar(30) NOT NULL,
LaborHrs char(3) NOT NULL,
Date date NOT NULL,
PRIMARY KEY (Project_ID)
);
CREATE TABLE ProjectType
(
Project_ID varchar(100) NOT NULL,
ProjectDesc varchar(100) NOT NULL,
PRIMARY KEY (Project_ID)
);
CREATE TABLE PaymentType
(
Payment_ID varchar(100) NOT NULL,
PaymentDesc varchar(100) NOT NULL,
PRIMARY KEY (Payment_ID)
);
Hopefully I didn't do anything wrong, thanks!

1) You should change your types for the id columns. Using varchar as id column should be avoided, as this will just blow off the performance (+ some other problems which might occur). Using any type of int (int, tinyint,..) would be much better.
2) The table "ProjectType" should have a column "ProjectType_ID" instead of "Project_ID" - same goes for the PaymentType ("PaymentType_ID").
3) Rename the fields in "Project" and "Payment" table as well.
4) The code for foreign-keys will look like:
ALTER TABLE Project
ADD CONSTRAINT Project_ProjectType
FOREIGN KEY (ProjectType_ID)
REFERENCES ProjectType(ProjectType_ID);
Do the same with Payment table.
Important: add "alter table"-command to the end of your sql file, so all tables are created
Important: your database schema should be innodb, or any other schema which supports foreign-keys (MyIsam does NOT support foreign-keys)
5) For the relation between Customer and Projects you will need an extra table (so one project can have multiple users | might be a change to your erd). A cross-relation table (called something Like CustomerProject) with fields "Project_ID" and "Customer_ID". Then add a foreign-key to the project table and add a foreign-key to customer table. (extra points for adding a unique key to "Project_ID" + "Customer_ID")
For the payment and user, just add a "Customer_ID" field in "Payment" table and add a foreign-key as explained in #4.
(offtopic): your naming convention is a bit wierd. Mixing underscore and camelcase should be avoided. You can just stick to camelcase - even for your id fields - but this is just a personal opinion

Related

Can't add foreign key to mysql

I have multiple tables and they all seem to be fine but there is this one table which I'm trying to create but it wont work because I am keep on getting Error1005 "Foreign key constraint is incorrectly formed".
These are the two tables. I don't know what seems to be the problem.
CREATE TABLE Patient(
ID INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
Name VARCHAR(255) NOT NULL,
Age TINYINT UNSIGNED,
Sex VARCHAR(10),
Contact INT(11),
Email TEXT(2083),
PRIMARY KEY(ID)
);
CREATE TABLE Appointments (
Appointment_No INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
Name VARCHAR(255) NOT NULL,
Contact INT(11),
Date DATE NOT NULL,
Time TIME NOT NULL,
Reason TEXT(2083),
PRIMARY KEY(Appointment_No),
FOREIGN KEY (Name, Contact) REFERENCES Patient (Name, Contact)
);
As per me, table structure should be like below:
CREATE TABLE Patient(
ID INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
Name VARCHAR(255) NOT NULL,
Age TINYINT UNSIGNED,
Sex VARCHAR(10),
Contact INT(11),
Email TEXT(2083),
PRIMARY KEY(ID)
);
CREATE TABLE Appointments (
Appointment_No INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
Patient_ID INT UNSIGNED NOT NULL,
Date DATE NOT NULL,
Time TIME NOT NULL,
Reason TEXT(2083),
PRIMARY KEY(Appointment_No),
FOREIGN KEY (Patient_ID) REFERENCES Patient (ID)
);
FOREIGN KEY (Name, Contact) REFERENCES Patient (Name, Contact)
The referenced columns in the Patient table must be part of a key. Ideally you would want Patient (Name, Contact) to be a unique key, because then the foreign key is guaranteed to reference exactly one row in the Patient table.
But in your table definition, the Name and Contact columns are not part of a key. That explains why you got the error given your table design.
But your table design is not good. Name and Contact are not good choices as a unique key, because two people can share a name, and in theory you could even have two people with the same name with the same contact details (for example, the former boxer George Foreman named his five sons George).
#Shadow is correct that it's a better idea is to reference Patient(id) instead, because it's guaranteed to be unique already.
Define Engine so sql statement would end with
ENGINE = MyISAM;
It should fix the issue.
Try to split the two foreign keys in two lines like this:
FOREIGN KEY (Contact) REFERENCES Patient (Contact)
FOREIGN KEY (Name) REFERENCES Patient (Name)

Getting errno: 150 in MySQL while trying to use composite keys

I'm new to both this site and databases. I am creating a database for a point of sale for a company. Im having problems since I have so many composite primary keys okay so here is my question... I have the table member:
DROP TABLE IF EXISTS member;
CREATE TABLE member (
fName varchar(10) NOT NULL,
lname varchar(10) NOT NULL,
shippingAddress varchar(50) NOT NULL,
billingAddress varchar(50) NOT NULL,
memberNo varchar(15) NOT NULL,
memStartDate date NOT NULL,
memOf varchar(15) ,
PRIMARY KEY(memberNo, shippingAddress)
);
and table shipping:
DROP TABLE IF EXISTS shipping;
CREATE TABLE shipping (
company varchar(10) NOT NULL,
warehouseAddress varchar(50) NOT NULL,
memberAddress varchar(50) NOT NULL,
memberNum varchar(15) NOT NULL,
orderNumber varchar(20) NOT NULL,
PRIMARY KEY(orderNumber)
);
ALTER TABLE shipping ADD CONSTRAINT shipping_memberAddnNUM_refs_member_memberNoNshippingAddress FOREIGN KEY (memberAddress, memberNum)
REFERENCES member (shippingAddress, memberNo);
So it gives me an errno: 150
I dont necessarily need member(shippingAddress) to be part of the primary key. But i do need to reference it my shipping table. Does anyone know how to get past this I have been looking at examples online but none of them seem to fix it.
I do it like this:
CONSTRAINT NAME_OF_PK PRIMARY KEY(Field1, Field2)
But this is Microsoft's SQL way of doing things.
You have the two columns in reverse order - from how they appear in the PRIMARY KEY of member. Try this:
ALTER TABLE shipping
ADD CONSTRAINT shipping_memberAddnNUM_refs_member_memberNoNshippingAddress
FOREIGN KEY (memberNum, memberAddress)
REFERENCES member (memberNo, shippingAddress);

SQL foreign keys and referencing other tables

I'm trying link two tables together using a foreign key. One table is users, the other is userInfo. When I delete a user I also want to delete their info as well. When I delete a user from the users table their entry in usersInfo is still there. I can't seem to figure out what I'm doing wrong.
CREATE TABLE users (
userid INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30) NOT NULL,
email VARCHAR(50) NOT NULL,
password VARCHAR(32) NOT NULL,
userlevel INT UNSIGNED NOT NULL,
rating int,
organization int(1),
timestamp varchar(20) NOT NULL,
);
Here is my table for userinfo. Yes, I know it could be in the same table. I'm just doing this for an easy example.
CREATE TABLE usersInfo(
userid int auto_increment NOT NULL,
userlocation varchar(50),
about varchar(300),
userkeywords varchar(150),
FOREIGN KEY(userid) REFERENCES users(userid) ON DELETE CASCADE ON UPDATE CASCADE
);
Edit - problem solved. Thanks to everyone who helped.
Added TYPE = InnoDB at the end of the CREATE TABLE statements.
Add ENGINE=INNODB to these CREATE TABLE statements to ensure they're InnoDB tables. MySQL versions below 5.5.5 will default to MyISAM, which does not support foreign-key relationships, but which will not throw an error if you define a foreign-key relationship either.

Can a table have two foreign keys?

I have the following tables (Primary key in bold. Foreign key in Italic)
Customer table
ID---Name---Balance---Account_Name---Account_Type
Account Category table
Account_Type----Balance
Customer Detail table
Account_Name---First_Name----Last_Name---Address
Can I have two foreign keys in the Customer table and how can I implement this in MySQL?
Updated
I am developing a web based accounting system for a final project.
Account Category
Account Type--------------Balance
Assets
Liabilities
Equity
Expenses
Income
Asset
Asset_ID-----Asset Name----Balance----Account Type
Receivable
Receivable_ID-----Receivable Name-------Address--------Tel-----Asset_ID----Account Type
Receivable Account
Transaction_ID----Description----Amount---
Balance----Receivable_ID----Asset_ID---Account Type
I drew the ER(Entity relationship) diagram using a software and when I specify the relationship it automatically added the multiple foreign keys as shown above. Is the design not sound enough?
create table Table1
(
id varchar(2),
name varchar(2),
PRIMARY KEY (id)
)
Create table Table1_Addr
(
addid varchar(2),
Address varchar(2),
PRIMARY KEY (addid)
)
Create table Table1_sal
(
salid varchar(2),`enter code here`
addid varchar(2),
id varchar(2),
PRIMARY KEY (salid),
index(addid),
index(id),
FOREIGN KEY (addid) REFERENCES Table1_Addr(addid),
FOREIGN KEY (id) REFERENCES Table1(id)
)
Yes, MySQL allows this. You can have multiple foreign keys on the same table.
Get more details here FOREIGN KEY Constraints
The foreign keys in your schema (on Account_Name and Account_Type) do not require any special treatment or syntax. Just declare two separate foreign keys on the Customer table. They certainly don't constitute a composite key in any meaningful sense of the word.
There are numerous other problems with this schema, but I'll just point out that it isn't generally a good idea to build a primary key out of multiple unique columns, or columns in which one is functionally dependent on another. It appears that at least one of these cases applies to the ID and Name columns in the Customer table. This allows you to create two rows with the same ID (different name), which I'm guessing you don't want to allow.
Yes, a table have one or many foreign keys and each foreign keys hava a different parent table.
CREATE TABLE User (
user_id INT NOT NULL AUTO_INCREMENT,
userName VARCHAR(100) NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
userImage LONGBLOB NOT NULL,
Favorite VARCHAR(255) NOT NULL,
PRIMARY KEY (user_id)
);
and
CREATE TABLE Event (
EventID INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (EventID),
EventName VARCHAR(100) NOT NULL,
EventLocation VARCHAR(100) NOT NULL,
EventPriceRange VARCHAR(100) NOT NULL,
EventDate Date NOT NULL,
EventTime Time NOT NULL,
EventDescription VARCHAR(255) NOT NULL,
EventCategory VARCHAR(255) NOT NULL,
EventImage LONGBLOB NOT NULL,
index(EventID),
FOREIGN KEY (EventID) REFERENCES User(user_id)
);

In my sql set condition for table?

In mysql can I set a condition that a combination of two fields can never be the same???
Example:
id-1
name-abc
grade-A
Now, another entry with name='abc' and grade='A' can not be added into that table ????
You can create a composite primary key from those two columns, but that makes little sense as the table already has an ID field, and surely two people of the same name can have the same grade? e.g.:
CREATE TABLE student_grades (
id int unsigned not null,
name varchar not null,
grade varchar not null,
PRIMARY KEY(name, grade));
You can also add a secondary UNIQUE constraint:
CREATE TABLE student_grades (
id int unsigned not null,
name varchar(10) not null,
grade varchar(10) not null,
PRIMARY KEY(id),
UNIQUE KEY(name, grade)
);