How to remove unique constraint in MySQL? - mysql

I was searching online about how to remove unique constraint in MySQL in the Internet and I found a lot of solutions.
DROP INDEX index_name ON table_name;
ALTER TABLE table_name
DROP INDEX index_name;
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
What's the difference between all these queries? Which one of these queries is according to standard SQL?
Also, what's the difference between unique constraint, unique index, and unique key?

Many users of SQL do not realize that indexes are not in the SQL standard.
Go ahead, try to find CREATE INDEX, DROP INDEX, or any of the other related syntax for indexes in the ANSI/ISO SQL specification.
Constraints are in the specification. Here are links to coverage of UNIQUE CONSTRAINT in the online version of the book "SQL-99, Complete, Really"
https://crate.io/docs/sql-99/en/latest/chapters/20.html#constraint-type-unique-constraint
https://crate.io/docs/sql-99/en/latest/chapters/20.html#dropping-constraints
A UNIQUE constraint describes a logical limitation on the behavior INSERT/UPDATE/DELETE operations performed on a given table. That is, no two rows may have the same non-NULL values in the unique column(s) named in the constraint.
But indexes are an implementation detail, and the SQL standard leaves implementation details up to the vendor.
It just happens that adding an index data structure is the most common way to make implementation of a constraint have a hope of being efficient. So virtually all SQL vendors have some kind of feature like that, and they extend SQL syntax with the necessary statements and clauses to support indexes.
It's frankly a miracle that the index syntax is as similar between vendors as it is. This gives users an impression that the vendors are complying with some part of the SQL standard. They are not; they are just mimicking earlier implementations.
Re your comment:
These two queries accomplish the same thing. There is no difference in semantics, only syntax.
DROP INDEX index_name ON table_name;
ALTER TABLE table_name
DROP INDEX index_name;
For example, with ALTER TABLE, you could combine dropping the index with other alter operations on the same table, such as dropping multiple indexes, or creating new indexes, or any other alteration.
But DROP INDEX only allows you to drop one index on one table.
Then the third query drops a constraint. Constraints are not indexes.
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
This may have the effect of dropping an index, but not necessarily. It depends on what type of constraint you are dropping. For example, dropping a UNIQUE constraint implicitly drops the index associated with that constraint. Whereas dropping a FOREIGN KEY or CHECK constraint does not drop an index on the same column.

DROP INDEX index_name ON table_name;
and
ALTER TABLE table_name
DROP INDEX index_name;
are absolutely the same. Moreover, first query is really mapped to second one.
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
performs another function.
Index is a structure within the table. DROP INDEX drops the index (sorry..).
Constraint is a rule within the table, this rule may be accompanied by according index creation for constraint maintainance. DROP CONSTRAINT drops the constraint. But if the index for its maintainance was created then the index is not dropped. See fiddle.

As of MySQL 8.0.19, ALTER TABLE permits more general (and SQL standard) syntax for dropping and altering existing constraints of any type, where the constraint type is determined from the constraint name:
Drop an existing constraint named symbol:
ALTER TABLE tbl_name
DROP CONSTRAINT symbol;
Source
The SQL standard specifies that all types of constraints (primary key, unique index, foreign key, check) belong to the same namespace. In MySQL, each constraint type has its own namespace per schema. Consequently, names for each type of constraint must be unique per schema, but constraints of different types can have the same name. When multiple constraints have the same name, DROP CONSTRAINT and ADD CONSTRAINT are ambiguous and an error occurs. In such cases, constraint-specific syntax must be used to modify the constraint. For example, use DROP PRIMARY KEY or DROP FOREIGN KEY to drop a primary key or foreign key.
Source
So, technically, on MySQL 8.0.19 or above, we can use ALTER TABLE tbl_name DROP CONSTRAINT constraint_name to remove a UNIQUE constraint. But, in case if some other constraint has the same name as UNIQUE constraint, this method won't work. In such cases, we must use ALTER TABLE tbl_name DROP INDEX index_name or DROP INDEX index_name ON tbl_name to remove the UNIQUE constraint.
The difference between ALTER TABLE tbl_name DROP INDEX index_name and DROP INDEX index_name ON tbl_name has been explained in this answer.

Related

Disable auto indexing of mysql

