I'm considering using pt-online-schema-change to ALTER a primary key (changing it from one column, to a composite primary index) of a table. Are there any limitations to doing this? The documentation states
In most cases the tool will refuse to operate unless a PRIMARY KEY or
UNIQUE INDEX is present in the table. See --alter for details.
Well, don't do that.
Running pt-online-schema-change on a table w/o a single column unique index, may result in a loss of data. See #3 here: http://www.pythian.com/blog/important-caveats-when-using-pt-online-schema-change/
Related
When I add a primary key to a table that already has data, what does each of these database management systems do?
Do they analyze each and every value of the column to confirm it is unique ?
Or do they have some other optimized mechanism ? And if that's the case, what is that mechanism ?
Yes, at least in PostgreSQL and MySQL (probably MonetDB too) the DBMS will first check if all values are unique (like when you use a "unique" parameter in your sql query). You can simulate it by counting all rows and then counting a "unique" select of the same rows. If the row numbers are not equal, you will not be able to create the primary key.
An index really is created, but only to speed things up when you use the primary key after its created.
Currently I am using DBGen to generate the database which will be used to generate the TPC-H benchmarks. I am import the files (raw data directly from DBGen) into both mysql and postgres. After the data is imported, I need to add primary key as well as foreign keys onto the existing tables.
I am using the most simple command to add primary keys and foreign keys.
According to my own experience, postgres run much faster than mysql (especially handling big tables, 1.4 GB lineitem table in my case).
But does anyone know why it is the case?
Does it mean that the two systems do something very differently when they are trying to add primary key or foreign keys?
When you add and remove PRIMARY KEYs in MySQL, it rebuilds the entire table -- so effectively re-imports it by making a copy of it.
In addition to being a general limitation (this happens with MyISAM too), InnoDB is stored as a "Clustered Primary Key", that is, the rows are internally stored in a tree based on the primary key.. so the primary key is integral to how the table is stored, and sorted... so even if it could somehow do this without copying everything it would have to basically completely re-organise everything anyway.
See: https://dev.mysql.com/doc/refman/5.6/en/innodb-index-types.html
I would suggest adding the PRIMARY KEY before you import the data, so that you only need to do it once.
You should be able to add secondary indexes and foreign key references online, without a table copy. See:
https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html
https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-limitations.html
In MySQL Workbench's EER diagram, there is a checkbox to make each column in a table unique, not null, primary key etc.
However, I would like to have a UNIQUE constraint on multiple columns. Is it possible to add it in in MySQL Workbench's EER diagram?
EDIT: Ok, I realised the unique checkbox, creates a UNIQUE INDEX, and not a UNIQUE CONSTRAINT
In the Alter Table dialog of MySQL Workbench:
Go to Indexes tab.
Double-click on a blank row to create a new index.
Choose 'UNIQUE' as the index type.
Check the columns that you want to be unique together.
There's some discussion as to whether this is weird, since an index is not the same as a constraint. I certainly wouldn't have thought to look there. However, apparently the `unique index' enforces uniqueness in the same way as a unique constraint, and may improve performance. For example, if I try to insert a row that would break unique together after using this method, it throws an '1062 Duplicate entry' error.
it does not seem to be available : http://bugs.mysql.com/bug.php?id=48468 . it seems what you can is to create a multi column unique index on the indexes tab but for a multi column unique constraint, you need to run the creation command manually.
With latest MWB (I'm on 6.0.8), it is possible to create composite keys
If you wish to create a composite primary key you can select multiple columns and check the PK check box. However, there is an additional step that is required, you must click the Indexes tab, then in the Index Columns panel you must set the desired order of the primary keys.
The relation of PRIMARY is equal to fk_student_single_user1. So i must remove one of them.
The problem is, i can't remove or rename PRIMARY in workbench, the program does not allow, and if i delete fk_student_single_user1, i also delete the foreign key. The only way is delete PRIMARY in the phpmyadmin.
But i think that exists any problem in my eer model, it is supposed an export without bugs.
I deleted my previous column id, because two foreign keys can be the primary key of the table.
How i can solve that?
Try deleting the foreign key, dropping the needless fkey index, and re-adding the foreign key using plain sql (alter table...) rather than your GUI.
The SQL spec requires a unique index on the target column, so there's no reason to add an extra (non-unique) index on top.
If MySQL still adds the index, you might want to report it as a bug (as well as to http://sql-info.de/mysql/gotchas.html).
If not, you might want to investigate whether the index was added by your GUI in the first place. And if so, report the issue as a bug to the GUI's creator.
I saw some other questions related to this, but they were not MySQL.
The database is a live database, so I don't want to delete and recreate the table. I simply want to make a column no longer unique, which is less permissive in nature so it shouldn't cause any problems.
If your column was defined unique using UNIQUE clause, then use:
ALTER TABLE mytable DROP INDEX constraint_name
, or, if your constraint was implicitly named,
ALTER TABLE mytable DROP INDEX column_name
If it was defined unique using PRIMARY KEY clause, use:
ALTER TABLE mytable DROP PRIMARY KEY
Note, however, that if your table is InnoDB, dropping PRIMARY KEY will result in implicit recreation of your table and rebuilding all indexes, which will lock the table and may make it inaccessible for quite a long time.
These are instructions for phpmyadmin app (if you are using phpMyAdmin) ::
In a some cases, the developer (you) may not want to drop it but rather just modify the "uniqueness" to "not-unique".
Steps :
Go to the table in context, where you want to make the modification
Click on the "Structure" tab (mostly next to Browse)
Look for the "+Indexes" link, just under the columns. Yeah... now click it
Now you can see all the "Indexes" and you can now click on the "DROP" button or link to modify.
Answer was found here :
Source : https://forums.phpfreaks.com/topic/164827-phpmyadmin-how-to-make-not-unique/
Just DROP the unique index. There shouldn't be a problem with the fact that it is a live DB. If it is a really large table, you may block some queries temporarily while the index is removed. But that should only happen if you were adding an index.
ALTER TABLE table_name DROP INDEX index_name;
Although the accepted answer is incorrect (see comments), the suggested workaround is possible. But it is not correct too, at least for a "live table", as asked.
To lower the impact you should create a new index at first, and then delete the old one:
ALTER TABLE mytable ADD INDEX idx_new (column);
ALTER TABLE mytable DROP INDEX idx_old;
This avoids using the table (column) without index at all, which can be quite painful for clients and the MySQL itself.
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast (MySQL Manual).
If the unique key that you want to make non-unique is used by a foreign key constraint, then you'll get an error when dropping it. You will have to recreate it on the same line:
alter table mytable drop KEY myUniqueKey, add key myUniqueKey (myColumn);