Además de la buena solución de activación de @Rolando, hay otra solución alternativa para este problema en MySQL (hasta CHECKque se implementen las restricciones).
Cómo emular algunas CHECKrestricciones en MySQL
Por lo tanto, si prefiere restricciones de integridad referencial y desea evitar los desencadenantes (debido a los problemas en MySQL cuando tiene ambos en sus tablas), puede usar otra pequeña tabla de referencia:
CREATE TABLE age_allowed
( age TINYINT UNSIGNED NOT NULL
, PRIMARY KEY (age)
) ENGINE = InnoDB ;
Llénalo con 20 filas:
INSERT INTO age_allowed
(age)
VALUES
(0), (1), (2), (3), ..., (19) ;
Entonces tu mesa sería:
CREATE TABLE test
( id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT
, age TINYINT UNSIGNED NOT NULL
, PRIMARY KEY (id)
, CONSTRAINT age_allowed__in__test
FOREIGN KEY (age)
REFERENCES age_allowed (age)
) ENGINE = InnoDB ;
Tendrá que eliminar el acceso de escritura a la age_allowedtabla, para evitar agregar o eliminar accidentalmente filas.
Este truco no funcionará con FLOATcolumnas de tipo de datos, desafortunadamente (demasiados valores entre 0.0y 20.0).
Cómo emular CHECKrestricciones arbitrarias en MySQL (5.7) y MariaDB (desde 5.2 hasta 10.1)
Dado que MariaDB agregó columnas calculadas en su versión 5.2 ( versión GA: 2010-11-10 ) y MySQL en 5.7 (versión GA: 2015-10-21 ), que las llaman VIRTUALy GENERATEDrespectivamente, eso puede ser persistente, es decir, almacenado en el tabla - los llaman PERSISTENTy STOREDrespectivamente - podemos usarlos para simplificar la solución anterior e incluso mejor, extenderla para emular / imponer CHECKrestricciones arbitrarias ):
Como se indicó anteriormente, necesitaremos una tabla de ayuda, pero esta vez con una sola fila que actuará como una tabla "ancla". Aún mejor, esta tabla se puede usar para cualquier cantidad de CHECKrestricciones.
Luego agregamos una columna calculada que evalúa a TRUE/ FALSE/ UNKNOWN, exactamente como lo CHECKharía una restricción, pero esta columna tiene una FOREIGN KEYrestricción en nuestra tabla de anclaje. Si la condición / columna se evalúa FALSEpara algunas filas, las filas se rechazan, debido a la FK.
Si la condición / columna se evalúa como TRUEo UNKNOWN( NULL), las filas no se rechazan, exactamente como debería suceder con CHECKrestricciones:
CREATE TABLE truth
( t BIT NOT NULL,
PRIMARY KEY (t)
) ENGINE = InnoDB ;
-- Put a single row:
INSERT INTO truth (t)
VALUES (TRUE) ;
-- Then your table would be:
-- (notice the change to `FLOAT`, to prove that we don't need)
-- (to restrict the solution to a small type)
CREATE TABLE test
( id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
age FLOAT NOT NULL,
age_is_allowed BIT -- GENERATED ALWAYS
AS (age >= 0 AND age < 20) -- our CHECK constraint
STORED,
PRIMARY KEY (id),
CONSTRAINT check_age_must_be_non_negative_and_less_than_20
FOREIGN KEY (age_is_allowed)
REFERENCES truth (t)
) ENGINE = InnoDB ;
El ejemplo es para la versión MySQL 5.7. En MariaDB (versiones 5.2+ hasta 10.1), solo necesitamos modificar la sintaxis y declarar la columna como en PERSISTENTlugar de STORED. En la versión 10.2 también STOREDse agregó la palabra clave, por lo que el ejemplo anterior funciona en ambos tipos (MySQL y MariaDB) para las últimas versiones.
Si queremos imponer muchas CHECKrestricciones (lo cual es común en muchos diseños), solo tenemos que agregar una columna calculada y una clave foránea para cada una de ellas. Solo necesitamos una truthtabla en la base de datos. Debe tener una fila insertada y luego todo acceso de escritura eliminado.
Sin embargo, en el último MariaDB, ya no tenemos que realizar todas estas acrobacias, ya que las CHECKrestricciones se han implementado en la versión 10.2.1 (versión alfa: 2016-Jul-04).
La versión actual 10.2.2 sigue siendo una versión beta, pero parece que la característica estará disponible en la primera versión estable de la serie MariaDB 10.2.