2010-02-22 2 views
3

Просто найдите некоторые предложения о том, как подойти к дизайну базы данных для этого.Дизайн базы данных - подход для хранения баллов для пользователей

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

Итак, сегодня - пользователь получает очки 1) Когда он добавляет новый магазин он получает 10 баллов (магазин информация хранится в запасниках таблице) 2) Когда он отвечает на вопрос, он получает 7 баллов (вопросы/ответы хранится в таблице ОТВЕТЫ) 3) Когда он называет друзей, которые присоединяются к сайту он получает 5 баллов

так это то, что я до сих пор - но он не выглядит правильно :)

Points_Table point_id user_id action (Это будет фиксировать, для какого действия даются очки) баллов

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

Спасибо за ваши советы

ответ

2

Не храните баллы вообще. Просто делайте запросы на этом представлении. Таким образом, он будет устойчивым перед лицом произвольных изменений.

create view UserPoints 
as 
select 
    created_by_id as user_id, 
    'STORE' as action_type, 
    store_id as action_id, 
    (select points from action_points where action_desc='create store') as points 
from store 
union 
select 
    user_id, 
    'ANSWER' as action_type, 
    question_id as action_id, 
    (select points from action_points where action_desc='answer question') as points 
from answer 
union 
select 
    referred_by_id as user_id, 
    'REFERRAL' as action_type, 
    referred_id as action_id, 
    (select points from action_points where action_desc='referral') as points 
from referral 

Edited добавить:

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

Включение таблицы точек в основном просто повторяет информацию, содержащуюся в остальной базе данных. Поэтому его следует опустить. Это становится ясным при рассмотрении длин, к которым нужно идти, чтобы поддерживать согласованность данных. Не беспокоясь о точках, если реферал приписывается Алисе, но позже выясняется, что Боб должен получить кредит, для этого потребуется изменение одного поля в одной строке одной таблицы. Если таблица точек включена, то она также должна быть каким-то образом обновлена. Если данные о точках сохраняются, тогда Бог может помиловать вашу базу данных.

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

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

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

select 
    sum(up.points) as total_points, 
    up.user_id, 
    u.user_name 
from 
    UserPoints up 
    join user u on up.user_id = u.user_id 
group by 
    user_id, 
    user_name 
order by 
    total_points desc 
+0

Спасибо Jeffrey - я вообще не думал об этом подходе – Gublooo

+0

@Jeffrey, очень интересный подход в самом деле. Смотрите, что это очень старая нить. Любопытно, действительно ли этот подход хорошо масштабируется в системе, скажем, такой же большой, как SO? Это представление может быть довольно сложным, и набор данных может быть довольно большим. –

0

Если вы хотите, чтобы иметь возможность проследить действие обратно в ряд в магазине или ответы таблице, добавить столбец, который является записью рк для строки добавили, что действия ,

+0

Здравствуйте Андрей, - я не совсем понимаю, что вы сказали - Если я хочу, чтобы связать эти точки фактического магазина, созданного или друзей называют - затем добавить один столбец этой таблицы будет недостаточно - я должен был бы для добавления 3 столбцов right - store_id, refer_id и answer_id, которые являются соответствующими pk этих таблиц. Но это не будет хорошим дизайном? – Gublooo

+0

Вам нужно добавить один столбец для целевой таблицы pk и другой столбец, который идентифицирует целевую таблицу. – Kangkan

+0

OFCOURSE - Я думаю, что не думаю прямо - большое спасибо – Gublooo

2

Добавить таблицу, в которой хранятся действия (общие операции перечисления таблиц, указывающие на фактическое действие в другой таблице), для которых пользователь получает баллы. Таблица может быть чем-то вроде Reward_Actions (ActionId, ActionType, заработанные очки) и т. Д., И вы можете добавить к этому различные виды полезных действий.

+0

Спасибо, что имеет смысл – Gublooo

1

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

+0

Спасибо ryan - оцените вашу помощь – Gublooo

Смежные вопросы