我有一个复杂的问题,但没有进入以下内容的细节。
可以说,我们正在尝试构建一个系统,在该系统中,系统的用户可以在每个邮政编码的基础上申请各种服务上的优先级级别。该系统将有四个桌...
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个zip编码,几百个服务和几千用户,并且没有用户可以在同一邮政编码中具有相同服务的其他用户相同的优先级。p>我需要一个查询,如果给出了特定的邮政编码,半径,服务和用户_ID将返回该服务中该半径内所有其他邮政编码的最高优先级级别。
,也想知道重组此数据的任何建议。
我在这里看到的问题是随着用户群的增长,Service_priority表将变得巨大,从理论上讲,每个用户更大45000行,尽管实际上可能只有10000行更大。
我该怎么办来减轻这些问题?
切换到innodb。
zip_code
表可能具有PRIMARY KEY(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
注意:
- 上面的索引也针对此查询量身定制。
- 最内向的查询获得了中心点的一个lng。
- 中间查询重点是查找附近的拉链。请参阅我添加的标签以找到许多问题讨论如何做到这一点。
- 外部查询然后根据用户和服务过滤结果。
- 最后,选择了最高优先级行。