I understand MySQL is automatically placing an index on every table's primary and foreign keys.
However, I would like to personally create my own indices on the foreign keys as I want to execute a query with hibernate showing the difference in time when I execute it with and without indices.
Is there any option in MySQL Workbench to disable it's auto indexing feature?
No you cannot disable the auto index creation of index on tables. This is a inbuilt feature which is added in MySql.
However if you want you can drop the index like this:
DROP INDEX index_name ON tbl_name
and then create it again.
From InnoDB and FOREIGN KEY Constraints
"InnoDB 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 is in contrast to some older versions, in which indexes
had to be created explicitly or the creation of foreign key
constraints would fail.) index_name, if given, is used as described
previously."
No, these indexes are always created. Otherwise, every UPDATE or INSERT that modifies these columns would have to perform a full table scan, to ensure that the primary key is unique and the foreign key has a valid reference.
Regarding foreign keys, the documentation says:
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.

MYSQL: foreign keys auto indexing

The below set of commands:
alter table opportunities add column ownerId int null;
alter table opportunities add foreign key (ownerId) references users (id) on delete set null on update cascade;
Yields an error like this:
Error in foreign key constraint of table taous/#sql-318c_27:
There is no index in table "taous"."#sql-318c_27" where the columns appear
as the first columns. Constraint:
foreign key (ownerId) references users (id) on delete set null on update cascade
;
So I understand that an index is lacking on the referenced column
Now, the mysql documentation for foreign key constraints states:
InnoDB 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 is in contrast to some older versions, in which indexes had to be created explicitly or the creation of foreign key constraints would fail.) index_name, if given, is used as described previously.
I run mysql 5.1 (xampp, windows) So I expect the columns to be indexed automatically on creation of a foreign key.
Any idea why can the auto indexing fail?
One more point:
The error only happens when the sql commands are run through PDO (a db update tool). When run directly in mysql console, no problems.
Thanks
Gidi
My understanding is that the auto-indexing is on the referencing table and not the referenced table.
In your case, the auto-indexing would add an index to ownerId in opportunities... except it doesn't need to, since you already did this.
I don't quite understand where "taous"."#sql-318c_27" comes from, but assuming that it relates to the users table, I believe the error is complaining that id is not indexed.
Another cause of this error could be that the types of the the referenced and referencing table columns do not match.
For example if the the ownerId column of the opportunities table is an INT but the Id column of the users is any type other than INT
That doesn't explain why it would work with the console and not a PDO however, but maybe this helps someone else down the line.

Dropping Unique constraint from MySQL table

How can I drop the "Unique Key Constraint" on a column of a MySQL table using phpMyAdmin?
A unique constraint is also an index.
First use SHOW INDEX FROM tbl_name to find out the name of the index. The name of the index is stored in the column called key_name in the results of that query.
Then you can use DROP INDEX:
DROP INDEX index_name ON tbl_name
or the ALTER TABLE syntax:
ALTER TABLE tbl_name DROP INDEX index_name
You can DROP a unique constraint from a table using phpMyAdmin as requested as shown in the table below. A unique constraint has been placed on the Wingspan field. The name of the constraint is the same as the field name, in this instance.
The indexes capable of placing a unique key constraint on a table are PRIMARY and UNIQUE indexes.
To remove the unique key constraint on a column but keep the index, you could remove and recreate the index with type INDEX.
Note that it is a good idea for all tables to have an index marked PRIMARY.
To add UNIQUE constraint using phpmyadmin, go to the structure of that table and find below and click that,
To remove the UNIQUE constraint, same way, go to the structure and scroll down till Indexes Tab and find below and click drop,
Hope this works.
Enjoy ;)
If you want to remove unique constraints from MySQL database table, use alter table with drop index.
Example:
CREATE TABLE unique_constraints (
unid INT,
activity_name VARCHAR(100),
CONSTRAINT activty_uqniue UNIQUE (activity_name),
PRIMARY KEY (unid)
);
ALTER TABLE unique_constraints
DROP INDEX activty_uqniue;
Where activty_uqniue is UNIQUE constraint for activity_name column.
For WAMP 3.0 :
Click Structure
Below Add 1 Column you will see '- Indexes'
Click -Indexes and drop whichever index you want.
The constraint could be removed with syntax:
ALTER TABLE
As of MySQL 8.0.19, ALTER TABLE permits more general (and SQL standard) syntax for dropping and altering existing constraints of any type, where the constraint type is determined from the constraint name: ALTER TABLE tbl_name DROP CONSTRAINT symbol;
Example:
CREATE TABLE tab(id INT, CONSTRAINT unq_tab_id UNIQUE(id));
-- checking constraint name if autogenerated
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'tab';
-- dropping constraint
ALTER TABLE tab DROP CONSTRAINT unq_tab_id;
db<>fiddle demo
This might help:
Inside your sql terminal
FIRST STEP:
SHOW INDEX FROM {YOUR_TABLE_NAME}
SECOND STEP:
SHOW INDEX FROM {YOUR_TABLE_NAME} WHERE Column_name='ACTUAL_COLUMN_NAME_YOU_GOT_FROM_FIRST_STEP_OUTPUT'
THIRD STEP:
ORIGINAL_KEY_NAME_VALUE = SECOND_STEP_RESPONSE["Key_name"]
FOURTH STEP:
ALTER TABLE {YOUR_TABLE_NAME} DROP INDEX ${ORIGINAL_KEY_NAME_VALUE}
while dropping unique key we use index
ALTER TABLE tbl
DROP INDEX unique_address;
my table name is buyers which has a unique constraint column emp_id now iam going to drop the emp_id
step 1: exec sp_helpindex buyers, see the image file
step 2: copy the index address
step3: alter table buyers drop constraint [UQ__buyers__1299A860D9793F2E]
alter table buyers
drop column emp_id
note:
Blockquote
instead of buyers change it to your table name :)
Blockquote
thats all column name emp_id with constraints is dropped!

