My stream of consciousness being a programmer.

Wednesday, May 9, 2012

No CHECK Constraint in MYSQL



It looks like MYSQL doesn’t really validate for check constraint. I checked for mysql manual and noticed its true.

Copied the following section from MySQL manual. (http://dev.mysql.com/doc/refman/5.5/en/alter-table.html)

The CHECK clause is parsed but ignored by all storage engines. See Section 13.1.17, “CREATE TABLE Syntax”. The reason for accepting but ignoring syntax clauses is for compatibility, to make it easier to port code from other SQL servers, and to run applications that create tables with references. See Section 1.8.5, “MySQL Differences from Standard

How I came to know this bad behavior of mysql is, I just created a simple table such as below and After creating I assumed the column gender_code would not accept any values other than ‘m’ or ‘f’. but unfortunately it did which pushed me in a dilemma. The bad scene is it didn’t even throw me an error.

 CREATE TABLE USER (  
 id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,  
 name VARCHAR( 128 ) NOT NULL,  
 gender_code CHAR(1) NOT NULL,  
 CONSTRAINT chk_gender CHECK (gender_code = 'm' OR gender_code = 'f')  
 );  

Hence, in order to have a check constraint in mysql database I found three alternative ways.

Solution 1

Define the data type of column gender_code  as ENUM.

 ‘gender_code’ ENUM(‘m’, ‘f’) NOT NULL  

Only disadvantage i noticed in this way, when inserting any other values (not ‘m’or  ‘f’) it accepts an empty string.

Solution 2

Create a trigger to check for gender_code ‘m’ or  ‘f’ else throw an error.

 DROP TRIGGER IF EXISTS chk_gender;   
 delimiter $$  
  CREATE TRIGGER chk_gender BEFORE INSERT ON `user`   
 FOR EACH ROW  
 BEGIN  
 DECLARE msg varchar(255);  
 IF (NEW.gender <> 'm' AND NEW.gender<>'f')  
 THEN  
 SET msg = concat('Constraint chk_gender violated: gender must not contain invalid value ', cast(new.gender as char));  
 SIGNAL sqlstate '45000' SET message_text = msg;  
 END IF;  
 END$$  
 delimiter ;  

 feel this is the best way to go.

Solution 3

To create a lookup table to contain gender code (‘m’ & ‘f’) and  define current table’s gender_code as foreign key to refer lookup table.

 CREATE TABLE gender_codes  
 ( code CHAR(1) NOT NULL  
 , PRIMARY KEY (code)  
 ) ENGINE = InnoDB ;  
 INSERT INTO gender_codes (code) VALUES  (‘m’), (‘f’) ;  

And then,  original table should look like.

 CREATE TABLE user (  
 id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,  
 name VARCHAR( 128 ) NOT NULL,  
 gender_code CHAR(1) NOT NULL,  
 CONSTRAINT fk_gender FOREIGN KEY (gender_code) REFERENCES gender_codes (gender_code)  
 );  

Hope these workarounds saves someone’s time.

09 May 2012

Related Posts:

  • PHP Incrementing & Decrementing Operators What is the meaning of ++ increment operator and - – decrement operator and how can we use it ? Below is a small explanation on what it does, ++… Read More
  • CRUD application with Yii framework. Please note that, this is a very minimal sample application done for a USER model using yii framework. How to run, 1 – Please download the attach… Read More
  • NIC me, another andorid app Happy to announce my android application which i have named as Nic Me (nik me).. A basic app which will give you the birth day and some other informa… Read More
  • MYSQL Table locking his topic can be new to some but its very much important when working with concurrent access to a particular table row (record). for example lets s… Read More
  • PHP has no FINALLY I am so curious why PHP doesn’t have FINALLY block along with normal TRY CATCH blocks. It’s very much necessary and will let us stay away from code … Read More

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.