Сейчас я работаю над рейтинговой системой PHP / MySQL. Для того, чтобы пользователь мог оценивать пользователя, он должен войти в систему. Каждый пользователь имеет уникальный «UID». На веб-сайте будет несколько рейтинговых экземпляров (по одному для каждой игры, в моем случае), и мне нужен эффективный способ хранения списка UID в строке MySQL (одна строка MySQL в таблице оценок для каждого экземпляра рейтинговой системы ), чтобы сохранить счет того, кто голосовал.
Я видел в других системах, что список хранится в сериализованном массиве PHP. Каждый раз, когда пользователь голосует, сериализованный массив должен быть извлечен, неэтериализован, добавлен новый UID, массив повторно сериализуется, а строка MySQL – UPDATEd. Каждый раз, когда страница загружается, этот список снова должен быть неэтериализован и проверен, чтобы проверить, не проголосовал ли пользователь, просматривающий страницу, чтобы убедиться, что пользователь не проголосовал дважды.
Это кажется неэффективным и громоздким. У MySQL есть встроенная функция списка, чтобы помочь этому процессу быть более эффективным? Есть ли еще более умные способы решить эту проблему?
Я рассмотрел одну из возможных альтернатив, которая забудет сериализацию и сохранение UID в поле типа TEXT в базе данных MySQL. Я бы просто добавил некоторый нечисловой символ после каждого UID (скажем, период [.]). Чтобы добавить пользовательскую запись, я бы просто конкатенировал UID в конце поля TEXT, а затем в период. Когда вы проверяете, проголосовал ли пользователь, я мог бы просто «ВЫБЕРИТЬ * ОТ таблицы WHERE vote = '% $ UID.%';". Будет ли это работать более эффективно или есть более элегантный способ выполнения работы?
Последующая публикация о структуре таблицы … Эффективная структура таблицы MySQL для рейтинговой системы
Это неэффективно. То, что у вас здесь есть в отношениях, – это взаимоотношения «многие-ко-многим» между пользователями и играми. Пользователь может голосовать во многих играх. Многие пользователи могут проголосовать за игру. Для этого нужно иметь таблицу соединений:
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"); ...
и так далее.
Не присоединяйтесь к массиву и сохраняйте его в одном столбце. Вы правы, чтобы этого избежать.
В нормализованной базе данных вы должны хранить ее в таблице соединений:
UserRatings ------------- RatingID int UserID int UserVote int
Я не знаю, каковы ваши запросы. В зависимости от приложения это может не иметь приемлемой производительности. Тем не менее, в любом случае, я предлагаю вам пойти с нормализованным подходом, ориентироваться и денормализовать только в случае необходимости.