Лучший способ для хранения списка идентификаторов пользователей - PullRequest
4 голосов
/ 07 марта 2009

Я сейчас работаю над рейтинговой системой PHP / MySQL. Чтобы пользователь мог оценивать, он должен войти в систему. Каждый пользователь имеет уникальный «UID». На сайте будет несколько экземпляров рейтинга (по одному для каждой игры, в моем случае), и мне нужен эффективный способ хранения списка UID в строке MySQL (по одной строке MySQL в таблице рейтингов для каждого экземпляра системы рейтинга). ) вести подсчет голосовавших.

В других системах я видел, что список хранится в сериализованном массиве PHP. Каждый раз, когда пользователь голосует, сериализованный массив должен быть извлечен, не сериализован, новый UID вставлен, массив повторно сериализован, и строка MySQL ОБНОВЛЕНА. Каждый раз, когда страница загружается, этот список снова должен быть сериализован и проверен, чтобы проверить, проголосовал ли пользователь, просматривающий страницу, чтобы убедиться, что пользователь не голосовал дважды.

Это кажется неэффективным и громоздким. Есть ли в MySQL встроенная функция списка, чтобы этот процесс был более эффективным? Есть ли еще какие-нибудь умные способы, которыми я мог бы решить эту проблему?

Я рассмотрел одну возможную альтернативу - забыть сериализацию и сохранить UID в поле типа TEXT в базе данных MySQL. Я бы просто добавил некоторые нечисловые символы после каждого UID (скажем, точка [.]). Чтобы добавить запись пользователя, я бы просто конкатенировал UID в конце поля TEXT и затем точку. При проверке, если пользователь уже проголосовал, я мог просто "ВЫБРАТЬ * ИЗ таблицы, ГДЕ голосов ="% $ UID.% '; ". Будет ли это работать более эффективно или есть более элегантный способ выполнения работы?

Последующее сообщение о структуре таблицы ... Эффективная структура таблицы MySQL для рейтинговой системы

Ответы [ 2 ]

17 голосов
/ 07 марта 2009

Это неэффективно. То, что вы имеете здесь в реляционных терминах, это отношения «многие ко многим» между пользователями и играми. Пользователь может голосовать за многие игры. За игру могут голосовать многие пользователи. Решением для этого является наличие таблицы соединений:

USERS (uid, name, ...)
GAMES (gid, name, ...)
VOTES (id, uid, gid, ...)

Где uid и gid - это внешние ключи обратно к соответствующим таблицам.

Если кто-то проголосует, вставьте запись в ГОЛОСА.

Чтобы получить список голосов за игру:

$get = mysql_query("SELECT * FROM votes WHERE gid = $game_id");
...

Чтобы получить список голосов пользователя:

$get = mysql_query("SELECT * FROM votes WHERE uid = $user_id");
...

и т. Д.

Не объединяйте массив и не храните его в одном столбце. Вы правы, избегая этого.

4 голосов
/ 07 марта 2009

В нормализованной базе данных вы должны хранить ее в соединительной таблице:

UserRatings
-------------
RatingID int
UserID int
UserVote int

Я не знаю, каковы ваши запросы. В зависимости от приложения это может не иметь приемлемой производительности. Тем не менее, в любом случае, я предлагаю вам использовать нормализованный подход, тестировать и денормализовать только при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...