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億行があります。

この方法で問題がない場合、最高のパフォーマンスを得るために何を覚えておく必要がありますか?テーブルのインデックスで十分ですか?この方法で問題が発生する可能性がある場合、他にどのような方法を提案しますか?

「すべてのリレーションを異なる行に格納せず、それらを1つのフィールドに保持する」についてどう思いますか?

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

2 に答える 2

0

cityを別の列に保管できれば、はるかに優れています。mysql のような組み込み関数は存在しますfind_in_set()が、別のデータベース サーバーを試すと十分な柔軟性が得られません。また、100 万ではなく数十億の行について話しているのです。したがって、ここではクエリの効率が最も重要です。

于 2012-08-09T00:16:54.160 に答える
0

The important thing is to index both columns in city_relations. Since UserID,CityID is presumably the unique, primary key for the table, you don't need an additional index for UserID (indexes are B-trees, so any prefix of an indexed set of columns is also indexed), but you'll need an index for CityID by itself.

I agree with John that you should keep the cities in separate rows. find_in_set() can't take advantage of the index, so it will have to search every row and perform a complicated string search.

于 2012-08-09T00:31:51.363 に答える