2010-02-15 101 views
1

我正在設計一個使用PHP和MySQL的網站,並且隨着網站的進展,我發現自己在users表中添加了越來越多的列來存儲各種變量。網站:什麼是存儲大量用戶變量的最佳方式?

這讓我想到了,有沒有更好的方法來存儲這些信息?只是爲了澄清,這些信息是全球性的,可能會受到其他用戶的影響,因此cookies不起作用,如果他們清除cookie,我也會丟失信息。

我的問題的第二部分是,如果它確實證明將它存儲在數據庫中是最好的方法,那麼擁有大量列或者將相關列組合到分隔的varchar列然後用PHP爆炸它們?

謝謝!

+0

謝謝! 我會研究其他提到的數據庫,並分解數據庫。 標準化的user_variables表方式不幸的是不能正常工作,因爲我經常需要一次拉多個變量。 對於一些我認爲我可以連接成一個字符串,因爲我幾乎總是將它們拉在一起,我從來沒有索引它們。 再次感謝,只是想確保我沒有失去明顯的東西。 – Alex 2010-02-15 22:30:14

回答

3

根據我的經驗,我寧願得到數據庫的權利,而不是開始添加逗號分隔的領域持有多個項目。不得不篩選多個逗號分隔的字段只會損害程序的效率和代碼的可讀性。另外,如果你的表增長得很多,那麼你可能需要考慮將它拆分成多個由外部依賴關係連接的表嗎?

0

數據庫是一個非常好的地方存儲這些數據,只要它們是變量而不是像龐大的圖像文件。數據庫具有存儲和檢索大量數據的所有優化和規範。您在文件系統級別設置的任何內容都會隨着數據庫在速度和功能方面的優勢而受到打擊。

擁有大量列還是相關列組合到分隔的varchar列然後在PHP中分解它們會更便宜嗎?

這不是真的那麼多的性能維護問題IMO - 它不好玩管理幾百列。將這些數據(可能爲serialize d對象)存儲在TEXT字段中是一個可行的選項 - 只要100%確定您不需要對該數據進行任何查詢即可。

但是,爲什麼不使用規範化user_variables表所示:

id | user_id | variable_name | variable_value 

這是一個更復雜的查詢,但提供了一個完整的清潔表結構。您可以通過這種方式輕鬆添加任意用戶變量。

如果您正在進行諸如SELECT FROM USERS WHERE variable257 = 'green'之類的大量查詢,您可能必須堅持要有特定的列。

0

我不會去分組列和爆炸他們的選項。這是不整潔的工作,非常難以管理。相反,也許可以嘗試將這些列分佈在幾張桌子上,並使用InnoDb的交易功能。

如果您仍然不喜歡頻繁更新數據庫的想法,並且如果此方法符合您嘗試實現的目標,則可以使用APC's caching function在服務器上「全局」存儲(緩存)信息。

0

MongoDB(和它的NoSQL表親)對於像這樣的東西很棒。

3

我會創建一個user_meta表,其中有三列:user_id,key,value

+0

雖然我喜歡這種方法的簡單性,但正如我之前所說的,我不確定它適用於哪些情況下(大多數情況下),我需要同時從大量列中獲取數據(這是最的時間)。還是我誤會了? – Alex 2010-02-15 22:34:45

+0

正確索引,類似於'SELECT鍵,值FROM user_meta WHERE user_id = 1 AND key IN('homepage','background_color','arm_length','bacon_lover')的查詢應該運行得很好。一旦開始放緩,您可以考慮劃分數據庫,其中用戶1-100,000在一個DB上,100,001-200,000在另一個上,等等。 – ceejayoz 2010-02-15 22:38:16

+2

E.F. Codd在他的墳墓裏翻滾。 – Breton 2010-02-15 23:00:48

0

數據庫絕對是存儲數​​據的最佳場所。 (我假設你正在考慮將它存儲在平面文件中)否則,使用數據庫而不是存儲在文件中,您肯定會獲得更好的性能和安全性。

