One key as foreign key for multiple table - mysql

There are many similar question but this is bit different.
I have one table which has one foreign key that will reference to two tables.
I used below query for testing.
CREATE TABLE users
(
id int NOT NULL,
username varchar(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE admins
(
id int NOT NULL,
username varchar(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE info
(
id int NOT NULL,
fullname int NOT NULL,
user_id int,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (user_id) REFERENCES admins(id)
);
Above queries works fine.
but when I try to draw model in mysql workbench it create on new field in info table that I don't want. I want user_id should work and show relation as foreign key for users and admins table.
One more thing, am I trying to do that is not well standard? Also suggests a correct way to do it.
Table names used only for example purpose. There is no logic here. I am trying to find solution for one key as foreign key for multiple table and faced issue with mysql work bench.

Try this:
Save your DDL in a file.
Create new model in MySQL Workbench
File > Import > Reverse Engineer MySQL Create Script
Browse to file created in step 1. Ensure that 'Place imported objects on diagram' is selected.
Click 'Execute'
From a data modelling point of view you might be better off specifying a user as an admin by including an extra column on the users table. Hence:
CREATE TABLE users
(
id int NOT NULL,
username varchar(255) NOT NULL,
isAdmin boolean not null default false,
PRIMARY KEY (id)
);
CREATE TABLE info
(
id int NOT NULL,
fullname int NOT NULL,
user_id int,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users(id)
);

Related

error 1215: database design with foreign key

I am trying to create three tables such as associate, manager and attendance. The attendance table should be having employee and manager details from the other two table which should enable marking the attendance. I created this SQL script. I'm not sure where I am making mistake.
CREATE TABLE associate (
id INT NOT NULL,
idmanager INT NOT NULL,
emp_id DATE NOT NULL,
emp_name VARCHAR(25) NOT NULL,
FOREIGN KEY (id) REFERENCES attendance (associate_id) ON DELETE CASCADE,
FOREIGN KEY (idmanager) REFERENCES attendance (manager_idmanager) ON DELETE CASCADE,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE manager (
id INT NOT NULL,
mgr_usr_id VARCHAR(15) NOT NULL,
mgr_name VARCHAR(25) NOT null,
KEY (id),
KEY (mgr_usr_id),
FOREIGN KEY (id) REFERENCES associate (idmanager) ON DELETE CASCADE,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE attendance (
sno INT NOT NULL,
manager_idmanager INT NOT NULL,
associate_id INT NOT NULL,
date_stamp DATETIME,
state BIT NOT NULL,
PRIMARY KEY (sno)
) ENGINE=INNODB;
Screenshot
It's an issue of ordering. For example, the first statement executed is
CREATE TABLE associate (
which references attendance. However, the attendance table has not yet been created. Switch the order so that any tables that reference other tables come last.
Alternatively, don't put the FOREIGN KEY constraints in the CREATE statements, but them at the end of your script with ALTER TABLE statements. Consider:
CREATE TABLE associate (
id INT NOT NULL,
idmanager INT NOT NULL,
emp_id DATE NOT NULL,
emp_name VARCHAR(25) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE attendance (
sno INT NOT NULL,
manager_idmanager INT NOT NULL,
associate_id INT NOT NULL,
date_stamp DATETIME,
state BIT NOT NULL,
PRIMARY KEY (sno)
) ENGINE=INNODB;
ALTER TABLE associate ADD FOREIGN KEY (id) REFERENCES associate(id) ON DELETE CASCADE;
Edit
The above is just syntax. To model the requested problem consider orthogonality of information. You might also see/hear "normalization." The basic concept is this: have only one copy of your information. The schema should have a single point of authority for all data. For example, if a user has a birthdate, make sure you don't have an ancillary column that also stores their birthday; it's superfluous information and can lead to data errors.
In this case, what is the relationship? What must come first for the other to exist? Can an attendance be had without a manager? How about a manager without attendance? The former makes no sense. In this case then, I would actually use a third table, to form a hierarchy.
Then, consider that maybe roles change in a company. It would not behoove the DB architect to hard code roles as tables. Consider:
CREATE TABLE employee (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(25) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE role (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
description VARCHAR(254) NOT NULL,
PRIMARY KEY( id ),
UNIQUE( name )
) ENGINE=INNODB;
INSERT INTO role (name, description) VALUES
('associate', 'An associate is a ...'),
('manager', 'A manager follows ...');
CREATE TABLE employee_role (
employee_id INTEGER NOT NULL,
role_id INTEGER NOT NULL,
PRIMARY KEY (employee_id, role_id),
FOREIGN KEY (idemployee_id) REFERENCES employee_id (id) ON DELETE CASCADE,
FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE CASCADE
) ENGINE=INNODB;
CREATE TABLE attendance (
sno INTEGER NOT NULL,
employee_id INTEGER NOT NULL,
date_stamp DATETIME,
state BIT NOT NULL,
PRIMARY KEY (sno),
FOREIGN KEY (idemployee_id) REFERENCES employee_id (id) ON DELETE CASCADE
) ENGINE=INNODB;
From this schema, the attendance needs only one foreign key because everyone is an employee. Employee's can have multiple roles, and they can change. Further, role definitions can change without needing to resort to costly DDL statements (data definition layer changes, like ALTER TABLE), and can be modified with simple DML (data manipulation layer changes, like UPDATE TABLE). The former involves rewriting all entries in the tables, and changing schemas, while the latter involves changing individual entries.

MySQL : Error Code 1215 : Cannot add foreign key constraint

I'm trying to make a simple SQL schema, but I'm having some problem with defining foreign keys. I really don't have that much MySQL knowledge, so I thought I'd ask her for some help. I get Error Code 1215 when I try to create the foreign key roomID and 'guestEmail' in the HotelManagement.Reservation table creation.
CREATE database HotelManagement;
CREATE TABLE HotelManagement.Room (
roomID INT not null auto_increment,
roomTaken TINYINT(1),
beds INT not null,
size INT not null,
roomRank INT not null,
PRIMARY KEY(roomID));
CREATE TABLE HotelManagement.HotelTask (
taskType INT not null,
taskStatus TINYINT(1) not null,
whichRoom INT not null,
note VARCHAR(255),
PRIMARY KEY (taskType),
FOREIGN KEY (whichRoom) REFERENCES HotelManagement.Room(roomID));
CREATE TABLE HotelManagement.Guest (
firstName varchar(25) not null,
lastName varchar(25) not null,
userPassword varchar(25) not null,
email varchar(25) not null,
reservation INT,
PRIMARY KEY (userPassword, email));
CREATE TABLE HotelManagement.Reservation (
reservationID INT not null,
id_room INT not null,
guestEmail varchar(25) not null,
fromDate DATE not null,
toDate DATE not null,
PRIMARY KEY (reservationID),
FOREIGN KEY (guestEmail)
REFERENCES HotelManagement.Guest(email),
FOREIGN KEY (id_room)
REFERENCES HotelManagement.Room(roomID)
);
ALTER TABLE HotelManagement.Guest
ADD CONSTRAINT res_constr FOREIGN KEY (reservation)
REFERENCES HotelManagement.Reservation(reservationID);
Updated the .sql
In the hoteltask table you have already defined a foreign key named roomid. Foreign key names also have to be unique, so just give a different name to the 2nd foreign key or omit the name completely:
If the CONSTRAINT symbol clause is given, the symbol value, if used,
must be unique in the database. A duplicate symbol will result in an
error similar to: ERROR 1022 (2300): Can't write; duplicate key in
table '#sql- 464_1'. If the clause is not given, or a symbol is not
included following the CONSTRAINT keyword, a name for the constraint
is created automatically.
UPDATE
The email field in the guest table is the rightmost column of the primary key, this way the pk cannot be used to independently look up email in that table. Either change the order or fields in the pk, or have a separate index on email field in the guest table. Quote from the same link as above:
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
Pls read through the entire documentation I linked before proceeding with creating the fks!
Side note 2 (1st is in the comments below): you should probably have a unique numeric guest id because that is lot more efficient than using email. Even if you decide to stick with email as id, I would restrict the pk in the guest table to email only. With the current pk I can register with the same email multiple times if I use different password.

Cannot INSERT because of Foreign key constraints - mysql

So I don't understand why I cannot insert data in my table that have foreign constraint keys or even modify anything in it.
Here is an example of the tables that are created. I am trying to insert data in the addresses table:
///////////////////////ADDRESSES TABLE ////////////////////////
CREATE TABLE IF NOT EXISTS addresses (
id INT NOT NULL AUTO_INCREMENT,
addressline1 VARCHAR(255) NOT NULL,
addressline2 VARCHAR(255) NOT NULL,
postcode VARCHAR(255) NOT NULL,
phonenumber INT(13) NOT NULL,
country_id INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (country_id) REFERENCES countries(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
) ENGINE=InnoDB ";
///////////////////////COUNTRIES TABLE ////////////////////////
CREATE TABLE IF NOT EXISTS countries (
id INT NOT NULL AUTO_INCREMENT,
countryname VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
)
The issue here is that you are trying to insert into a referencing table (addresses) when the referenced entry (the country you reference) does not exist. That's what's triggering the FOREIGN KEY CONSTRAINT exception.
Try first inserting some countries into the countries table, then inserting some addresses where you reference those countries you entered in the first step.
As for your second question, that's a choice for you to make. I would probably choose to have the User have an Address (address field in the User table), but some of that depends on how the data is being used/updated.
Have a quick look through this resource if you're new to relational database design. It covers (in brief) topics like relationship types, key constraints, and normal forms.

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)
);

How do I create a MySQL table when it has two foreign keys?

What would be the code for creating a table with two foreign keys?
I have a USER table and a PICTURE table. Since a USER can be in many PICTURE and many PICTURE can be from a USER, I need a third table with both primary keys.
Thank you SO, as usual you are invaluable for a learning novice. :)
I can't speak specifically for mySQL but in most databases I have worked with you can put as many foreign keys as you need on a table. But you can only have one primary key. A third table with both keys is the right choice. Make a foreign key to each of the other two tables and a primary key consisting of both ids in the table.
If I understood correctly, you may need to do something like the following:
CREATE TABLE users (
user_id INT NOT NULL PRIMARY KEY,
name VARCHAR(50) NOT NULL
) ENGINE=INNODB;
CREATE TABLE pictures (
picture_id INT NOT NULL PRIMARY KEY,
filename VARCHAR(255) NOT NULL,
posted_by INT NOT NULL,
FOREIGN KEY (posted_by) REFERENCES users(user_id)
) ENGINE=INNODB;
CREATE TABLE users_in_pictures (
user_id INT NOT NULL,
picture_id INT NOT NULL,
PRIMARY KEY (user_id, picture_id),
FOREIGN KEY (user_id) REFERENCES users(user_id),
FOREIGN KEY (picture_id) REFERENCES pictures(picture_id)
) ENGINE=INNODB;
Note that each picture can be posted by a user. In fact the posted_by field is constrained by a foreign key that references the users table.
In addition, I assume that you want to tag pictures ala-facebook. In this case, you can use the third table, which is using a composite primary key on (user_id, picture_id) and both fields are also constrained to the appropriate table.