【问题标题】:Don't allow reversed composite primary key in MySQL不允许 MySQL 中的反向复合主键
【发布时间】:2013-11-07 13:08:32
【问题描述】:

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

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

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

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

【问题讨论】:

  • 不确定 mysql - 在 Oracle 中,您可能会使用某种基于函数的索引,将值散列在一起..

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


【解决方案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 ;

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

【讨论】:

  • 我认为我应该用 INSERT 代替 SELECT 语句,对吧?
  • @Zahrec 不,您可以保持原样。没关系。插入和选择在这里属于一起。看这里:dev.mysql.com/doc/refman/5.1/en/insert.html 第三种写插入语句的方式。
【解决方案2】:

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

但是,您可能还没有 MariaDB。因此,您将很难实施防止重复条目的业务规则。您当然可以使用系统地忽略禁止条目(其中 town_2

 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))

【讨论】:

    猜你喜欢
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 2013-03-05
    相关资源
    最近更新 更多