隨着多列或界定他們的問候到存儲你的數據......這是個人的選擇,但如果你要劃定項目,你應該考慮幾件事情

  1. ,則需要想想你要用什麼劃分它們(在你的分隔文本中不會出現的東西)
  2. 我經常發現它有助於試圖和可視化你的關卡中的其他程序員是否能夠理解什麼你沒有多少幫助。
  3. 是的,正如Pekka所說,如果你想對存儲的數據執行查詢,你應該堅持使用單獨的列
  4. 如果你只是不檢索和解析所有數據,你也可以稍微提高性能想要幾個字段的信息

我建議與單獨的列一起,因爲它爲您提供了更大的靈活性在未來的選項。沒有比徹底改變你的數據結構和將信息遷移到軌道上更糟的了!

0

我會建議設置一個memcached服務器(請參閱http://memcached.org/)。它已被證明是可行的與大量的大網站。 PHP有兩個將客戶端集成到運行時的擴展(請參閱http://php.net/manual/en/book.memcached.php)。

試一下,你不會後悔的。

編輯
當然,這僅是該公司經常使用和否則將不得不從數據庫連連加載數據的選項。請記住,您仍然需要將數據保存到某種持久性存儲。

+0

謝謝,我也會考慮這一點。 – Alex 2010-02-15 22:30:56

0

面向文檔的數據庫可能是您需要的。

如果你想堅持到關係數據庫,不拿只是哦,這麼多場創建表的原始的方法:

CREATE TABLE SomeEntity (
    ENTITY_ID CHAR(10) NOT NULL, 
    PROPERTY_1 VARCHAR(50), 
    PROPERTY_2 VARCHAR(50), 
    PROPERTY_3 VARCHAR(50), 
    ... 
    PROPERTY_915 VARCHAR(50), 
    PRIMARY KEY (ENTITY_ID) 
); 

而是定義屬性表:

CREATE TABLE Attribute (
    ATTRIBUTE_ID CHAR(10) NOT NULL, 
    DESCRIPTION VARCHAR(30), 
    /* optionally */ 
    DEFAULT_VALUE /* whatever type you want */, 
    /* end_optionally */ 
    PRIMARY KEY (ATTRIBUTE_ID) 
); 

然後定義您的SomeEntity表,該表僅包含基本屬性(例如,註冊表中的必填字段):

CREATE TABLE SomeEntity (
    ENTITY_ID CHAR(10) NOT NULL 
    ESSENTIAL_1 VARCHAR(30), 
    ESSENTIAL_2 VARCHAR(30), 
    ESSENTIAL_3 VARCHAR(30), 
    PRIMARY KEY (ENTITY_ID) 
); 

然後爲您可能或可能不想存儲的那些屬性定義一個表。

CREATE TABLE EntityAttribute (
    ATTRIBUTE_ID CHAR(10) NOT NULL, 
    ENTITY_ID  CHAR(10) NOT NULL, 
    ATTRIBUTE_VALUE /* the same type as SomeEntity.DEFAULT_VALUE; 
         if you didn't create that field, then any type */, 
    PRIMARY KEY  (ATTRIBUTE_ID, ENTITY_ID) 
); 

很明顯,在你的情況下,SomeEntity是用戶。

0

相反的MySQL的你可以考慮使用一個triplestorekey-value store 這樣,你得到其所有的多線程多用戶,性能和緩存巫術的典型應用該類超支,想通了,沒有試圖提前弄清楚所有的麻煩時間什麼樣的價值,你真的想存儲。

缺點:找出愛達荷州所有擁有帽子的人的平均工資要高一點。

0

取決於您正在存儲什麼樣的用戶信息。如果它的會話相關數據,使用php會話協調會話事件處理程序將會話數據存儲在數據庫中的單個數據字段中。

相關問題