我正在尝试建立一个MySQL数据库。最终数据库将包含约。分为7个表的200列。现在我遇到了一个问题,我想在大多数列中添加检查约束。有些列只有一个约束,其他列有很多和/或受不同表的列影响。
E.g。如果年龄超过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 ;
这就是我不想处理问题的方式。
我的问题是,如果有一种方法以正常的人类可读方式声明约束(例如,每个文本文件有一个好名称的约束)并将这些约束添加到数据库中。
答案 0 :(得分:0)
不幸的是,MySQL中的检查约束不起作用。您可以通过此 SO question 了解详情。即使是这个问题的公认答案也建议使用触发器。
当您决定使用触发器时,您处于正确的轨道上。但是你有一些误解。
触发器基本上是在表上的事件上定义的。由于你有7个表,每个表至少有7个独立的触发器。在MySQL Reference Manual了解有关MySQL中触发器的更多信息。
只有你和你才能找到保持代码组织良好的方法,这样你的队友甚至你都能很好地理解它。您需要做的就是遵循软件行业遵循的最佳实践。有关提示,您可以在dba.stackexchange.com上提及here和here。
答案 1 :(得分:0)
我已经考虑过我的问题,并且有关于检查触发器中约束的另一个论点和解决方案。 首先,参数:我可能至少需要一个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 ;
这是一个机会吗? 如果我有超过20个被调用的程序,我的数据库的性能如何?
或者您是否想到另一种方式?我不是修复MySQL,PostgreSQL也是一个机会。在PostgreSQL中使用CHECK CONSTRAINS更好/更快/更标准吗?