MySQL allows you to work with both transactional tables that allow rollback and non-transactional tables that do not, so constraint handling is a bit different in MySQL than in other databases.
We have to handle the case when you have updated a lot of rows in a non-transactional table that cannot roll back when an error occurs.
The basic philosophy is to try to give an error for anything that we can detect at compile time but try to recover from any errors we get at runtime. We do this in most cases, but not yet for all. See TODO future.
The options MySQL has when an error occurs are to stop the statement in the middle or to recover as well as possible from the problem and continue.
The following sections describe what happens for the different types of constraints.
Normally you will get an error when you try to INSERT or UPDATE a row that causes a primary key, unique key or foreign key violation. If you are using a transactional storage engine such as InnoDB, MySQL will automatically roll back the transaction. If you are using a non-transactional storage engine, MySQL will stop at the incorrect row and leave any remaining rows unprocessed.
To make life easier, MySQL supports an IGNORE keyword for most commands that can cause a key violation (such as INSERT IGNORE and UPDATE IGNORE). In this case, MySQL will ignore any key violation and continue with processing the next row. You can get information about what MySQL did with the mysql_info() API function. See mysql_info(). In MySQL 4.1 and up, you also can use the SHOW WARNINGS statement. See SHOW WARNINGS.
Note that for the moment only InnoDB tables support foreign keys. See InnoDB foreign key constraints. Foreign key support in MyISAM tables is scheduled for implementation in MySQL 5.1.
To be able to support easy handling of non-transactional tables all columns in MySQL have default values.
If you insert an ``incorrect'' value in a column, such as a NULL in a NOT NULL column or a too-large numerical value in a numerical column, MySQL sets the column to the ``best possible value'' instead of producing an error. For numerical values, this is either 0, the smallest possible value or the largest possible value. For strings, this is either the empty string or the longest possible string that can be in the column.
This means that if you try to store NULL into a column that doesn't take NULL values, MySQL Server instead stores 0 or '' (the empty string). This last behavior can, for single row inserts, be changed with the -DDONT_USE_DEFAULT_FIELDS compile option.) See configure options. This causes INSERT statements to generate an error unless you explicitly specify values for all columns that require a non-NULL value.
The reason for the preceding rules is that we can't check these conditions until the query has begun executing. We can't just roll back if we encounter a problem after updating a few rows, because the table type may not support rollback. The option of terminating the statement is not that good; in this case, the update would be ``half done,'' which is probably the worst possible scenario. In this case it's better to ``do the best you can'' and then continue as if nothing happened.
This means that you should generally not use MySQL to check column content. Instead, the application should ensure that is passes only legal values to MySQL.
In MySQL 5.0, we plan to improve this by providing warnings when automatic column conversions occur, plus an option to let you roll back statements that attempt to perform a disallowed column value assignment, as long as the statement uses only transactional tables.
In MySQL 4.x, ENUM is not a real constraint, but is a more efficient way to define columns that can only contain a given set of values. This is because of the same reasons NOT NULL is not honored. See constraint NOT NULL.
If you insert an incorrect value into an ENUM column, it will be set to the reserved enumeration value 0, which will be displayed as an empty string in string context. See ENUM.
If you insert an incorrect value into a SET column, the incorrect value is ignored. For example, if the column can contain the values 'a', 'b', and 'c', an attempt to assign 'a,x,b,y' results in a value of 'a,b'. See SET.