Can I convert Innodb with foreign directly into mysiam?

I want to convert the db with innodb tables into myisam, all of them. How can I do these? there are some foreign keys exist among tables.
how can I make this in the best way?
You can't convert directly from InnoDB to MyISAM while the foreign keys are still there. You have to remove the constraints first. To do this, for each table follow these steps:
Issue SHOW CREATE TABLE tablename
For each CONSTRAINT ... FOREIGN KEY declaration in the output, you will need to issue ALTER TABLE tablename DROP FOREIGN KEY x where x is the identifier that appears between CONSTRAINT and FOREIGN KEY.
Issue SHOW CREATE TABLE tablename again. The foreign key constraints may have left behind indexes (since InnoDB requires an index on each foreign key, and it won't necessarily remove them just because you have removed the constraint). For each index you decide you no longer want, issue ALTER TABLE tablename DROP INDEX indexname.
Once you have done this for all tables that are involved with constraints, you can convert tables to MyISAM individually using ALTER TABLE tablename ENGINE=MYISAM.

Does MySQL index foreign key columns automatically?

Does MySQL index foreign key columns automatically?
Yes, but only on innodb. Innodb is currently the only shipped table format that has foreign keys implemented.
Apparently an index is created automatically as specified in the link robert has posted.
InnoDB 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 is in contrast to some older versions, in which indexes had to be created explicitly or the creation of foreign key constraints would fail.) index_name, if given, is used as described previously.
InnoDB and FOREIGN KEY Constraints
For those who are looking for quote from 5.7 docs:
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.
You don't get the index automatically if you do an ALTER TABLE (instead of CREATE TABLE), at least according to the docs (the link is for 5.1 but it's the same for 5.5):
[...] When you add a foreign key constraint to a table using ALTER TABLE, remember to create the required indexes first.
As stated it does for InnoDB. At first I thought it was strange that many other (in particular MS SQL and DB2) doesn't. TableSpace scans are only better than index scans when there are very few table rows - so for the vast majority of cases a foreign key would want to be indexed. Then it kind of hit me - this doesn't necessarily mean it has to be a stand alone (one column) index - where it is in MySQL's automatic FK Index. So, may be that is the reason MS SQL, DB2 (Oracle I'm not sure on) etc leave it up to the DBA; after all multiple indexes on large tables can cause issues with performance and space.
Yes, Innodb provide this. You can put a foreign key name after FOREIGN KEY clause or leave it to let MySQL to create a name for you. MySQL automatically creates an index with the foreign_key_name name.
CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action
It's not possible to get index key automatically use
ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)
Name of the table which you have created for example photographs and FOREIGN KEY for example photograph_id. The code should be like this
ALTER TABLE photographs ADD INDEX (photograph_id);