Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何向mysql数据库添加许多约束_Mysql_Sql - Fatal编程技术网

如何向mysql数据库添加许多约束

如何向mysql数据库添加许多约束,mysql,sql,Mysql,Sql,我正在尝试建立一个MySQL数据库。最终数据库将由分布在7个表上的约200列组成。现在我遇到了一个问题,我想向大多数列添加检查约束。某些列只有一个约束,其他列有许多约束和/或受不同表的列的影响 例如,如果年龄大于20岁,或者邮政编码由5个字符组成且以1开头,或者如果入院日期(表内入院)早于出院日期(表内出院),则只能将行添加到表中。 只有三个例子。我能想到1000多个,这是我的问题 我想以更结构化的方式添加这些约束。具有10个以上约束的触发器将非常复杂,除了作者之外,没有人能够重建所有约束。但是

我正在尝试建立一个MySQL数据库。最终数据库将由分布在7个表上的约200列组成。现在我遇到了一个问题,我想向大多数列添加检查约束。某些列只有一个约束,其他列有许多约束和/或受不同表的列的影响

例如,如果年龄大于20岁,或者邮政编码由5个字符组成且以1开头,或者如果入院日期(表内入院)早于出院日期(表内出院),则只能将行添加到表中。 只有三个例子。我能想到1000多个,这是我的问题

我想以更结构化的方式添加这些约束。具有10个以上约束的触发器将非常复杂,除了作者之外,没有人能够重建所有约束。但是,如果数据库将被使用多年,许多管理员将不得不使用数据库,并可能添加新的或删除不必要的约束

DELIMITER $$
CREATE TRIGGER `test``_before_insert` BEFORE INSERT ON `zip`
FOR EACH ROW

BEGIN
    IF NEW.zip_id < 5 THEN
        SIGNAL SQLSTATE '12345'
        SET MESSAGE_TEXT = 'check constraint 1';
    END IF;

    IF NEW.zip_id = 5 THEN
        SIGNAL SQLSTATE '12345'
        SET MESSAGE_TEXT = 'check constraint 2';
    END IF;
END $$

DELIMITER ;
分隔符$$
在zip上插入之前在插入之前创建触发器'test```
每行
开始
如果NEW.zip_id<5,则
信号状态“12345”
设置消息_TEXT='检查约束1';
如果结束;
如果NEW.zip_id=5,则
信号状态“12345”
设置消息_TEXT='检查约束2';
如果结束;
结束$$
定界符;
这就是我不想处理这个问题的方式


我的问题是,是否有一种方法可以以正常的人类可读的方式声明约束(例如,每个文本文件有一个好名字的约束)并将其添加到数据库中。

不幸的是,MySQL中的check约束不起作用。您可以在这里了解更多信息。即使是这个问题的公认答案也建议使用触发器

DROP TRIGGER IF EXISTS test_before_insert;
DROP PROCEDURE IF EXISTS `procedureLess5`;
DROP PROCEDURE IF EXISTS `procedureEquals5`;

DELIMITER $$

CREATE PROCEDURE `procedureLess5` (IN myInput INT)
BEGIN
    IF myInput < 5 THEN
        SIGNAL SQLSTATE '12345'
        SET MESSAGE_TEXT = 'check constraint 1';
    END IF;
END $$

CREATE PROCEDURE `procedureEquals5` (IN myInput INT)
BEGIN
    IF myInput = 5 THEN
        SIGNAL SQLSTATE '12345'
        SET MESSAGE_TEXT = 'check constraint 2';
    END IF;
END $$

CREATE TRIGGER `test_before_insert` BEFORE INSERT ON `zip`
FOR EACH ROW
BEGIN
    CALL procedureLess5(NEW.zip_id);
    CALL procedureEquals5(NEW.zip_id);
END $$

DELIMITER ; 
当您决定使用触发器时,您的思路是正确的。然而,你有一些误解

触发器基本上是在表上的事件上定义的。由于有7个表,每个表至少有7个单独的触发器。阅读更多关于MySQL中触发器的信息


只有你自己才能找到方法使代码组织良好,这样你的队友甚至你都能很好地理解它。您需要做的一切就是遵循整个软件行业遵循的最佳实践。有关一些提示,您可以在dba.stackexchange.com上查阅和。

我已经仔细考虑了我的问题,并且有另一个关于检查触发器中约束的参数和解决方案。 首先是论点:我可能至少需要一个BEFORE INSERT和BEFORE UPDATE触发器来检查我的数据。两个触发器或多或少是相同的。如果约束随时间变化,我必须将更改提交给两个触发器,否则我的数据可能不一致。 我想到了实现一个约束的存储过程,可以在INSERT和UPDATE触发器中调用该约束。现在如果我改变一个过程,它会影响两个触发器

DROP TRIGGER IF EXISTS test_before_insert;
DROP PROCEDURE IF EXISTS `procedureLess5`;
DROP PROCEDURE IF EXISTS `procedureEquals5`;

DELIMITER $$

CREATE PROCEDURE `procedureLess5` (IN myInput INT)
BEGIN
    IF myInput < 5 THEN
        SIGNAL SQLSTATE '12345'
        SET MESSAGE_TEXT = 'check constraint 1';
    END IF;
END $$

CREATE PROCEDURE `procedureEquals5` (IN myInput INT)
BEGIN
    IF myInput = 5 THEN
        SIGNAL SQLSTATE '12345'
        SET MESSAGE_TEXT = 'check constraint 2';
    END IF;
END $$

CREATE TRIGGER `test_before_insert` BEFORE INSERT ON `zip`
FOR EACH ROW
BEGIN
    CALL procedureLess5(NEW.zip_id);
    CALL procedureEquals5(NEW.zip_id);
END $$

DELIMITER ; 
如果存在触发器,则在插入前测试\u;
删除过程(如果存在)`procedureLess5`;
删除过程(如果存在)`procedureEquals5`;
分隔符$$
创建过程“ProcedureReless5”(在myInput INT中)
开始
如果myInput<5,则
信号状态“12345”
设置消息_TEXT='检查约束1';
如果结束;
结束$$
创建过程“procedureEquals5”(在myInput INT中)
开始
如果myInput=5,则
信号状态“12345”
设置消息_TEXT='检查约束2';
如果结束;
结束$$
在zip上插入前创建触发器“插入前测试”`
每行
开始
调用过程reless5(新的.zip\u id);
调用过程equals5(新的.zip\u id);
结束$$
定界符;
这是一个机会吗? 如果我有20多个被调用的过程,那么数据库的性能如何


还是你想另一种方式?我不习惯MySQL,PostgreSQL也是一个机会。在PostgreSQL中使用检查约束是否更好/更快/更标准?

谢谢您的回复。我同意良好的文档和组织良好的代码在团队项目中是最重要的。在我的例子中,我想保证输入数据的质量,比如说,不必输入20岁以下的人的数据集。现在,一种方法当然是创建一些标准操作程序,并告诉用户在输入数据之前进行检查。但除此之外,我想在应用程序和/或数据库级别添加这些检查。如何确保项目中的数据质量?当您决定使用触发器强制执行检查约束时,您做了正确的事情。现在只需要管理触发器中的代码。我找不到其他的选择。