Don';MySQL中不允许反向复合主键

Don';MySQL中不允许反向复合主键,mysql,sql,primary-key,composite-primary-key,Mysql,Sql,Primary Key,Composite Primary Key,我正在开发一个需要保存两个城市之间距离数据的应用程序 我在Mysql数据库中创建了一个距离表,其中保存了这两个城市的名称以及它们之间的距离。我已将两个town列作为复合主键 我希望数据库能够限制应用程序生成重复的反向条目,如屏幕截图所示,以防止出现不同的距离值 解决这个问题的最好办法是什么 MySQL分支MariaDB提供虚拟列。如果您使用的是MariaDB,那么可以创建这样一个虚拟列并声明它是唯一的 但是,您可能还没有MariaDB。因此,您很难实现防止重复条目的业务规则。您当然可以使用一个查

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

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

我希望数据库能够限制应用程序生成重复的反向条目,如屏幕截图所示,以防止出现不同的距离值

解决这个问题的最好办法是什么


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

但是,您可能还没有MariaDB。因此,您很难实现防止重复条目的业务规则。您当然可以使用一个查找方案,系统地忽略禁止的条目(其中town_2 将检索所有有效条目。此查询将检索作为查询参数提供的两个城镇之间的距离,即使两个城镇名称的顺序不正确。(带有连接的monkey business允许每个town name参数仅向查询显示一次,即使它被多次使用。)


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

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 ;

仅使用此过程插入,可以确保在条目已存在时引发错误。而且您不会意外地以错误的顺序插入towns。

不确定mysql-在Oracle中,您可能会使用某种基于函数的索引将值散列在一起。我认为我应该用insert替换SELECT语句,对吗?@Zahrec No,您可以保持原样。没关系。插入和选择属于这里。请参见此处:编写insert语句的第三种方法。
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))
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 ;