I am using MySQL Workbench and i am trying to create a table with a primary key constraint without using PRIMARY KEY keyword.
create table employee
(
e_name varchar(20),
e_surname varchar(20),
depart varchar(20),
salary int,
check (e_name is not null and 1 = (select count(*)
from employee E
where e_name=E.e_name and e_surname=E.e_surname))
);
This query causes this error: Error Code: 1146. Table 'test.employee' doesn't exist
Can i use FROM referring to the table that i am creating? Is it allowed in MySQL?
There is no such thing as a primary key constraint that doesn't use the primary key keyword. A primary key has three properties:
It is unique.
It is not NULL.
There is only one per table.
It is the third that you cannot guarantee. However, you can easily impose the first two conditions:
create table employee (
e_name varchar(20) NOT NULL UNIQUE,
e_surname varchar(20),
depart varchar(20),
salary int
);
There is no use of a check constraint for this purpose.
Related
Which is better method among below:-
Using unique column name for each column, primary and foreign keys among all table.
Example 1:
CREATE TABLE projects (
project_id PRIMARY KEY,
project_name VARCHAR(30)
client_id INT,
fk_project_user_id INT, ( FOREIGN KEY )
projects_created_by INT, ( FOREIGN KEY )
);
CREATE TABLE clients (
client_id PRIMARY KEY,
client_name varchar(20),
fk_client_user_id INT,( FOREIGN KEY )
client_created_by INT, ( FOREIGN KEY )
)
Don't care about the uniqueness of each column name for each primary and foreign keys among all tables.
Example 2:
CREATE TABLE projects (
id PRIMARY KEY,
project_name VARCHAR(30)
client_id INT, ( FOREIGN KEY )
fk_user_id INT, ( FOREIGN KEY )
created_by INT ( FOREIGN KEY )
);
CREATE TABLE clients (
id PRIMARY KEY, (Same as above table)
client_id INT,
client_name varchar(20),
fk_user_id INT, ( FOREIGN KEY ) (Same as above table)
fk_client_id int, ( FOREIGN KEY )
created_by INT ( FOREIGN KEY ) (Same as above table)
);
When we plan database for big ERP having multiple tables and relationships among all? I have used a different name for each key to avoiding ambiguous error when we join two tables.
What is the best solution?
Naming conventions are up to you. Which naming convention you decide to use is not important. What's important is that you follow your own convention consistently, and document it so that other developers know how to understand your code and your schema.
Some people choose to give every table a primary key named id. If every one of their tables must have a column named id, then they can write reusable code for certain queries against any table.
However, this convention does not account for compound primary keys. Also if your query does a join, the query result set may have multiple columns named id unless you define column aliases.
When I design a database, I name my primary key in a descriptive way. projects.project_id for example. This avoids the problem of duplicate column names in a result set of a join. It also makes it more clear what the column means when you see it in a query or a result set.
I like to name the foreign key the same as the primary key column it references, when I can do it without resulting in a conflict.
But consider this example, where there are multiple foreign keys in the same table that reference Users.user_id.
CREATE TABLE Bugs (
bug_id INT PRIMARY KEY,
description TEXT NOT NULL,
reported_date DATETIME NOT NULL,
user_reported_by INT NOT NULL,
user_assigned_to INT,
user_verified_by INT,
FOREIGN KEY (user_reported_by) REFERENCES Users(user_id),
FOREIGN KEY (user_assigned_to) REFERENCES Users(user_id),
FOREIGN KEY (user_verified_by) REFERENCES Users(user_id)
);
You can't assume you can use a common column name, because it's normal to need multiple foreign keys referencing the same table, as in the example above. Therefore you must allow the FK column name to be different from the PK it references.
The tables will build, but every time I try to insert values into the table I get a 1452 error of foreign key constraints fails. I wonder if the problem has to do with EMPLOYEE table has a foreign key for STORE_CODE in the STORE table, and STORE table has a foreign key for EMP_CODE in EMPLOYEE table. Is the circular reference the problem here?
ALTER TABLE EMPLOYEE DROP FOREIGN KEY STORE_CD;
ALTER TABLE STORE DROP FOREIGN KEY REGION_CD;
ALTER TABLE STORE DROP FOREIGN KEY EMPLOYEE_CD;
DROP TABLE IF EXISTS EMPLOYEE, REGION, STORE;
CREATE TABLE EMPLOYEE (
EMP_CODE int NOT NULL PRIMARY KEY,
EMP_TITLE varchar(4),
EMP_LNAME varchar(15),
EMP_FNAME varchar(15),
EMP_INITIAL varchar(1),
EMP_DOB datetime,
STORE_CODE int NOT NULL
) Engine=InnoDB;
-- Table Region
CREATE TABLE REGION (
REGION_CODE int NOT NULL PRIMARY KEY,
REGION_DESCRIPT varchar(20)
) Engine=InnoDB;
-- Table Store
CREATE TABLE STORE (
STORE_CODE int NOT NULL PRIMARY KEY,
STORE_NAME varchar(20) NOT NULL,
STORE_YTD_SALES numeric NOT NULL,
REGION_CODE int NOT NULL,
EMP_CODE int NOT NULL
) Engine=InnoDB;
ALTER TABLE EMPLOYEE ADD CONSTRAINT STORE_CD
FOREIGN KEY STORE_CD(STORE_CODE) REFERENCES STORE(STORE_CODE);
ALTER TABLE STORE ADD CONSTRAINT REGION_CD
FOREIGN KEY REGION_CD(REGION_CODE) REFERENCES REGION(REGION_CODE);
ALTER TABLE STORE ADD CONSTRAINT EMPLOYEE_CD
FOREIGN KEY EMPLOYEE_CD(EMP_CODE) REFERENCES EMPLOYEE(EMP_CODE);
It's not possible to have mutual foreign keys unless you allow at least one of the columns to be NULL. Otherwise you can never have a consistent set of tables: If you add the store first, it will refer to a nonexistent employee; if you add the employee first, it will refer to a nonexistent store.
So you need to allow the referencing column to be NULL. Then you can add a row to the first table with NULL in the referencing column, add a row to the second table, then fill in the referencing column in the first table with the ID from the second table.
In my experience with relational databases, I think you should create an
intermediate table to conect "store" with "employee" (lets name it (store_has_employee) with the atributes(idstore(fk), idemployee(fk) and isManager(boolean)).
Then you should insert the "regions" first, so you can insert a "store", then when you have registered "employees", all you have to do is conect them in "store_has_employee", and if you want to say that is the manager, just insert isManager=true.
This is the most eficient way to do it and to get faster queries.
Hope it helps.
Which one you Want to insert first? If EMPLOYEE then Make STORE_CD (nullable=true) in EMPLOYEE After that Insert STORE item with EMPLOYEE id and Update EMPLOYEE with store code.You can use Transaction for this whole process.
Due to my lack of understanding SQL, the simplest solution for me has been to remove the foreign key from the employee table so that I don't have a circular reference. Then populate the employee table first the other tables afterwards.
Hello i have a table which has one primary key by the name of ImageID and i want to make another column
also primary key which is PropertyID means Composite Key
HERE IS THE CODE, but its showing this error for me "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '( PropertyID INT, ImageID INT primary key (PropertyID, ImageID) )' at line "
Also the ImageID is already primary key, but with varchar(15) specification.
Alter TABLE properties (
PropertyID INT,
ImageID INT,
primary key (PropertyID, ImageID)
);
Each table can only have 1 primary key. You can only have one primary key, but you can have multiple columns in your primary key.
Taken from W3Schools:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)
Here the only primary key is pk_PersonID but that have stated that pk_PersonID is made up of P_Id and LastName.
Unique Indexes may be what you're looking for. This means unique values are required and runs like an index in that it can speed up queries.
Try this:
First drop the existing primary key
ALTER TABLE properties
DROP PRIMARY KEY;
Then add composite key
ALTER TABLE properties
ADD PRIMARY KEY(imageID, propertyID);
As I understand you already have a table with one key, which looks like the following:
CREATE TABLE `common`.`properties` (
`PropertyID` VARCHAR(15) NOT NULL,
`otherColumn` VARCHAR(45) NULL,
PRIMARY KEY (`PropertyID`));
And now you want to add another PK column and change the type of existing PK column from char to INT. So you need to do it as following:
ALTER TABLE `common`.`properties`
CHANGE COLUMN `PropertyID` `PropertyID` INT NOT NULL ,
ADD COLUMN `ImageID` INT NOT NULL AFTER `otherColumn`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`PropertyID`, `ImageID`);
P.S. common is my schema name, you can use your own, or even skip it if your schema is default.
I have three tables:
CREATE TABLE Address (
ResidentID CHAR(5) NOT NULL,
Location varchar(255) NOT NULL,
KEY ResidentID(ResidentID)
);
CREATE TABLE Customer (
CustomerID CHAR(5) NOT NULL,
ContactName varchar(40) NOT NULL,
PRIMARY KEY (CustomerID)
);
CREATE TABLE Supplier (
SupplierID CHAR(5) NOT NULL,
SupplierName varchar(40) NOT NULL,
PRIMARY KEY (SupplierID)
);
I want to store CustomerID and SupplierID in the Address.ResidentID field with using of foreign keys:
ALTER TABLE Address ADD CONSTRAINT fk_CustomerID1 FOREIGN KEY(ResidentID) REFERENCES Customer(CustomerID);
ALTER TABLE Address ADD CONSTRAINT fk_SupplierID1 FOREIGN KEY(ResidentID) REFERENCES Supplier(SupplierID);
But second 'ALTER TABLE' raises Error: relation already exists
Any suggestions?
Data example:
CustomerID ContactName
C0001 Den
SupplierID ContactName
S0001 John
So Address table should contains:
ResidentID Location
C0001 Alaska
S0001 Nevada
You need to either reference addresses from the Customer / Supplier (if they only have one) or two different columns.
The reason you see in this SQLFiddle You cannot INSERT the required columns into the Address table if the ResidentID references BOTH tables. You could only insert lines that would match the contents of Customer AND Supplier but you want an OR connection that you can't create that way.
(Note: In my solutions I assume addresses to be optional. As Tom pointed out in the comments that may not be what you wanted, or expected. Make sure to mark the FK Columns in the first solution as NOT NULL if you want addresses to be mandatory, its more complicated for the second one. You have to mind the correct insertion order then.)
Either:
CREATE TABLE Address (
AddressID CHAR(5) NOT NULL,
Location varchar(255) NOT NULL,
PRIMARY KEY (AddressID)
);
CREATE TABLE Customer (
CustomerID CHAR(5) NOT NULL,
AddressID CHAR(5),
ContactName varchar(40) NOT NULL,
PRIMARY KEY (CustomerID)
);
CREATE TABLE Supplier (
SupplierID CHAR(5) NOT NULL,
AddressID CHAR(5),
SupplierName varchar(40) NOT NULL,
PRIMARY KEY (SupplierID)
);
ALTER TABLE Customer ADD CONSTRAINT fk_AddressID_Cust FOREIGN KEY(AddressID) REFERENCES Address(AddressID);
ALTER TABLE Supplier ADD CONSTRAINT fk_AddressID_Supp FOREIGN KEY(AddressID) REFERENCES Address(AddressID);
or
CREATE TABLE Address (
CustomerID CHAR(5),
SupplierID CHAR(5),
Location varchar(255) NOT NULL,
PRIMARY KEY (CustomerID, SupplierID)
);
CREATE TABLE Customer (
CustomerID CHAR(5) NOT NULL,
ContactName varchar(40) NOT NULL,
PRIMARY KEY (CustomerID)
);
CREATE TABLE Supplier (
SupplierID CHAR(5) NOT NULL,
SupplierName varchar(40) NOT NULL,
PRIMARY KEY (SupplierID)
);
ALTER TABLE Address ADD CONSTRAINT fk_CustomerID1 FOREIGN KEY(CustomerID) REFERENCES Customer(CustomerID);
ALTER TABLE Address ADD CONSTRAINT fk_SupplierID1 FOREIGN KEY(SupplierId) REFERENCES Supplier(SupplierID);
The approach you're trying is (a) not possible and (b) undesirable even if it was possible.
The best approach is to have a CustomerAddress table and a SupplierAddress table, each with a single FK to the matching base table; or if you must, a cross-reference table with appropriate constraints.
If your motivation for having a single Address table was code reuse, you can still do that ... think in terms of a template xxxAddress table design that can refer to any base xxx table. You can write non-database code that treats the base table name as a parameter and then could handle any number of xxxAddress tables as you add more base tables over time.
Or if your motivation for having a single Address table was to simplify reporting, you can always create a view or stored proc that returns a union of all such tables + an added field to indicate the base table for each address row.
Angelo I am revising this a bit based on your comment ---
Angelo, I ran your sample code in a local MySQL instance (not SQLFiddle) and observed an error.
I was surprised (you learn something every day) that MySQL did allow two foreign key constraints to be defined on the same field; however when you attempt to insert data, when trying to point the FK to the Customer table, I get an error saying a foreign key constraint fails referencing the Supplier table; and vice versa for the insert trying to point the FK to the Supplier table.
So my revised statement is (a) it is possible to create the hydra-headed FK in at least some DBMSs -- verified in MySQL, MS SQL Server and Oracle -- although (b) this only makes sense to use when the foreign key can refer to the same logical entity by ID across multiple tables (e.g. to ensure there is a corresponding record in all required tables, for example); and (c) if used to refer to multiple tables where the primary key is NOT the same logical entity, only works if by chance the same primary key value just happens to exist in all referenced tables, which is likely to lead to subtle, hard-to-find errors.
In other words, your example would work when attempting to insert a record referring to Customer ID=3 only if there was also a Supplier ID=3, which are really logically unrelated.
So my slightly revised answer to the OP is, what you're trying to do is not possible (or logical) when the foreign key is referring to different ENTITIES, as in the OP example of Customers and Suppliers.
I want to create a table relationship with MYSQL PHPMYADMIN.
I have this Create table:
CREATE TABLE students(code_students int(8)not null AUTO_INCREMENT,
name_students varchar(25),
age_students int(3),
degree_program varchar(25),
code_advisor int(8)not null,
primary key(code_students, code_advisor)
);
and i want to make a create table named advise relationship between code_students, code_advisor.
Ok this is my tryout.
CREATE TABLE advise (
code_students int(8),
code_advisor int(8),
primary key(code_students, code_advisor),
foreign key(code_students)references students(code_students),
foreign key(code_advisor)references students(code_advisor)
);
mySQL says :
A FOREIGN KEY constraint that references a non-UNIQUE key is not standard SQL. It is an InnoDB extension to standard SQL
Try adding the UNIQUE keyword to your first table:
CREATE TABLE students(
code_students int(8)not null unique AUTO_INCREMENT,
name_students varchar(25),
age_students int(3),
degree_program varchar(25),
code_advisor int(8)not null unique,
primary key(code_students, code_advisor)
);
Check out this sqlFiddle and see how it works, then try removing the UNIQUE keywords and see that you get the same error that you mentioned. ( Hit the Build Schema button )
http://sqlfiddle.com/#!2/46b69