Don't fear the MySQL geekness! 
I have quite often seen people wrestle with easy problems. The trouble is, they don't really know the ins and outs of systems they work with. Very few times this was unresolvable by a bit more knowledge of how the software is used at a very basic, low level.
The most basic example of this is MySQL. Lots of people don't really learn SQL, they just get some GUI tool that does the "thinking" (mind the air-quotes) and generate all ALTER and CREATE queries for them in case of a structural change in the database. For productivity, this is fine, sure. However, if the availability of these tools is for some reason jeopardized, becoming somewhat helpless is inevitable.
I'm sometimes considered a bit of a geek for accessing my local MySQL databases through the command line MySQL tool. That black console just seems, short of a green font, "Matrixy". However, since I do, I know how to write a CREATE or ALTER statement, or even write patch scripts solely in MySQL. And this is where the advantage kicks in. Writing simple SQL patch files that can be loaded through a mysql command line interface, modifying the entire database to fit the code patches that are put live is a convenience, unsurpassed by any GUI tool I have ever seen.
So, I'd like give some pointers to get you started gaining the same experience, so you do not need to resort to patch scripts in another scripting language, unless you really have to.
Basic operations
I assume you know how to write select, update and delete statements, since you probably use them on a nearly daily basis. If you don't already master them, learn ALTER and CREATE. They are much simpler than you might think, considering they mostly consist of field and key definitions, which are really easy to master. I'll run into them soon.
The tricks
There are only four tricks you need to know to be able to write a lot of patch SQL without using any other tool or language:
SQL:
Now we are going to change the structure to remove the n:1 reference in the product table to the category table, and put them in a link table, so n:m relations are now possible1. We will put all the products of the first category in the new category too.
SQL:
Lastly, for the sake of the example, we are going to add a page_id field to the category table and let page_id's point to the page with the same title as the category. Let's just assume this is a sensible thing to do.
SQL:
Of course, the ON clause can contain other cool stuff, or you could use cross joins and write the conditions in a WHERE clause, whatever your preference.
Now, we can put this script in a patch file. I use a naming conventing where I put the current date, the name of the database and a short description of the script in the filename, and, if available, a bug ID from my issue tracker, so I'll call this one 2009.11.02-webshop-issue123.sql. It's a good habit so you can easily track back your patch SQL's. Of course, commit them to your version control system too.
I usually load a live dump into a development server and run the patch file as such:
code:
Get off the habit of tab-completion in a shell for these tasks, because there will be a time when you were sorry you knew tab-completion
Note the similarity in file names between the local and the live db dumps, for instance.
After testing your new local database, your patch script is ready to run live (or maybe at a staging server first, whatever you're used to), now you're good to go
Note I didn't drop the category_id column in the product table yet. It does no harm for now, and you should only drop it on your test and staging servers to track down possibly related bugs. You might consider just renaming it and dropping it after a few weeks.
1) Note: I'm leaving out constraints here, but if you're using InnoDB or another capable storage engine, be sure to master how to add, edit and delete foreign key constraints. I consider this outside the scope of this post for now.
The most basic example of this is MySQL. Lots of people don't really learn SQL, they just get some GUI tool that does the "thinking" (mind the air-quotes) and generate all ALTER and CREATE queries for them in case of a structural change in the database. For productivity, this is fine, sure. However, if the availability of these tools is for some reason jeopardized, becoming somewhat helpless is inevitable.
I'm sometimes considered a bit of a geek for accessing my local MySQL databases through the command line MySQL tool. That black console just seems, short of a green font, "Matrixy". However, since I do, I know how to write a CREATE or ALTER statement, or even write patch scripts solely in MySQL. And this is where the advantage kicks in. Writing simple SQL patch files that can be loaded through a mysql command line interface, modifying the entire database to fit the code patches that are put live is a convenience, unsurpassed by any GUI tool I have ever seen.
So, I'd like give some pointers to get you started gaining the same experience, so you do not need to resort to patch scripts in another scripting language, unless you really have to.
Basic operations
I assume you know how to write select, update and delete statements, since you probably use them on a nearly daily basis. If you don't already master them, learn ALTER and CREATE. They are much simpler than you might think, considering they mostly consist of field and key definitions, which are really easy to master. I'll run into them soon.
The tricks
There are only four tricks you need to know to be able to write a lot of patch SQL without using any other tool or language:
- First is temporary tables. Temporary tables exists for the span of your connection. As soon as your connection is gone, the table is deleted. This is awesome, since you can now consider the table an "in-memory variable".
- Second is variables. You can have variables that contain basic scalar values (like numeric and string values).
- Third is INSERT INTO ... SELECT statements. You can insert values into a table by selecting values from a query.
- Last is a joined UPDATE. You can add JOINs to the table clause in an UPDATE statement to easily transfer data from one table in the clause to another.
SQL:
1 | -- retrieve the ID of the row we want to copy
|
Now we are going to change the structure to remove the n:1 reference in the product table to the category table, and put them in a link table, so n:m relations are now possible1. We will put all the products of the first category in the new category too.
SQL:
1 | -- create the new table
|
Lastly, for the sake of the example, we are going to add a page_id field to the category table and let page_id's point to the page with the same title as the category. Let's just assume this is a sensible thing to do.
SQL:
1 | ALTER TABLE category
|
Now, we can put this script in a patch file. I use a naming conventing where I put the current date, the name of the database and a short description of the script in the filename, and, if available, a bug ID from my issue tracker, so I'll call this one 2009.11.02-webshop-issue123.sql. It's a good habit so you can easily track back your patch SQL's. Of course, commit them to your version control system too.
I usually load a live dump into a development server and run the patch file as such:
code:
1
2
3
| mysqldump -Q --opt my_db > 2009.11.02-local.sql mysql my_db < ./2009.11.02-live.sql mysql my_db < ./2009.11.02-webshop-issue123.sql |
After testing your new local database, your patch script is ready to run live (or maybe at a staging server first, whatever you're used to), now you're good to go
Note I didn't drop the category_id column in the product table yet. It does no harm for now, and you should only drop it on your test and staging servers to track down possibly related bugs. You might consider just renaming it and dropping it after a few weeks.
1) Note: I'm leaving out constraints here, but if you're using InnoDB or another capable storage engine, be sure to master how to add, edit and delete foreign key constraints. I consider this outside the scope of this post for now.
|
|
What PHP editor or IDE do you use? |
|
|
The horror of open source behemoths |
Comments
Real geeks use PostgresQL because they know it's better than MySQL. MySQL didn't even have transactional support for a long time. A database without transactions is worthless in a lot of environments. And MySQL had some huge security holes in the past. Those are facts. MySQL is okay now, but real geeks are used to working with PostgresQ - because from the start it was a lot more feature packed.
[Comment edited on Monday 02 November 2009 22:18]
Why is it that when I post something about FreeBSD, someone comes along and says "MacOSX!", when I post something about Subversion, "use GIT", and now this? It doesn't matter what you think is better, what matters is that someone might benefit from this post, even if some evangelist is so kind to deliver the good message about real salvation that isn't in this world, excuse the analogy.

[Comment edited on Monday 02 November 2009 22:08]
@drm: hmm, maybe you've found yourself a new blogpost item! 
[Comment edited on Monday 02 November 2009 22:11]
Nice post! I am sure that it is useful for people that are not so familiar with MySql (or Sql in general).
read this post just for interest i hardly ever use sql ...
but i bookmarked it anyway's (so if ever i need to change any sql stuf in a db, im going to read it again for sure)...
+ 1k karma in my book..
but i bookmarked it anyway's (so if ever i need to change any sql stuf in a db, im going to read it again for sure)...
+ 1k karma in my book..
Only.Holoris, real geeks use whatever they like and try to make the most of it. And real tweakers even make it do stuff it wasn't even designed for.
You use what you know, you use what you like. In this case MySQL.
And i Bet that when PostegreSQL started in 1982 it was as feature rich as MySQL at it's start in 1994.
You use what you know, you use what you like. In this case MySQL.
And i Bet that when PostegreSQL started in 1982 it was as feature rich as MySQL at it's start in 1994.
@Only.Holoris so because there were some bugs and features that weren't implemented in the past and because PostegreSQL had them already in the beginning we shouldn't use MySQL now but PostegreSQL?
What is that kind argumenting
_!
What is that kind argumenting