不要在MySQL中允许反向复合主键

时间:2013-11-07 13:08:33

标签: mysql sql primary-key composite-primary-key

我正在开发一个需要保存两个城市之间距离数据的应用程序。

我在Mysql数据库中创建了一个距离表,它包含两个城市的名称以及它们之间的距离。我已将两个城镇列作为复合主键。

我希望数据库限制应用程序制作重复的反向条目,如屏幕截图所示,以防止有不同的距离值。

解决此问题的最佳解决方案是什么?

Screenshot of distance table with reversed city entries, which shouldn't be possible

2 个答案:

答案 0 :(得分:1)

您可以创建一个存储过程以插入此表。

DELIMITER $$
CREATE PROCEDURE insert_distance(IN p_town1 varchar(50), IN p_town2 varchar(50), IN p_distance int)
BEGIN
INSERT INTO distance(town1, town2, distance)
SELECT LEAST(p_town1, p_town2), GREATEST(p_town1, p_town2), p_distance;
END $$
DELIMITER ;

仅使用此过程插入,确保在条目已存在时抛出错误。而且你不会意外地以错误的顺序插入城镇。

答案 1 :(得分:0)

MariaDB,一个MySQL分支,提供虚拟列。如果您使用的是MariaDB,则可以创建这样一个虚拟列并将其声明为唯一。

但是,你可能还没有MariaDB(还)。因此,您很难实现防止重复条目的业务规则。你当然可以使用一个系统地忽略禁止条目的查找方案(其中town_2< town_1)。

 SELECT town_1, town_2, distance
   FROM distance
  WHERE town_2 > town_1

将检索所有有效条目。此查询将检索作为查询参数提供的两个城镇之间的距离,即使两个城镇名称以错误的顺序提供。 (带有JOIN的猴子业务允许每个城镇名称参数仅向查询呈现一次,即使它被多次使用。)

SELECT town_1, town_2, d.distance
  FROM (
    SELECT ? AS a, ? AS b
  ) cities
  JOIN distance AS d ON
       ( town_1 = LEAST(a,b) AND town_2 = GREATEST(a,b))