MySQL Composite Keys Integrity - mysql

I have this table
CREATE TABLE `inventario` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cla` varchar(100) NOT NULL,
`des` varchar(500) NOT NULL,
`lin` varchar(3) NOT NULL,
`cal` varchar(20) NOT NULL,
`uen` varchar(20) NOT NULL,
`can` double NOT NULL,
`fei` varchar(10) NOT NULL,
`fec` varchar(10) NOT NULL,
`obs` varchar(500) NOT NULL,
`ppu` double NOT NULL,
`pl1` double NOT NULL,
`pl2` double NOT NULL,
`pl3` double NOT NULL,
`pl4` double NOT NULL,
`prm` double NOT NULL,
`pr1` varchar(50) NOT NULL,
`pr2` varchar(50) NOT NULL,
`mnm` double NOT NULL,
`max` double NOT NULL,
`dias` int(10) NOT NULL DEFAULT '1',
`categoria` varchar(50) NOT NULL,
PRIMARY KEY (`id`,`cla`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
Id and cla are primary keys, but I need to keep the integrity and this structure allows duplicate "cla" values: F/e:
Id | Cla
01 | ADI001
02 | ADI001
And I need to avoid repeating the "cla" value in spite of the "id" value, how can I do that? Thanks.

Create a unique index on cla. Add the line:
unique key cla

Related

MySQL 5.7 Windows, table key issue?

What is wrong with this MySQL table script code?:
CREATE TABLE `securities_master`.`symbol` (
`id` INT NOT NULL,
`exchange_id` INT NULL,
`ticker` VARCHAR(32) NOT NULL,
`instrument` VARCHAR(64) NOT NULL,
`name` VARCHAR(255) NULL,
`sector` VARCHAR(255) NULL,
`currency` VARCHAR(32) NULL,
`created_date` DATETIME NOT NULL,
`last_updated_date` DATETIME NOT NULL,
PRIMARY KEY (`id`), FOREIGN KEY 'index_exchange_id' ('exchange_id'))
ENGINE = InnoDB AUTO_INCREMENT = 1
DEFAULT CHARACTER SET = utf8;
I think it is the "FOREIGN KEY" but I am not sure
Single quotes denote string literals in SQL. Object names (such as the constraint name and the columns it refers to) should be denoted with backticks, or nothing at all:
CREATE TABLE `securities_master`.`symbol` (
`id` INT NOT NULL,
`exchange_id` INT NULL,
`ticker` VARCHAR(32) NOT NULL,
`instrument` VARCHAR(64) NOT NULL,
`name` VARCHAR(255) NULL,
`sector` VARCHAR(255) NULL,
`currency` VARCHAR(32) NULL,
`created_date` DATETIME NOT NULL,
`last_updated_date` DATETIME NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY `index_exchange_id` (`exchange_id`)
-- Here ----^-----------------^--^-----------^
)
ENGINE = InnoDB AUTO_INCREMENT = 1
DEFAULT CHARACTER SET = utf8;

Mysql error 1215 - Cannot add foreign key constraint

Created these two tables successfully
First table
CREATE TABLE IF NOT EXISTS `lawncare_user` (
`ID` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`FirstName` varchar(255) NOT NULL,
`LastName` varchar(255) NOT NULL,
`Email` varchar(255) NOT NULL,
`UserType` varchar(30) NOT NULL,
`UserName` varchar(255) NOT NULL,
`Password` varchar(255) NOT NULL,
`AddedBy` int(11) NOT NULL,
`AddedOn` date NOT NULL,
`ModifiedOn` date DEFAULT NULL,
`Status` BOOLEAN NOT NULL DEFAULT '0',
`QuestionID` int(11) DEFAULT NULL,
`QuestionAnswer` text DEFAULT NULL,
`Params` text NOT NULL,
`Address` text NOT NULL,
`Country` varchar(300) NOT NULL,
`State` varchar(300) NOT NULL,
`City` varchar(300) NOT NULL,
`ContactNo` double DEFAULT NULL,
`Activation` BOOLEAN NOT NULL DEFAULT '0',
`ActivatedOn` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Second table
CREATE TABLE IF NOT EXISTS `lawncare_customer` (
`ID` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`FirstName` varchar(255) NOT NULL,
`LastName` varchar(255) NOT NULL,
`Email` varchar(255) NOT NULL,
`Password` varchar(255) NOT NULL,
`ContactNo` varchar(20) NOT NULL,
`Address` varchar(255) NOT NULL,
`Params` text NOT NULL,
`Province` varchar(255) NOT NULL,
`ZipCode` varchar(255) NOT NULL,
`Status` Boolean NOT NULL DEFAULT '0',
`AddedBy` int(11) NOT NULL,
`AddedOn` date NOT NULL,
`ModifiedOn` date DEFAULT NULL
) ENGINE =InnoDB DEFAULT CHARSET=latin1;
But while creating third table as
CREATE TABLE IF NOT EXISTS `lawncare_message` (
`ID` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Reason` int(5) NOT NULL,
`Subject` text NOT NULL,
`Description` text NOT NULL,
`Customer` int(11) NOT NULL,
`CustomerUser` varchar(255) NOT NULL,
`CustomerEmail` varchar(255) NOT NULL,
`SendTo` int(11) NOT NULL,
`SendToUser` varchar(255) NOT NULL,
`SendToEmail` varchar(255) NOT NULL,
`Status` int(5) NOT NULL DEFAULT '0',
`AddedBy` int(11) NOT NULL,
`AddedOn` date NOT NULL
FOREIGN KEY (SendTo, SendToUser, SendToEmail)
REFERENCES lawncare_user(ID, UserName, Email)
ON UPDATE CASCADE ,
FOREIGN KEY (Customer, CustomerUser, CustomerEmail)
REFERENCES lawncare_customer(ID, FirstName,Email)
ON UPDATE CASCADE
) ENGINE =InnoDB DEFAULT CHARSET=latin1
I get #1215 - Cannot add foreign key constraint , error in mysql tried adding foreign keys after creating table but it still gives the same error. I don't know what I'm doing wrong here.
First of all Check whether you have applied indexes on the keys.
As per your code their is no point in referencing id,UserName and Email.
Only id is enough for referencing.
Check the following code
CREATE TABLE IF NOT EXISTS `lawncare_message` (
`ID` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Reason` int(5) NOT NULL,
`Subject` text NOT NULL,
`Description` text NOT NULL,
`Customer` int(11) NOT NULL,
`CustomerUser` varchar(255) NOT NULL,
`CustomerEmail` varchar(255) NOT NULL,
`SendTo` int(11) NOT NULL,
`SendToUser` varchar(255) NOT NULL,
`SendToEmail` varchar(255) NOT NULL,
`Status` int(5) NOT NULL DEFAULT '0',
`AddedBy` int(11) NOT NULL,
`AddedOn` date NOT NULL,
FOREIGN KEY (SendTo)
REFERENCES lawncare_user(ID)
ON UPDATE CASCADE ,
FOREIGN KEY (Customer)
REFERENCES lawncare_customer(ID)
ON UPDATE CASCADE
) ENGINE =InnoDB DEFAULT CHARSET=latin1

How can I declare a table without primary key?

I am using MySQL Query Browser.
I have tried this code:
CREATE TABLE `something`.`payment_something` (
`firstName` varchar(15) NOT NULL,
`lastName` varchar(15) NOT NULL,
`inputEmail` varchar(55) NOT NULL,
`genderRadios` varchar(15) NOT NULL,
`monthh` varchar(10) NOT NULL,
`dayy` varchar(10) NOT NULL,
`yearr` varchar(10) NOT NULL,
`postalAddress` varchar(15) NOT NULL,
`phoneNumber` varchar(15) NOT NULL,
`ZipCode` varchar(15) NOT NULL,
`CreditCard` varchar(15) NOT NULL,
`expireMonth` varchar(10) NOT NULL,
`expireYear` varchar(10) NOT NULL,
`Institution` varchar(25) NOT NULL,
`textinput` varchar(15) NOT NULL,
`radios` varchar(10) NOT NULL,
PRIMARY KEY ()
) ENGINE=InnoDB DEFAULT CHARSET=greek;
of course it shows error in the PRIMARY KEY line. Any idea?
EDIT Better solution
CREATE TABLE `something`.`payment_something` (
`id` int(15) NOT NULL AUTO_INCREMENT,
`firstName` varchar(15) NOT NULL,
`lastName` varchar(15) NOT NULL,
`inputEmail` varchar(55) NOT NULL,
`genderRadios` varchar(15) NOT NULL,
`monthh` varchar(10) NOT NULL,
`dayy` varchar(10) NOT NULL,
`yearr` varchar(10) NOT NULL,
`postalAddress` varchar(15) NOT NULL,
`phoneNumber` varchar(15) NOT NULL,
`ZipCode` varchar(15) NOT NULL,
`CreditCard` varchar(15) NOT NULL,
`expireMonth` varchar(10) NOT NULL,
`expireYear` varchar(10) NOT NULL,
`Institution` varchar(25) NOT NULL,
`textinput` varchar(15) NOT NULL,
`radios` varchar(10) NOT NULL,
PRIMARY KEY ('id')
) ENGINE=InnoDB DEFAULT CHARSET=greek;
It shows wrong in the PRIMARY KEY line why?
Simply exclude the problematic line:
PRIMARY KEY ()
You don't need to have that line, if you are not actually defining a key. In your example, you will also have to remove the comma directly preceding this line, of course.
UPDATE:
In your updated example, just take the '' off of 'id' when you declare it. Use the backtick (`), instead of the apostrophe:
PRIMARY KEY (`id`)

