[英]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.