Is there a way to do this?
In case the DBMS command history got cleaned or, in my case, when many ALTER TABLE were used in the course of time.
I'm using MySQL.
Yes, it is as simple as
SHOW CREATE TABLE yourtable;
This will include all the subsequent ALTER TABLE statements. You cannot retrieve the table's original state.
Here is the relevant documentation
Related
I have a schema that is used to archive a data set on a daily basis. Some of the analysis needs to look back, so to optimise things I need to create a couple of indexes on each table. These would be seperate (I'm not trying to cross index or anything) just a simple non-unique index, but on each table in the schema.
The archive has already been building for over a year, so we have some 400 - 500 tables, making a manual ALTER query on each tablea bit too time consuming.
I could write a php script to do it, but wondered if there was a more elegant solution with a single query or transaction?
TIA
I have copied #Shadow's answer in the comments above here to show it as the answer:
Well, the alter table and add index sections will be string constants as you have to generate the alter table statements and then execute the alter table statements you generated in the first step. See an example here: stackoverflow.com/a/44527818/5389997
In MySQL, which is a better practice? Always use "CREATE TABLE IF NOT EXISTS", or check first the existence of the table using "SHOW TABLES LIKE" before making the table?
I have to regularly save a page where the table for it may or may not be there (sometimes, it is deliberately deleted when not in use). Previously, I used to do "SHOW TABLES LIKE" to check if that table exists before I insert new entries. But I changed it to "CREATE TABLE IF NOT EXISTS". Either way, I just do a "INSERT .. ON DUPLICATE UPDATE" to add new or update existing data.
I don't know how to benchmark this, which is why I am asking.
Performance isn't critical with these operations.
The key aspect is race conditions. If you use CREATE TABLE IF NOT EXISTS you know it will happen or it won't. If two threads happen to be doing this statement one will succeed and the other won't be negatively affected.
If a SHOW TABLE LIKE was used in both threads, both could detect the table didn't exist, and upon trying to create the table, one would fail.
So use CREATE TABLE IF NOT EXISTS to mitigate race conditions. Also in general is better to use a database provided feature than roll your own.
CREATE TABLE IF NOT EXISTS is option provided by MySQL and good to use. If table will not exist this statement will create else will skip.
other end, if you first check table existence by show table like then either skip or create as per result of condition/check. Ultimately you are increasing one step or runtime of you script or program for same functionality which you can achieve in single step.
I want to create a history table for actions done inside the database, the easiest way i thought was to create a history table that was updated through a trigger on each table modified.
I would like to also include a userId so I can identify who changed it as well, but when i do my inserts/delete statements etc, I would also need to add in the userId (which kinda has no relevance to the operation), in order to use the history table as i described.
So is there a way to just put the userId into a SQL statement? Or should I just actually do the history table as a separate query after doing my insert / delete statements, rather than using a trigger
Thanks in advance
Grant
It will be the best practices to add user column in main table which we can easily use in trigger to inserts/delete/update in history table.
I need to put all the result of a query to a temporary table then select from it, but due to the nature of the temporary table, I cannot refer to it more than once in the same query. So is it ok to create a uniquely named (regular) table for this and drop it after the query is completed? Or is there a better way to do this?
I tried using Derived tables but I cannot access it from different blocks.
It's not necessarily a matter of whether it's good practice or not. Whether it's a regular table, temporary table or derived table they all serve a purpose when trying to accomplish a task. Therefore, creating a regular table or a temporary table all depends on you and what you want your application to accomplish at the end of the day.
But based on your problem it seems that you might need to create a regular table in this situation since you require access to the table more than once, and you can drop the table after you're finished with it.
Is there a way to rename a column on an InnoDB table without a major alter?
The table is pretty big and I want to avoid major downtime.
Renaming a column (with ALTER TABLE ... CHANGE COLUMN) unfortunately requires MySQL to run a full table copy.
Check out pt-online-schema-change. This helps you to make many types of ALTER changes to a table without locking the whole table for the duration of the ALTER. You can continue to read and write the original table while it's copying the data into the new table. Changes are captured and applied to the new table through triggers.
Example:
pt-online-schema-change h=localhost,D=databasename,t=tablename \
--alter 'CHANGE COLUMN oldname newname NUMERIC(9,2) NOT NULL'
Update: MySQL 5.6 can do some types of ALTER operations without rebuilding the table, and changing the name of a column is one of those supported as an online change. See http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html for an overview of which types of alterations do or don't support this.
If there aren't any constraints on it, you can alter it without a hassle as far as I know. If there are you'll have to remove the constraints first, alter and add the constraints back.
Altering a table with many rows can take a long time (though if the columns involved are not indexed, it may be trivial).
If you specifically want to avoid using the ALTER TABLE syntax created specifically for that purpose, you can always create a table with almost the exact same structure (but different name) and copy all the data into it, like so:
CREATE TABLE `your_table2` ...;
-- (using the query from SHOW CREATE TABLE `your_table`,
-- but modified with your new column changes)
LOCK TABLES `your_table` WRITE;
INSERT INTO `your_table2` SELECT * FROM `your_table`;
RENAME TABLE `your_table` TO `your_table_old`, `your_table2` TO `your_table`;
For some ALTER TABLE queries, the above can be quite a bit faster. However, for a simple column name change, it could be trivial. I might try creating an identical table and performing the change on it in order to see how much time you're actually looking at.