根本不存儲點。只需對此視圖進行查詢即可。這樣一來,面對任意改變,它就會很健壯。
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
編輯補充:
這遵循了正常的數據庫設計原則。所有數據庫規範化都可以歸結爲:不重複數據。
包含點表基本上只是重複其餘數據庫已包含的信息。因此,應該省略。考慮到維護數據一致性所必須達到的長度,這一點已經很清楚。不用擔心這些問題,如果推薦是歸功於Alice,但是後來確定Bob應該獲得這筆貸款,則需要更改單個表格中單個行中的單個字段。如果包含點表,那麼它也必須以某種方式更新。如果積分總結被存儲,那麼上帝可能會憐憫你的數據庫。
而不是存儲點,可以使用視圖或存儲過程來代替,然後當數據更改時自動調整點系統。
在這種情況下,我認爲視圖對於存儲過程是可以推出的,因爲有很多方法可能需要分析點數據,並且這提供了最大的靈活性,並且它爲優化器提供了最佳機會確定最佳路徑。
您可以從視圖中選擇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
謝謝傑弗裏 - 我沒有想到這種方法 – Gublooo 2010-02-22 17:08:20
@Jeffrey,非常有趣的方法確實。看到這是一個非常古老的線程。只是好奇,這種方法在一個系統中能夠很好地擴展,比如像SO一樣大?這個視圖可能非常複雜,數據集可能非常大。 – 2016-03-09 16:19:22