Come aggiungo un vincolo di controllo a una tabella?

Sto avendo problemi con questo tavolo

CREATE TABLE `Participants` ( `meetid` int(11) NOT NULL, `pid` varchar(15) NOT NULL, `status` char(1) DEFAULT NULL, PRIMARY KEY (`meetid`,`pid`), CONSTRAINT `participants_ibfk_1` FOREIGN KEY (`meetid`) REFERENCES `Meetings` (`meetid`) ON DELETE CASCADE CONSTRAINT `participants_ibfk_2` CHECK (status IN ('a','d','u')) CONSTRAINT `participants_ibfk_3` CHECK (pid IN (SELECT name FROM Rooms) OR pid IN (SELECT userid FROM People)) ); 

Voglio avere un vincolo di chiave esterna, e questo funziona. Quindi voglio aggiungere un vincolo allo status dell’attributo in modo che possa prendere solo i valori ‘a’, ‘d’ e ‘u’. Non è ansible per me impostare il campo come Enum o set .

Qualcuno può dirmi perché questo codice non funziona in MySQL?

CHECK vincoli CHECK non sono supportati da MySQL. Puoi definirli, ma non fanno nulla (a partire da MySQL 5.7).

Dal manuale :

La clausola CHECK viene analizzata ma ignorata da tutti i motori di archiviazione.

La soluzione alternativa è creare trigger , ma non è la cosa più facile con cui lavorare.

Se vuoi un RDBMS open source che supporti i vincoli CHECK , prova PostgreSQL . In realtà è un ottimo database.

Non capisco perché nessuno qui abbia menzionato che VISUALIZZARE CON CHECK OPTION può essere una buona alternativa a CHECK CONSTRAINT in MySQL:

 CREATE VIEW name_of_view AS SELECT * FROM your_table WHERE  WITH [LOCAL | CASCADED] CHECK OPTION; 

C’è un documento sul sito MySQL: la vista con la clausola CHECK OPTION

 DROP TABLE `Participants`; CREATE TABLE `Participants` ( `meetid` int(11) NOT NULL, `pid` varchar(15) NOT NULL, `status` char(1) DEFAULT NULL check (status IN ('a','d','u')), PRIMARY KEY (`meetid`,`pid`) ); -- should work INSERT INTO `Participants` VALUES (1,1,'a'); -- should fail but doesn't because table check is not implemented in MySQL INSERT INTO `Participants` VALUES (2,1,'x'); DROP VIEW vParticipants; CREATE VIEW vParticipants AS SELECT * FROM Participants WHERE status IN ('a','d','u') WITH CHECK OPTION; -- should work INSERT INTO vParticipants VALUES (3,1,'a'); -- will fail because view uses a WITH CHECK OPTION INSERT INTO vParticipants VALUES (4,1,'x'); 

Accanto ai trigger, per semplici vincoli come quello che hai:

 CONSTRAINT `participants_ibfk_2` CHECK status IN ('a','d','u') 

è ansible utilizzare una Foreign Key dallo status a una tabella di riferimento ( ParticipantStatus con 3 righe: 'a','d','u' ):

 CONSTRAINT ParticipantStatus_Participant_fk FOREIGN KEY (status) REFERENCES ParticipantStatus(status) 

Ecco un modo per ottenere i controlli desiderati in modo rapido e semplice:

 drop database if exists gtest; create database if not exists gtest; use gtest; create table users ( user_id integer unsigned not null auto_increment primary key, username varchar(32) not null default '', password varchar(64) not null default '', unique key ix_username (username) ) Engine=InnoDB auto_increment 10001; create table owners ( owner_id integer unsigned not null auto_increment primary key, ownername varchar(32) not null default '', unique key ix_ownername (ownername) ) Engine=InnoDB auto_increment 5001; create table users_and_owners ( id integer unsigned not null primary key, name varchar(32) not null default '', unique key ix_name(name) ) Engine=InnoDB; create table p_status ( a_status char(1) not null primary key ) Engine=InnoDB; create table people ( person_id integer unsigned not null auto_increment primary key, pid integer unsigned not null, name varchar(32) not null default '', status char(1) not null, unique key ix_name (name), foreign key people_ibfk_001 (pid) references users_and_owners(id), foreign key people_ibfk_002 (status) references p_status (a_status) ) Engine=InnoDB; create or replace view vw_users_and_owners as select user_id id, username name from users union select owner_id id, ownername name from owners order by id asc ; create trigger newUser after insert on users for each row replace into users_and_owners select * from vw_users_and_owners; create trigger newOwner after insert on owners for each row replace into users_and_owners select * from vw_users_and_owners; insert into users ( username, password ) values ( 'fred Smith', password('fredSmith')), ( 'jack Sparrow', password('jackSparrow')), ( 'Jim Beam', password('JimBeam')), ( 'Ted Turner', password('TedTurner')) ; insert into owners ( ownername ) values ( 'Tom Jones'),( 'Elvis Presley'),('Wally Lewis'),('Ted Turner'); insert into people (pid, name, status) values ( 5001, 'Tom Jones', 1),(10002,'jack Sparrow',1),(5002,'Elvis Presley',1);