How to optimize a MySQL JOIN Query

I have this MySQL query that I want to optimize:
SELECT r.WarehouseLocation,sum(sir.qty)
FROM repairableissue as r
INNER JOIN SIR ON r.sirno=sir.sirno
AND r.region=sir.region
AND r.ItemName=sir.Itemdesc
AND r.SerialNo=sir.Serialno
WHERE r.status='Pending'
GROUP BY r.warehouseLocation
How do I optimize this query? I read about optimization and found out that indexes might help but still could not achieve the desired performance.
Which index should be used and which should be removed?
Below is the explain of query:
Repairableissue
CREATE TABLE `repairableissue` (
`Vendor` varchar(40) NOT NULL,
`ItemName` varchar(200) NOT NULL,
`SerialNo` varchar(50) NOT NULL,
`person` varchar(200) NOT NULL,
`siteid` varchar(10) NOT NULL,
`invuser` varchar(50) NOT NULL,
`region` varchar(50) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`Dated` date NOT NULL,
`Sirno` varchar(50) NOT NULL,
`status` varchar(30) NOT NULL DEFAULT 'Pending',
`trackthrough` varchar(30) NOT NULL,
`reason` varchar(100) NOT NULL,
`ckh` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`WarehouseType` varchar(20) NOT NULL,
`WarehouseLocation` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `I1` (`status`),
KEY `ind2` (`ItemName`),
KEY `ind3` (`region`),
KEY `ind5` (`SerialNo`),
KEY `ind4` (`Sirno`)
) ENGINE=MyISAM AUTO_INCREMENT=63029 DEFAULT CHARSET=latin1
sir
CREATE TABLE `sir` (
`SirNo` varchar(50) NOT NULL,
`SiteId` varchar(80) NOT NULL,
`Vendor` varchar(70) NOT NULL,
`Type` varchar(15) NOT NULL,
`ItemDesc` varchar(200) NOT NULL,
`ItemCode` varchar(25) NOT NULL,
`SerialNo` varchar(50) NOT NULL,
`Unit` varchar(15) NOT NULL,
`AssetCode` varchar(50) NOT NULL,
`Qty` decimal(11,0) NOT NULL,
`Region` varchar(15) NOT NULL,
`Status` varchar(20) NOT NULL DEFAULT 'Installed',
`FaultInfo` varchar(100) NOT NULL DEFAULT 'date()',
`chk` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`Phase` varchar(15) NOT NULL,
`Category` varchar(200) NOT NULL,
`Issue_Vendor` varchar(30) NOT NULL,
`AssetName` varchar(150) NOT NULL,
`Ownership` varchar(20) NOT NULL,
`Dated` date NOT NULL,
`PersonName` varchar(150) NOT NULL,
`Remarks` varchar(300) NOT NULL,
`po` varchar(100) NOT NULL,
`invuser` varchar(50) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`grnno` varchar(30) NOT NULL,
`WarehouseType` varchar(20) NOT NULL,
`WarehouseLocation` varchar(20) NOT NULL,
`mainpartserial` varchar(200) NOT NULL,
PRIMARY KEY (`Vendor`,`Type`,`ItemCode`,`ItemDesc`,`SerialNo`,`Ownership`,`SirNo`,`Region`,`WarehouseType`,`WarehouseLocation`,`po`,`Qty`,`id`),
KEY `id` (`id`),
KEY `ind4` (`ItemDesc`),
KEY `ind6` (`SerialNo`),
KEY `ind7` (`SerialNo`)
) ENGINE=MyISAM AUTO_INCREMENT=228007 DEFAULT CHARSET=latin1
One multi-column index on r.status + r.warehouseLocation, in that order.
One multi-column index on sir.sirno + sir.region + sir.Itemdesc + sir.Serialno, in order of most cardinality to least cardinality, with sir.qty tacked on the end.
This assumes the fields are small enough to fit (combined) into an index.
Still, join seeks are unavoidable. The number of records that match r.status='Pending' is going to dictate the speed of this query.

