我有一个复杂的问题,但我没有详细说明我将其简化为以下内容。
假设我们正在尝试构建一个系统,系统用户可以在每个邮政编码的基础上申请各种服务的优先级。这个系统有四个这样的表......
CREATE TABLE `zip_code` (
`zip` varchar(7) NOT NULL DEFAULT '',
`lat` float NOT NULL DEFAULT '0',
`long` float NOT NULL DEFAULT '0'
PRIMARY KEY (`zip`,`lat`,`long`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `user` (
`user_id` int(10) NOT NULL AUTO_INCREMENT
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `service` (
`service_id` int(10) NOT NULL AUTO_INCREMENT
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `service_priority` (
`user_id` int(10) NOT NULL',
`service_id` int(10) NOT NULL',
`zip` varchar(7) NOT NULL,
`priority` tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
现在还要说我们有45000个邮政编码,几百个服务和几千个用户,并且没有用户可以在同一个邮政编码中为同一服务的其他用户提供相同的优先级。
我需要一个查询,如果给定特定的邮政编码,radius,service和user_id将返回该服务该半径内所有其他邮政编码的最高可用优先级。
而且,也想知道重组这些数据的任何建议。
我在这里看到的问题是随着用户群的增长,service_priority表将变得庞大,理论上每个用户大45000行,尽管在实践中可能只有10000行更大。
我可以做些什么来缓解这些问题?
答案 0 :(得分:1)
切换到InnoDB。
zip_code
表可能应该有PRIMARY KEY(zip)
,除非您确实需要给定zip的多行。
"在同一邮政编码中,没有用户可以拥有与同一服务的另一个用户相同的优先级" - 可以通过
强制执行service_priority : UNIQUE(service_id, user_id, zip)
然后您的查询可能类似于
SELECT sp.*
FROM ( SELECT b.zip
FROM ( SELECT lat, lng FROM zip_code WHERE zip = '$zip' ) AS a
JOIN zip_code AS b
WHERE ... < $radius
) AS z
JOIN service_priority AS sp
WHERE sp.zip = z.zip
AND sp.user_id = $user_id
AND sp.service_id = $service_id
ORDER BY sp.priority DESC
LIMIT 1
注意: