繁体   English   中英

可以创建多个连接表的路径吗?

[英]Is it ok to create more than one path to join tables?

假设我有一个用户表:

CREATE TABLE `users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `city_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `users_city_id_foreign` (`city_id`),
  CONSTRAINT `users_city_id_foreign` FOREIGN KEY (`city_id`) REFERENCES `cities` (`id`)
);

这链接到一个城市表:

CREATE TABLE `cities` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `country_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `cities_country_id_foreign` (`country_id`),
  CONSTRAINT `cities_country_id_foreign` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`)
);

这与国家表相关联:

CREATE TABLE `countries` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
);

我经常需要用户的国家名称。 我已经可以通过user->city->country访问国家名称:

SELECT `users`.`name`, `countries`.`name`
FROM `users` JOIN 
    (`cities` JOIN `countries` ON `cities`.`country_id` = `countries`.`id`)
    ON `users`.`city_id` = `cities`.`id`;

但我想直接访问,例如:

SELECT `users`.`name`, `countries`.`name`
FROM `users` JOIN `countries` ON `users`.`country_id` = `countries`.`id

可以像这样添加一个将用户表直接链接到国家表的外键,还是应该避免它?

ALTER TABLE `users` 
ADD COLUMN `country_id` BIGINT(20) UNSIGNED NOT NULL AFTER `city_id`,
ADD INDEX `users_country_id_foreign_idx` (`country_id` ASC);

ALTER TABLE `users` 
ADD CONSTRAINT `users_country_id_foreign`
  FOREIGN KEY (`country_id`)
  REFERENCES `countries` (`id`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION;

通过将 country_id 添加到 users 表中,您会产生数据异常的风险。 您如何解释这些数据:

countries:
 1, UK
 2, US

cities:
 1, Little Whinging, 1
 2, New York, 2

users:
 1, Harry Potter, 1, 2

哈利波特怎么可能住在英国的一个城市,却被分配了一个与美国对应的country_id? 如果您将多余的 country_id 存储在 users 表中,则可能会出现这种异常情况。 您可以制作与自身不一致的数据。

您可以通过使用户中的 city_id 和 country_id引用城市表中的 city_id 和 country_id来解决此问题。 至少这可以防止异常,因为它必须引用该表中存在该对值的键(您必须首先在城市中创建一个两列键)。 但它仍然是多余的。

CREATE TABLE `users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `city_id` bigint(20) unsigned NOT NULL,
  `country_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `users_city_country_foreign` FOREIGN KEY (`city_id`, `country_id`)
    REFERENCES `cities` (`id`, `country_id`)
);

问题未解决?试试以下方法:

可以创建多个连接表的路径吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM