MYSQL How to safely remove UNIQUE KEY? What to have in mind? - mysql

I have a table in database.
CREATE TABLE `comment_sheets` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`doc_id` mediumint(9) NOT NULL,
`level` varchar(10) DEFAULT NULL,
`author` varchar(30) DEFAULT NULL,
`status` varchar(10) DEFAULT NULL,
`creation_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `cs` (`doc_id`,`level`,`author`)
) ENGINE=InnoDB AUTO_INCREMENT=3961075 DEFAULT CHARSET=utf8 ;
My UNIQUE KEY cs (doc_id,level,author) is a problem now. I want to remove it, becouse i need duplicate values.
My question is. What should i have in my mind or what shoud I be worry about, when i want delete unique key?
Thanks.

To drop unique key
ALTER TABLE table_name
DROP INDEX index_name;
To drop primary key
ALTER TABLE table_name
DROP INDEX `PRIMARY`;

You need to alter table:
alter table comment_sheets drop INDEX `cs`

It really depends on how the key is used apart from enforcing uniqueness of data.
Check if the key is used in any foreign key relationships. If yes, you need to drop the foreign key before you can drop the unique one. (Well, mysql won't let you drop the index if the foreign key exits anyway)
Check what queries may make use of the key and how its removal would affect their performance. You may have to add a non-unique key on these fields back.
I this particular case dropping the index is relatively simple task because it is not the primary key, and it is not a fulltext index. The only thing that may take long is the removal of the index data if your table is big (judging from the auto increment value, it is not a small table)

Related

How can I delete the rows of a table which stores foreign keys?

THE SOLUTION IS BELOW
I have three tables like the following:
CREATE TABLE `t_arch_layer` (
`arch_layer_id` int(11) NOT NULL AUTO_INCREMENT,
`arch_layer_name` varchar(45) NOT NULL,
PRIMARY KEY (`arch_layer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
CREATE TABLE `t_tech` (
`tech_id` int(11) NOT NULL AUTO_INCREMENT,
`tech_name` varchar(45) DEFAULT NULL,
`tech_type_id` int(11) NOT NULL,
`tech_icon` text,
PRIMARY KEY (`tech_id`),
KEY `fk_t_tech_t_tech_type1_idx` (`tech_type_id`),
CONSTRAINT `fk_t_tech_t_tech_type1` FOREIGN KEY (`tech_type_id`) REFERENCES `t_tech_type` (`tech_type_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;
CREATE TABLE `t_arch_layer_tech` (
`arch_layer_id` int(11) NOT NULL,
`tech_id` int(11) NOT NULL,
PRIMARY KEY (`tech_id`,`arch_layer_id`),
KEY `fk_t_layer_has_t_tech_t_tech1_idx` (`tech_id`),
KEY `fk_t_layer_has_t_tech_t_layer1_idx` (`arch_layer_id`),
CONSTRAINT `fk_t_layer_has_t_tech_t_layer1` FOREIGN KEY (`arch_layer_id`) REFERENCES `t_arch_layer` (`arch_layer_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_t_layer_has_t_tech_t_tech1` FOREIGN KEY (`tech_id`) REFERENCES `t_tech` (`tech_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Basically it's a tipical situation where one table use two foreign keys from another two different tables. This table stores the possible combinations between the layers and technologies so it can't store any combination of layer_id and tech_id which is not in both.
But there is a problem, I need to delete whenever I want some row from t_arch_layer_tech. This it's impossible due to the foreign keys, I know it.
My question is, is there something to use the foreign key as a reference to forbide insert values that there aren't into t_tech or t_arch_layer and also to be consider as "own fields" (I can't explain better) of the table in order to delete any row of the t_arch_layer_tech table? Delete t_tech and t_arch_layer tables to avoid the foreign keys and then set the limits into the t_arch_layer_tech is not a solution.
SOLUTION
When that error appears it's neccesary to check the DB relationships and read carefully the provided message. It seems useless but it helped me to understand what's happening with the t_arch_layer_tech FK. I was using them into another table BUT separately, not as a compound FK. This is the reason because I could insert some rows into t_arch_layer_tech and delete only specific pairs.
So, summarizing, if you are going to use FKs that exist together (as my pair "arch_layer_id, tech_id") create ONLY ONE FK which is a compound FK that uses the mentioned.

Odd Error in mariaDB Foreign Keys

Hi i hope some one can help my problem is that when i try to add a foreign key constraint i get this error.
My database name is "hazard"
Child:
CREATE TABLE `child` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`a` INT(11) NULL DEFAULT NULL,
`b` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
Parent:
CREATE TABLE `parent` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`alfa` INT(11) NULL DEFAULT NULL,
`beta` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
Those are the create codes (using HeidiSQL)
and when i try to add a foreign key
with
ALTER TABLE CHILD MODIFY COLUMN A INT,add constraint fk_parent_child FOREIGN KEY(A) REFERENCES PARENT(ALFA);
or
ALTER TABLE CHILD add constraint fk1 foreign key (a) references parent(alfa);
I get the same error
Can't create table 'hazard.#sql-d04_53' (errno: 150)
this is happening to many of my classmates using MariaDB and mySQL
Beforehand an apology for the inconvenience and I hope you guys can help us.
Add
KEY (`alfa`)
to the parent table. "The referenced columns must be a PRIMARY KEY or a UNIQUE index." – https://mariadb.com/kb/en/mariadb/foreign-keys/
http://sqlfiddle.com/#!9/b4c12
Error 150 usually means you are updating the tables in the wrong order. That is, your first INSERT violates the FOREIGN KEY constraint that your second INSERT will fix.
In your case you are doing ALTER instead of INSERT. Swap the order of the ALTERs. If that does not work, check the data to see that you won't be violating FK constraints. If you get past that, read on...
In extreme cases, you can turn off foreign key constraints while doing the inserts, then turn them back on. (But that leaves you vulnerable to screw-ups.)

What does the line " KEY `idx_pid` (`person_id`), " mean?

I am new to mysql and am working on an online server (MYSQL version 5.1.69) and i have the following table
CREATE TABLE `person_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`person_id` int(11) NOT NULL,
`info_type_id` int(11) NOT NULL,
`info` text NOT NULL,
`note` text,
PRIMARY KEY (`id`),
KEY `idx_pid` (`person_id`),
KEY `person_info_info_type_id_exists` (`info_type_id`)
)
Can someone explain to me what " KEY idx_pid (person_id)," does?
KEY, in MySQL, is an alias for INDEX; you can see this in the pseudo grammar in the CREATE TABLE documentation:
[INDEX|KEY] [index_name] (index_col_name,...)
It represents the definition of an index on a table, and nothing more. Here,
KEY `idx_pid` (`person_id`),
…creates an index named "idx_pid" on the column "person_id". This could have also been written as,
INDEX `idx_pid` (`person_id`),
However, MySQL's SHOW CREATE TABLE command (and other commands) will prefer KEY. It is an unfortunate choice for a keyword here, as it has nothing to do with a “key¹” in the relational databases sense of the word.
¹A key, in relational database theory, is a set of columns that uniquely identify a row.
It means you're creating an index named "idx_pid" on the person_info.person_id column.
This adds an index named idx_pid on the person_id column which speeds up queries using the persond_id as condition.
You can read up on MySQL indexes here.

Altering a table primary key which has foreign key constrains in mysql

I have a mysql database which have set of tables One table have a composite key as the primary key and and a single foreign key. Following are the table definitions.
CREATE TABLE IF NOT EXISTS `ohrm_emp_education` (
`emp_number` int(11) NOT NULL,
`education_id` int(11) NOT NULL,
`institute` varchar(100) DEFAULT NULL,
`major` varchar(100) DEFAULT NULL,
`year` decimal(4,0) DEFAULT NULL,
`score` varchar(25) DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
PRIMARY KEY (`emp_number`,`education_id`),
KEY `education_id` (`education_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `ohrm_emp_education`
ADD CONSTRAINT `ohrm_emp_education_ibfk_1` FOREIGN KEY (`emp_number`) REFERENCES `hs_hr_employee` (`emp_number`) ON DELETE CASCADE,
ADD CONSTRAINT `ohrm_emp_education_ibfk_2` FOREIGN KEY (`education_id`) REFERENCES `ohrm_education` (`id`) ON DELETE CASCADE;
But now I need to add a new column to this existing table and make it as the primary key. I tried it with the following query.
ALTER TABLE ohrm_emp_education
ADD column id int not null AUTO_INCREMENT,
DROP PRIMARY KEY,
ADD primary key (id)
But it shows following error
#1025 - Error on rename of './test/#sql-4f6_19b' to './test/ohrm_emp_education' (errno: 150)
I tried with several answers which are found on the internet but couldn't solve it properly. Can someone help me on this. Thanks in advance.
Try to delete foreign keys first, something like this:
ALTER TABLE `ohrm_emp_education` DROP FOREIGN KEY `emp_number`;
ALTER TABLE `ohrm_emp_education` DROP FOREIGN KEY `education_id`;
And then alter table.
If you are using SQL Server Management Studio.
Then right click on the table and click design.
Then right click on the row which contains the composite key
and click on remove primary key
then add new column
and insert data into that column
and check that the column has no empty data.
Then again go to design view
and right click on the required column and click on Set as Primary Key
You're Done!!
You usually get this error if your tables use the InnoDB engine. In that case you would have to drop the foreign key, and then do the alter table and drop the column.
drop/disable foreign key constraint. Drop primary key, add new PK, enable/add fk.

database design: User will submit a howto, each howto will have one or more steps associated with, each step can have random pictures associated with

I am trying to design a database but I need some help with the relationships. Am i getting the table design right?
Here is the database idea..
User will submit a howto, each howto will have one or more steps associated with(a one to many). each step can have random pictures associated with(another one to many). so I am thinking of this:
CREATE TABLE `HowtoStepImage`
`id` int(10) unsigned NOT NULL auto_increment,
`user_id` int(10) unsigned NOT NULL,
`howto_id` varchar(25) NOT NULL,
`step_id` varchar(25) NOT NULL,
`img_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `hsi_k_1` (`howto_id`),
CONSTRAINT `hsi_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
CONSTRAINT `hsi_ibfk_2` FOREIGN KEY (`step_id`) REFERENCES `HowtoStep` (`step_id`),
CONSTRAINT `hsi_ibfk_3` FOREIGN KEY (`img_id`) REFERENCES `StepImage` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
table HowtoStep
step_id, title, content, created
primary key (step_id)
table StepImage
img_id, filename, created
CREATE TABLE `UserHowtoComment` (
`id` int(10) unsigned NOT NULL auto_increment,
`howto_id` varchar(25) NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`comment` varchar(500) NOT NULL,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `UserHowtoComment_ibfk_1` (`howto_id`),
KEY `UserHowtoComment_ibfk_2` (`user_id`),
CONSTRAINT `UserHowtoComment_ibfk_1` FOREIGN KEY (`howto_id`) REFERENCES `HowtoStepImage` (`howto_id`),
CONSTRAINT `UserHowtoComment_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
however, I am getting error when creating the table, I am sure it is due to my database design. here is what mysql>SHOW ENGINE INNODB STATUS; shows:
091217 9:59:59 Error in foreign key constraint of table UserhowtoComment:
FOREIGN KEY (`howto_id`) REFERENCES `howtoStepImage` (`howto_id`),
CONSTRAINT `UserHowtoComment_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
the howto_id is a key(index) in UserHowtoComment though. I am not sure if that is the exact problem here..
Make 3 tables: one for HowTo, one for HowToStep, one for HowToStepImage.
Give each table a clearly defined key, e.g. a number or a string.
Then let the 'child' table refer to the key of the parent table.
Make sure that the columns have clear names as well.
TABLE HowTo
COLUMNS HowToId(key)
TABLE HowToStep
COLUMNS HowToStepId(key), HowToId
TABLE HowToStepImage
COLUMNS HowToStepImageId(key), HowToStepId
your query is really messy e.g. step_id varchar(25) needs to be an int.
why dont you just use a gui programm or maybe the good old phpMyAdmin, so you can learn the from the Querys they are creating, phpMyAdmin also has a advanced feature call "Designer" to create constraints.
If I read this correctly, your HowToComment id is a foreign key to HowtoStepImage. Does every comment have to have an image? Seems like a chicken and the egg issue. It seems, from your problem description, that an image links to a comment, not the other way around.
you're falling prey to the misleading terminology in MySQL. in the relational model, key is (necessarily) distinct. in the MySQL-speak, it's just an index. you need either PRIMARY KEY or UNIQUE KEY.
edit to add explicitly what is implied above: foreign keys must point to a key in the relational sense.