2013-07-10 58 views
3

我正在使用電子郵件支持系統。每個存儲的電子郵件包含from_email,subject,date,某些標誌以及郵件的contents。顯然,郵件數量可能很大,我們的系統主要關注最近的郵件(例如,最近14天),而較舊的郵件則被視爲已歸檔。我們也想搜索,過濾一些標籤,等等。如何在磁盤上存儲長文本列?

對於電子郵件的列表視圖,我們不需要考慮content字段。我正在考慮兩個選項,一個表中的所有數據,以及一個存儲LONGTEXT電子郵件正文的獨立表。

假設SQL SELECT字段不包含content字段,將它放在單獨的表中是否更高效?顯然,LONGTEXT字段不是與固定長度的行數據一起存儲的,但我想它可能是交錯的,所以必須爲列表視圖獲取的頁面數量更大。

我使用MariaDB 5.5.25和InnoDB引擎。

+1

答案將取決於您正在使用的MySQL存儲引擎以及您正在使用的是哪個版本的MySQL。 –

+0

我忘記了這些信息,但現在我添加了它。 – apartridge

回答

4

我發現在MySQL 5.5手動此信息,section 14.3.12.2. File Space Management

如果[一個InnoDB]行不到半頁長,它的所有網頁內本地存儲。如果它超過半頁,則將可變長度的列選擇用於外部頁外存儲,直到該行適合半頁爲止。對於選擇用於脫離頁面存儲的列,InnoDB將本地第一個768字節存儲在行中,其餘部分存儲在溢出頁面中。每個這樣的列都有自己的溢出頁面列表。 768字節的前綴伴隨着一個20字節的值,該值存儲列的真實長度並指向溢出列表,其中存儲剩餘的值。

在plainer英語中,如果僅使用主鍵和長文本創建表,InnoDB將在longtext大於8000字節(半頁)時拆分該行。

我的建議是將longtext放在存儲的電子郵件表格行的末尾,因爲無論如何,InnoDB可能會拆分長行電子郵件的行。

將所有固定長度的列放在行的開頭,並在行的末尾放置可變長度的列,這是很好的數據庫實踐。

+0

感謝您的回答。根據這些信息,我會發現最好在身體的另一張桌子上放一張桌子,這樣身體內容字段不會佔用'meta'表中的空間? – apartridge

+1

我也會提到這個[5.1。 InnoDB行存儲概述](http://dev.mysql.com/doc/innodb/1.1/en/innodb-row-format-overview.html)行和相關列的存儲會影響查詢和DML操作的性能。隨着更多的行裝入單個磁盤頁面,查詢和索引查找可以更快速地工作,[...]' –

+1

注意,對於Barracuda類型的文件中的表,這是不同的。當行需要分割時,只有20個字節長度和指針被存儲在行內,其餘的(即使少於768個字節)被存儲在外部。 http://dev.mysql.com/doc/innodb/1.1/en/innodb-row-format-dynamic.html –