0

我想存储用户访问过的城市。在个人资料页面中,将列出用户访问过的所有城市。并且会有一个功能,用户可以搜索“谁访问过那个城市”(可以有多个城市搜索)

我打算做一个多对多的关系。

Table Users
-----------
UserID
UserName
...


Table Cities
-------
CityID
CityName
....


Table City_Relations
-----------
UserID
CityID

在个人资料页面中,我可以运行一个简单的查询来获取城市。

select c.cityname FROM city_relations cr left join cities c on ( c.cityid = cr.cityid ) where cr.userid = 'USERID'

并在搜索页面获取访问过所选城市的用户;

select u.username FROM city_relations cr left join users u on ( u.userid = cr.userid ) where cr.cityid = 'CITYID'   ( there may be cr.cityid = '1' or cr.cityid = '2' and so on; or in()/find_in_set()  ) 

到目前为止一切正常。我的问题是这效率如何?假设有 1 亿用户,每个用户在 city_relations 表中可以有数百个城市。假设每个用户有 100 个城市,该表中将有 100 亿行将运行插入/删除和选择 - 连接查询。

如果这种方式可行,我应该记住什么以获得最佳性能?表上的索引就足够了吗?如果这种方式可能会导致问题,您还有什么其他的建议?

您如何看待“不将所有关系存储在不同的行中并将它们保存在一个字段中”?

For example;
-----------
UserID
CityIDS (separated by commas)
4

2 回答 2

0

重要的是索引 city_relations 中的两列。由于 UserID,CityID 可能是表的唯一主键,因此您不需要 UserID 的附加索引(索引是 B 树,因此索引列集的任何前缀也会被索引),但您将需要自己的 CityID 索引。

我同意约翰的观点,你应该将城市分开排列。find_in_set() 不能利用索引,因此它必须搜索每一行并执行复杂的字符串搜索。

于 2012-08-09T00:31:51.363 回答
0

city如果您可以将其存储在不同的行中,那就更好了。虽然 mysql 中存在内置函数,find_in_set()但如果您尝试使用其他数据库服务器,它会不够灵活。而且您说的是数十亿行而不是数百万行。所以查询的效率在这里是最重要的。

于 2012-08-09T00:16:54.160 回答