MySQL 테이블에 사용자 정의 CHECK 제약 조건을 추가하려면 어떻게 해야 합니까?
이 테이블에 문제가 있습니다.
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))
);
저는 외부 키 제약이 있기를 원하며, 그것이 작동합니다.그런 다음 속성에 제약 조건도 추가하고 싶습니다.status
따라서 'a', 'd' 및 'u' 값만 사용할 수 있습니다.필드를 다음과 같이 설정할 수 없습니다.Enum
또는set
.
누가 이 코드가 MySQL에서 작동하지 않는 이유를 말해줄 수 있습니까?
CHECK
제약 조건이 MySQL에서 지원되지 않습니다.사용자가 정의할 수 있지만 MySQL 5.7 기준으로 이들은 아무것도 하지 않습니다.
설명서에서:
그
CHECK
절은 구문 분석되지만 모든 스토리지 엔진에서 무시됩니다.
해결 방법은 트리거를 만드는 것이지만, 트리거를 사용하는 것이 가장 쉬운 방법은 아닙니다.
를 지원하는 오픈 소스 RDBMS를 원하는 경우CHECK
제약 조건, Postgre 사용해 보십시오.SQL. 사실 아주 좋은 데이터베이스입니다.
왜 여기에 아무도 체크 옵션이 있는 뷰가 MySQL의 체크 제약 조건에 대한 좋은 대안이 될 수 있다고 언급하지 않았는지 이해할 수 없습니다.
CREATE VIEW name_of_view AS SELECT * FROM your_table
WHERE <condition> WITH [LOCAL | CASCADED] CHECK OPTION;
MySQL 사이트에 문서가 있습니다.View WITH 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');
추신: 보기가 업데이트 가능해야 한다는 것을 명심하세요!MySQL Updatable Views(댓글에 대한 설명을 제공하는 Romeo Sierra에게 감사)를 참조하십시오.
트리거 외에도 다음과 같은 간단한 제약 조건이 있습니다.
CONSTRAINT `participants_ibfk_2`
CHECK status IN ('a','d','u')
당신은 사용할 수 있습니다.Foreign Key
부터status
참조 테이블(ParticipantStatus
3개 행 포함:'a','d','u'
):
CONSTRAINT ParticipantStatus_Participant_fk
FOREIGN KEY (status)
REFERENCES ParticipantStatus(status)
버전 8.0.16부터 MySQL은 CHECK 제약 조건에 대한 지원을 추가했습니다.
ALTER TABLE topic
ADD CONSTRAINT post_content_check
CHECK (
CASE
WHEN DTYPE = 'Post'
THEN
CASE
WHEN content IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
ALTER TABLE topic
ADD CONSTRAINT announcement_validUntil_check
CHECK (
CASE
WHEN DTYPE = 'Announcement'
THEN
CASE
WHEN validUntil IS NOT NULL
THEN 1
ELSE 0
END
ELSE 1
END = 1
);
이전에는 다음과 같이 삽입 전 및 업데이트 전 트리거만 사용할 수 있었습니다.
CREATE
TRIGGER post_content_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER post_content_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Post'
THEN
IF NEW.content IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Post content cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_check BEFORE INSERT
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
CREATE
TRIGGER announcement_validUntil_update_check BEFORE UPDATE
ON topic
FOR EACH ROW
BEGIN
IF NEW.DTYPE = 'Announcement'
THEN
IF NEW.validUntil IS NULL
THEN
signal sqlstate '45000'
set message_text = 'Announcement validUntil cannot be NULL';
END IF;
END IF;
END;
원하는 수표를 빠르고 쉽게 받을 수 있는 방법은 다음과 같습니다.
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);
언급URL : https://stackoverflow.com/questions/7522026/how-do-i-add-a-custom-check-constraint-on-a-mysql-table
'programing' 카테고리의 다른 글
Python에서 하위 프로세스, 멀티프로세싱 및 스레드 중에서 결정하시겠습니까? (0) | 2023.08.12 |
---|---|
텍스트 보기 텍스트를 클릭하거나 탭하는 방법 (0) | 2023.08.12 |
MySQL에서 문자열을 숫자로 자동 캐스트/변환하시겠습니까? (0) | 2023.08.12 |
MS Excel에서 공통 집합 연산(결합, 교차, 마이너스)을 수행하려면 어떻게 해야 합니까? (0) | 2023.08.12 |
RegisterStartupScript가 ScriptManager의 Updatepanel에서 작동하지 않습니다.왜 그런 것일까요? (0) | 2023.08.07 |