Лучший способ хранения списка идентификаторов пользователей

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

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

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

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

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

Ответ 1

Это неэффективно. То, что у вас здесь есть в отношениях, - это взаимоотношения "многие-ко-многим" между пользователями и играми. Пользователь может голосовать во многих играх. Многие пользователи могут проголосовать за игру. Для этого нужно иметь таблицу соединений:

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

Если uid и gid являются внешними ключами обратно к их соответствующим таблицам.

Если кто-то голосует, вставьте запись в VOTES.

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

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

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

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

и т.д.

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

Ответ 2

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

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

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