在两个不直接相关的表之间查询数据的最佳方法是什么,但通过第三个甚至第四个表,使用外键相关?
类似的东西1 -> 2 -> 3 -> 4
。
我看到了许多非常不同的建议,但想找出在这种情况下最好的方法是什么,我尝试维护关系数据库模型,同时避免超级复杂的 SQL 查询。
这是与我的情况相匹配的示例:
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`city_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_city_id` FOREIGN KEY (`city_id`)
REFERENCES `city` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
CREATE TABLE `city` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`country_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_country_id` FOREIGN KEY (`country_id`)
REFERENCES `country` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
CREATE TABLE `country` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`continent_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_continent_id` FOREIGN KEY (`continent_id`)
REFERENCES `continent` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
CREATE TABLE `continent` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
假设我想从特定大陆获取所有用户
SELECT name FROM user WHERE city_id IN (
SELECT id FROM city WHERE country_id IN (
SELECT id FROM country WHERE continent_id = 1 ) ) );
我猜它看起来不错,但是如果我想从特定城市获取所有用户怎么办
SELECT name FROM user WHERE city_id IN (
SELECT id FROM city WHERE country_id IN (
SELECT id FROM country WHERE continent_id = (
SELECT continent_id FROM country WHERE id = (
SELECT country_id FROM city WHERE id = 1 ) ) ) );
这有效率吗?
也许用 JOIN 也能达到同样的效果?
我试图避免将所有值添加到用户表中,以维护该关系city->country->continent
并涉及关系来完成这项工作,但也许在这种情况下它只是不值得这样做?..可能效率不高,重新设计数据库会更好吗?