MySQL most faster results with indexes

I have the following structure with indexes that help us to retrieve faster:
CREATE TABLE IF NOT EXISTS `index_site` ( `id_building` char(32) NOT NULL, `id_client` char(32) NOT NULL, `id_broker` smallint(5) unsigned NOT NULL, `kind_client` char(1) NOT NULL, `city` smallint(6) unsigned NOT NULL, `lat` float(10,6) NOT NULL, `lng` float(10,6) NOT NULL, `zone` smallint(2) unsigned NOT NULL, `sector` smallint(4) unsigned NOT NULL, `subregion` smallint(6) unsigned NOT NULL, `country` char(2) NOT NULL, `habs` smallint(5) unsigned NOT NULL, `bath` smallint(5) unsigned NOT NULL, `persons` smallint(5) unsigned NOT NULL, `include_elevator` enum('1','0') NOT NULL, `build_level` varchar(20) NOT NULL, `area` mediumint(8) unsigned NOT NULL, `area_um` enum('1','2','3','4','5') NOT NULL, `area_str` varchar(10) NOT NULL, `code` char(10) NOT NULL, `title` tinytext NOT NULL, `type_offer` varchar(50) NOT NULL, `offer_name` varchar(20) NOT NULL, `comments` text NOT NULL, `type_building` varchar(50) NOT NULL, `address` tinytext NOT NULL, `sector_name` tinytext NOT NULL, `city_name` varchar(50) NOT NULL, `subregion_name` varchar(50) NOT NULL, `area_terrain` varchar(10) NOT NULL, `area_um_terrain` tinyint(4) NOT NULL, `image` varchar(70) NOT NULL, `image_total` tinyint(2) unsigned NOT NULL, `build_status` tinyint(3) unsigned NOT NULL, `tags` text NOT NULL, `url` varchar(200) NOT NULL, `include_offer_value` enum('1','0') NOT NULL, `offer_value` varchar(15) NOT NULL, `offer_value_format` varchar(20) NOT NULL, `prc_comission` varchar(5) NOT NULL, `date_added` datetime NOT NULL, `date_updated` datetime NOT NULL, `date_expire` datetime NOT NULL, `date_suspended` date NOT NULL, `visits` int(11) NOT NULL, `kind_offer` tinyint(4) NOT NULL, `kind_building` tinyint(5) unsigned NOT NULL, `kind_building_type` tinyint(5) unsigned NOT NULL, `mark_bld` tinyint(3) unsigned NOT NULL, `mark_bld_color` char(7) NOT NULL, `status` tinyint(1) unsigned NOT NULL, `is_made` enum('0','1') NOT NULL, `is_project` enum('0','1') NOT NULL, `is_bm` enum('0','1') NOT NULL, `is_demo` enum('0','1') NOT NULL, `is_leading` enum('0','1') NOT NULL, `visible_in_metasearch` mediumtext NOT NULL, `visible_in_web` mediumtext NOT NULL, `seller_image` varchar(150) NOT NULL, `seller_name` varchar(50) NOT NULL,
KEY `id_broker` (`id_broker`), KEY `id_client` (`id_client`), KEY `kind_building` `kind_building`), KEY `city` (`city`), KEY `offer_value` (`offer_value`), KEY `is_bm` (`is_bm`), KEY `status` (`status`), KEY `sector` (`sector`), KEY `zone` (`zone`), KEY `area` (`area`), KEY `prc_comission` (`prc_comission`), KEY `is_made` (`is_made`), KEY `is_leading` (`is_leading`), KEY `id_building` (`id_building`), KEY `date_added` (`date_added`), KEY `code` (`code`), KEY `country` (`country`), KEY `habs` (`habs`), KEY `kind_offer` (`kind_offer`), FULLTEXT KEY `tags` (`tags`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;
Yes, it's too big!!! :)
Okay, the topic is in structure I use some keys when I find results; this is normal and I execute the following query:
SELECT * FROM `index_site` WHERE kind_building='1' AND kind_offer='1' AND city='1'
This query took 0.0179 seconds, great, but I add EXPLAIN to my query:
EXPLAIN SELECT * FROM `index_site` WHERE kind_building='1' AND kind_offer='1' AND city='1'
I got the following result:
+----+-------------+------------+-------------+-------------------------------+-------------------------------+---------+------+------+-------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------------+-------------------------------+-------------------------------+---------+------+------+-------------------------------------------------------------+
| 1 | SIMPLE | index_site | index_merge | kind_building,city,kind_offer | kind_offer,city,kind_building | 1,2,1 | NULL | 184 | Using intersect(kind_offer,city,kind_building); Using where |
+----+-------------+------------+-------------+-------------------------------+-------------------------------+---------+------+------+-------------------------------------------------------------+
And I use the right keys but in the column Extra by MySQL when I get "Using where" they say that "you look something is wrong".
My question is, if I have a correct query with indexes, What is the problem to get "Using where" Whats wrong?
Thanks for your help!
From the docs:
If the Extra column also says Using where, it means the index is being used to perform lookups of key values.
You are selecting all fields (*) from the table.
Since not all fields are covered by indexes used in the merge intersect, the fields need to be looked up in the table itself.
Try running this:
SELECT kind_building, kind_offer, city
FROM index_site
WHERE kind_building = '1'
AND kind_offer = '1'
AND city = '1'
, and Using where should go.