【发布时间】:2013-10-11 20:52:00
【问题描述】:
在两个不直接相关的表之间查询数据的最佳方法是什么,但通过第三个甚至第四个表,使用外键相关?
类似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 并涉及关系来完成这项工作,但也许在这种情况下它只是不值得这样做? ..可能效率不高,最好重新设计数据库?
【问题讨论】:
-
IN 语句不好......当索引到位时,JOIN 更好......
-
可以将您的表格和示例数据放在 SQLfriddle 上吗? sqlfiddle.com 那我给你看一些 JOIN 例子
-
这里 sqlfiddle.com/#!2/1c40e/1 是 SQLFiddle.com 上的工作示例,感谢分享链接
标签: mysql sql database-design relational-database