mysql prevent deleting records that is in used - mysql

i got 2 tables. product and order_items which contain all the products that were bought.
so how do i create a relationship in mysql whereby if a product exists in order_items, restrict users from deleting it from product table??
thanks

You can do this with Foreign keys with the InnoDB Engine.
ALTER TABLE order_items ADD FOREIGN KEY (`p_id`) REFERENCES `products` (`p_id`);
The ID on products must be a key (it probably already is the primary key).
If you are not using InnoDB, you cannot enforce this with MySQL, but it must be enforced with your application (check whether a record exists in orders first for example).
So with your tables, you run:
ALTER TABLE `order_item` ADD FOREIGN KEY (`bookid`) REFERENCES `book` (`id`);

You're looking for a foreign key. Specifically look at the "Restrict" option.
http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

my table structure:
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`title` varchar(100) NOT NULL,
`description` text NOT NULL,
`author` varchar(100) NOT NULL,
`publisher` varchar(100) NOT NULL,
`edition` int(11) NOT NULL,
`isbn` varchar(13) NOT NULL,
`category` varchar(11) NOT NULL,
`datesubmitted` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;
CREATE TABLE `order_item` (
`orderid` int(11) NOT NULL,
`bookid` int(11) NOT NULL,
KEY `Foreign` (`bookid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Related

Should I use one mapping table for multiple data-type tables, or create different mapping tables for each data-type?

At the moment I have one huge tag table and I use mapping table to map tags with another mapping table to map with data table. The reason I added another mapping-to-data table is that I have multiple different data tables.
There are two data tables:
CREATE TABLE IF NOT EXISTS `cars_list` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`description` varchar(255) default NULL,
`photo` varchar(45) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `website_list` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`description` varchar(255) default NULL,
`url` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Both of them I use in my search fields, and they should be linked to one TAG list table
There's tag table:
CREATE TABLE IF NOT EXISTS `tags` (
`tag_id` int(11) NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`tag_id`),
UNIQUE KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And what I do - I use two more tables to map data tables with tags:
Two mapping tables:
CREATE TABLE IF NOT EXISTS `tags_map_type` (
`tmtid` int(11) NOT NULL auto_increment,
`type` enum('cars_list','website_list') NOT NULL,
`type_id` int(11) NOT NULL,
PRIMARY KEY (`tmtid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `tags_map` (
`tmid` int(11) NOT NULL auto_increment,
`map_type_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL,
PRIMARY KEY (`tmid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `tags_map`
ADD CONSTRAINT `tag_id` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`tag_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `map_type_id` FOREIGN KEY (`map_type_id`) REFERENCES `tags_map_type` (`tmtid`) ON DELETE CASCADE ON UPDATE CASCADE;
And table tags_map_type then links either to cars_list or to website_list
QUESTION:
How can I make a foreign key to link tags_map_type to one of the list tables?
Or should I use another mapping table for each cars_list, website_list, some_other_list table?
Which way is correct and best to use?

Only allow one unique foreign key for primary

I have 3 tables in mysql, One is a Company table, the other is a license table and the last is a joining table between both primary keys, When a person adds a company id to the license id in the joining table, it allows multiple companies to exist for one license, this cannot happen, so I need to do something that will only allow one company id for one license id
heres the tables
Table license
CREATE TABLE `License` (
`license_id` int(11) NOT NULL AUTO_INCREMENT,
`license_number` varchar(45) NOT NULL,
`start_date` date NOT NULL,
`end_date` date NOT NULL,
`duration` int(11) NOT NULL,
`expiry_date` date NOT NULL,
`product_id` int(11) DEFAULT NULL,
PRIMARY KEY (`license_id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
;
Company Table
CREATE TABLE `Company` (
`company_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`physical_address` varchar(255) DEFAULT NULL,
`postal_address` varchar(255) DEFAULT NULL,
`reseller_id` int(11) DEFAULT NULL,
PRIMARY KEY (`company_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=latin1;
and Joining table
CREATE TABLE `CompanyLicense` (
`license_id` int(11) NOT NULL,
`company_id` int(11) NOT NULL,
PRIMARY KEY (`license_id`,`company_id`),
KEY `companlicence_company_fk_idx` (`company_id`),
CONSTRAINT `companylicense_company_fk` FOREIGN KEY (`company_id`) REFERENCES `Company` (`company_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `companylicense_license_fk` FOREIGN KEY (`license_id`) REFERENCES `License` (`license_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
So far i have this
INSERT INTO CompanyLicense (license_id, company_id) VALUES
('2','6') on duplicate key update license_id = '2';
doesnt seem to do the job
You need to make company unique in companylicense:
ALTER TABLE companylicense ADD UNIQUE KEY (company)
or better yet, make company a field in license instead of having a link table.

Designing E-commerce database and mysql error

I am trying to make an e-commerce site from scratch. Currently I am trying to make the database.
These are the core tables that the database will have:
Customer: which will have email, username, password....
Customers_Session: Stores information about customer session in hash
Group: basically tells what permissions a customer will have
Category: the category type of a product
Product: information about a product such as name, and description...
Product_Price: Price info on products. This will store the different prices put for each product at various times.
Product_Variation: information about product images, and various colors or styles of a product.
Customer_Orders: What products a customer has ordered.
Customer_Reviews: Reviews made by customers on a product.
Reviewed Products: This table is created based on many to many relationship between the Product table and the Review Table.
Ordered products: This table is created based on the many to many relationship between the Product and the Orders Table.
Based on the above, I have come up with the sql code below:
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`username` varchar(30) NOT NULL,
`password` varchar(64) NOT NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) NOT NULL,
`email` varchar(50) NOT NULL,
`address` varchar(320) NOT NULL,
`zip` mediumint(5) NOT NULL,
`salt` varchar(40) NOT NULL,
`joined` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`group` tinyint(1) NOT NULL,
`dob` date NOT NULL,
`pic_url` varchar(225) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
--
-- Table structure for table `groups`
--
CREATE TABLE IF NOT EXISTS `groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`permissions` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- This is for category table
--
CREATE TABLE IF NOT EXISTS `category`(
`category_id` tinyint(3) NOT NULL AUTO_INCREMENT,
`category_type` varchar(100) NOT NULL,
`category_description` varchar(160) NOT NULL,
PRIMARY KEY (`category_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
--
-- This is for product table
--
CREATE TABLE IF NOT EXISTS `products`(
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(100) NOT NULL UNIQUE,
`product_description` varchar(160) NOT NULL,
`quantity` int(5) NOT NULL,
`product_code` varchar(4) NOT NULL,
`keywords` varchar(70) NOT NULL,
`category_id` tinyint(3),
PRIMARY KEY (`product_id`),
INDEX (`category_id`),
CONSTRAINT FOREIGN KEY (`category_id`) REFERENCES category(`category_id`) ON DELETE SET NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
--
--
-- Table structure for table `bookings`
--
CREATE TABLE IF NOT EXISTS `bookings` (
`bookings_id` int(11) NOT NULL AUTO_INCREMENT,
`party_type` varchar(50) NOT NULL,
`location` varchar(100) NOT NULL,
`day` varchar(10) NOT NULL,
`time` smallint(6) NOT NULL,
`people_count` smallint(6) NOT NULL,
`booking_name` varchar(50) NOT NULL,
`booking_email` varchar(50) NOT NULL,
PRIMARY KEY (`bookings_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='This is for the bookings' AUTO_INCREMENT=1 ;
--
-- Dumping data for table `groups`
--
INSERT INTO `groups` (`id`, `name`, `permissions`) VALUES
(1, 'Administrator', '{"admin":1}'),
(2, 'Users', '{"users":2}');
--
-- Table Structure for Reviews
--
CREATE TABLE IF NOT EXISTS `customer_reviews`(
`reviews_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11),
`rating` int(5) NOT NULL,
`comment` varchar(160) NOT NULL,
PRIMARY KEY(`reviews_id`),
INDEX (`user_id`),
CONSTRAINT FOREIGN KEY(`user_id`) REFERENCES users(`user_id`) ON DELETE SET NULL
)ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
--
-- Table structure for reviewed products This is a many relationshi btw reviews table and product
--
CREATE TABLE IF NOT EXISTS `reviewed_products`(
`product_id` int(11),
`reviews_id`int(11),
PRIMARY KEY(`product_id`,`reviews_id`),
CONSTRAINT FOREIGN KEY(`product_id`) REFERENCES products(`product_id`) ON DELETE SET NULL,
CONSTRAINT FOREIGN KEY(`reviews_id`) REFERENCES customer_reviews(`reviews_id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='This is for many to many cardinality btw reviews and products' AUTO_INCREMENT=1 ;
--
--
-- Table structure for table `orders`
--
CREATE TABLE IF NOT EXISTS `customer_orders` (
`order_id` int(11) NOT NULL AUTO_INCREMENT,
`order_time` int(11) NOT NULL,
`amount` int(5),
`confirmation_number` int(,
`user_id` int(11),
`product_id` int(11),
PRIMARY KEY (`order_id`),
INDEX (`user_id`),
CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES users(`user_id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
/* We need a new table since the customer_order and product is in a many to many relationship */
--
--
-- Table structure for table `curtomer_order_product`
--
CREATE TABLE IF NOT EXISTS `ordered_product`(
`product_id` int(11),
`order_id` int(11),
`quantity` smallint(5),
PRIMARY KEY(`product_id`,`order_id`),
INDEX (`product_id`,`order_id`),
CONSTRAINT FOREIGN KEY (`order_id`) REFERENCES customer_orders(`order_id`) ON DELETE RESTRICT,
CONSTRAINT FOREIGN KEY (`product_id`) REFERENCES products(`product_id`) ON DELETE RESTRICT
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
-- This is for price table
--
CREATE TABLE IF NOT EXISTS `product_price`(
`price_id` int(11) NOT NULL AUTO_INCREMENT,
`price` decimal(6,2) NOT NULL,
`product_id` int(11) NOT NULL,
PRIMARY KEY (`price_id`),
INDEX (`product_id`),
CONSTRAINT FOREIGN KEY (`product_id`) REFERENCES products(`product_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
--
-- Table structure for table `product_variations`
--
CREATE TABLE IF NOT EXISTS `product_variations`(
`variations_id` int(11) NOT NULL AUTO_INCREMENT,
`color_name` varchar(10) NOT NULL,
`color_value` char(6) NOT NULL,
`product_id` int(11),
`picture1` varchar(100) NOT NULL,
`picture2` varchar(100) NOT NULL,
`picture3` varchar(100) NOT NULL,
PRIMARY KEY (`variations_id`),
INDEX (`product_id`),
CONSTRAINT FOREIGN KEY (`product_id`) REFERENCES products(`product_id`) ON DELETE RESTRICT
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
--
-- Table structure for table `users_session`
--
CREATE TABLE IF NOT EXISTS `users_session` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`hash` varchar(64) NOT NULL,
PRIMARY KEY (`id`),
INDEX (`user_id`),
CONSTRAINT FOREIGN KEY(`user_id`) REFERENCES users(`user_id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
The problem is that when I try to run the above code in PHPmyadmin, I get an error stating "Cannot add foreign key constraint". This starts to happen when creating the customer_Reviews table and any other subsequent tables that require foreign keys.
My questions are:
1. Would you recommend designing the database this way.
2. Why am I getting the "Cannot add foreign key constraint" error?
Thanks.
For a full quality review of your database design, you might try the Code Review sister site. At a glance, I don't see any glaring issues with your database design or your SQL.
The foreign key constraint is failing because you have misnamed the column in question.
CONSTRAINT FOREIGN KEY(`user_id`) REFERENCES users(`user_id`)
should be:
CONSTRAINT FOREIGN KEY(`user_id`) REFERENCES users(`id`)

Mysql connect tables through foreign key, depends from field type

Mysql database question. There is system with objects(Domains). Each domain has own table. All objects has unique 16 varchar id - guid
CREATE TABLE `guid` (
`guid` varchar(16) NOT NULL,
`obj_type` varchar(45) NOT NULL,
`obj_id` varchar(45) NOT NULL,
`actived` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`guid`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL,
/*....*/
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `catalog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL,
/*....*/
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
I would like connect table guid(fields: obj_type, obj_id) and domain tables(field:id) through foreign key.
Foreign key relationships involve a parent table that holds the central data values, and a child table with identical values pointing back to its parent. The FOREIGN KEY clause is specified in the child table. The parent and child tables must both be InnoDB tables. They must not be TEMPORARY tables.
CREATE TABLE product
(
id INT(11) NOT NULL auto_increment,
name VARCHAR(150) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES guid (guid )
)
engine=myisam
DEFAULT charset=utf8;

Declare Foreign key in MySQL

I have these database
=== Invoices ===
id
status
description
=== Invoice Items ===
id
invoice_id (FK)
item_name
description
To make this table I have made this MySQL command
CREATE TABLE IF NOT EXISTS `nt_invoices` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`status` varchar(45) NOT NULL DEFAULT '',
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ;
CREATE TABLE IF NOT EXISTS `nt_invoice_items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`invoice_id` int(11) NOT NULL,
`item_name` varchar(45) NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`),
KEY `invoice_id` (`invoice_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
My problem is that I want to declare a foreign key in the invoice_items table and to make the invoice_id the foreign key of invoices table id. So how to write that command? Any help and suggestions will be highly appreciated.
MyISAM does not support foreign keys. You need to use InnoDB (which is a better choice in all aspects anyway). Then it's just like in any other SQL dialect:
`invoice_id` int(11) NOT NULL references nt_invoices(id),
P.S. Also, always use utf8 encoding everywhere. It will bite you in the ass if you don't.
You should have innodb engine type for using foreign keys.
CREATE TABLE IF NOT EXISTS `nt_invoice_items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`invoice_id` int(11) NOT NULL references nt_invoices(id)
`item_name` varchar(45) NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`),
KEY `invoice_id` (`invoice_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
OR if you want to use cascaded update delete:
CREATE TABLE IF NOT EXISTS `nt_invoice_items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`invoice_id` int(11) NOT NULL,
`item_name` varchar(45) NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`),
KEY `invoice_id` (`invoice_id`),
FOREIGN KEY (invoice_id) REFERENCES nt_invoices(id)
ON DELETE CASCADE
ON UPDATE CASCADE,
) ENGINE=INNODB DEFAULT CHARSET=utf8;
You may also use ALTER command to declare FOREIGN KEY as follows:
Alter table table_name add foreign key(column_name)
references other_table_name(column);