在下表中:
Country Name | Country Code | isStandardName
----------------------------------------------------------
United States | USA | false
----------------------------------------------------------
United States of America | USA | True
----------------------------------------------------------
Yankees | USA | false
在某些情况下,美国/美国等国家/地区的名称与国家/地区代码(在本例中为美国)不同,但其中一个可以是标准名称。在这种情况下,最简单的解决方案是强制执行一个约束,其中类似的国家/地区代码一次只能在isStandardName部分中使用一个布尔值。
换句话说,如何通过触发器/约束使“CountryCode,'true'”对于一组相等的countryCode名称唯一?
有关如何强制执行此约束的任何建议?
答案 0 :(得分:1)
我建议删除列'isStandardName'。创建表standard_country。在country和country_country之间建立了一种关系。使用左连接创建视图并更改模型以使用新结构。
实施例
CREATE TABLE `country` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`country` varchar(63) DEFAULT NULL,
`code` char(3) DEFAULT NULL COMMENT 'ISO 3166-1 alpha-3',
PRIMARY KEY (`id`),
UNIQUE KEY `country` (`country`,`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `country` (`id`, `country`, `code`)
VALUES
(1,'United States','USA'),
(2,'United States of America','USA'),
(3,'Yankees','USA');
CREATE TABLE `standard_country` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`country_id` int(11) unsigned NOT NULL,
`code` char(3) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`code`),
KEY `country_id` (`country_id`),
CONSTRAINT `standard_country_ibfk_1` FOREIGN KEY (`country_id`) REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `standard_country` (`id`, `country_id`, `code`)
VALUES
(1,2,'USA');
create or replace view countries_view as
select country.id country_id
, country
, country.code
, COALESCE( (standard_country.id > 0) , 0 ) isStandard
from `country`
left join `standard_country`
on country.id = standard_country.country_id
-- example result
select * from countries_view ;
country_id country code isStandard
1 United States USA 0
2 United States of America USA 1
3 Yankees USA 0
答案 1 :(得分:0)
我在保持桌子一样的情况下做到了(就像它一样)。
首先,创建检查规范国家/地区集成的程序
DELIMITER //
CREATE PROCEDURE `db`.`check_canonical_integrity` (IN new_countrycode
VARCHAR(10), IN new_iscanonical tinyint(1))
BEGIN
SELECT sum(iscanonical) into @canonicalsum from `gapminder_db`.`COUNTRY_CODES` WHERE countrycode = new_countrycode;
IF (@canonicalsum + new_iscanonical) > 1 THEN
SET @msg := 'More than one canonical countrycode cannot exit.';
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @msg;
END IF;
END
//DELIMITER ;
其次,我们在插入之前调用上面的内容,你可以在删除时做同样的事情:
DELIMITER &&
CREATE TRIGGER `db`.`check_canonical_flag_insert` BEFORE INSERT ON
`COUNTRY_CODES`
FOR EACH ROW
BEGIN
CALL check_canonical_integrity(New.countrycode, New.iscanonical);
END&&
DELIMITER ;