2011-11-29 114 views
2

前段時間,我意識到我想通過CSV格式來保持玩家在遊戲中的技能。在玩家的統計資料中,我製作了一個可以存儲爲CSV的技能。 (1,6,9,10等)我爲每個技能(姓名,效果)制定了一個「技能」表,並且當需要查看他們擁有的技能時,我所要做的就是查詢單個技能列並使用PHP的str_getcsv()來查看某個技能是否存在,因爲它將在數組中。但是,我的同事建議,一個優秀的系統是讓每個技能只是進入一個每個玩家將使用的主技能表,並且每個技能都有一個ID外鍵給玩家。我只是查詢這個表中的所有行,返回的將是他們的技能!數據庫列中的CSV - 不是一個好主意嗎?

起初我以爲這不會很好,但似乎互聯網不同意。我知道這種搜索不太容易 - 但我並不打算說,「玩家是否擁有X技能?」或者「用這個技能向我展示所有玩家!」。 最壞的情況下如果我想要這樣的數據,我只會爲它做一個PHP報告,但是,無可否認,這將是緩慢的。

但它看起來好像這是真的更快?!我很難找到一個超越「是的,這是好的,正常化」的硬答案。堆棧溢出可以幫助我嗎?

編輯:謝謝,夥計們!我從來沒有意識到這是多麼糟糕。對於這個騙局我很遺憾,但請相信我,我沒有至少沒有檢查過這些騙局就沒有輸入所有這些。 :P

回答

4

將逗號分隔的值放入數據庫中的單個字段不僅僅是一個壞主意,它是數據庫模型中表達的撒旦的化身。

它不能準確表示很多情況(值包含逗號或其他值的情況,您的CSV消費代碼遇到問題),常常存在嵌套在其他值中的值問題,無法正確編制索引,不能在數據庫JOIN中使用,難以重複數據刪除,不能添加額外的信息(獲得技能的次數,在你的情況下,或技能水平),不能參與關係完整性,不能強制執行類型約束,以及等等。名單幾乎是無窮的。

這是尤其的MySQL真的,有很方便的group_concat功能,可根據需要,同時仍保持規範化的數據庫的全部功能和速度時,容易出現這個數據作爲一個逗號分隔的字符串。

您從使用逗號分隔方法中獲益匪淺,但失去了可搜索性和性能。讓撒旦落後於你,並規範你的數據。

2

那麼,有一些東西,如可擴展性要考慮。如果您需要添加/刪除技能,該怎麼辦?如何重命名技能?如果技能的數量增加了你的領域的規模會發生什麼?爲了適應這種情況,必須重新調整字段的大小是個不錯的做法。

可維護性怎麼樣?另一位開發人員是否可以進來並理解你所做的事情?如果給玩家兩次相同的技能會發生什麼?

你的同事的建議也不正確。在這種情況下你會有3張桌子。一個高手玩家表,一張技能表和一張與兩者都有關係的表,創建一個多對多的關係,允許單個技能與許多玩家相關聯,許多玩傢俱有相同的技能。

+0

恕我直言:我相信海報的意圖是(實質上)有一個播放器記錄包含一些值代表技能水平 - 即fixnum類型,而不是布爾值 - 所以第三個表會有player_id:skill_id:level(int)映射,或者(如果所有玩家都擁有所有技能),雙表設計可能會爲每種技能(int或適當類型)使用一列。絕對同意@達思格爾的意圖,但我認爲他/他可能會誤解這個意圖嗎? – BRFennPocock

2

由於數據庫將索引內容(假設您使用索引),因此搜索內容並獲取所需內容的速度非常快。請記住:數據庫旨在保存大量信息,而數據庫(如作爲關係數據庫的mysql)則用於關係。

另一個問題是系統的可維護性。維護一個正常化的系統會容易得多。而當你要移除或添加技能時,它會更容易。

當您即將從數據庫中獲取有關玩家技能的信息時,您可以通過簡單的JOIN輕鬆獲取與相關技能相關的信息。

我說:讓數據庫做它最擅長的事情 - 處理數據。並讓你的編程做它應該做的;)

相關問題