2012-07-01 14 views
0

如果您希望在select語句上獲得更多查詢性能和最小內存丟失,在數據庫中插入布爾值的最佳解決方案是什麼?保存布爾值並在搜索時保存cpu和內存的最佳解決方案

例如: 我有36場一個表,其中30布爾值(零或一個),我需要搜索使用布爾字段,僅僅有真正值的記錄。

SELECT * FROM `myTable` 
WHERE 
    `field_5th` = 1 
    AND `field_12th` = 1 
    AND `field_20` = 1 
    AND `field_8` = 1 

有沒有解決方法?

+0

轉到位掩碼和二進制運算符。 – Mahn

+0

@Mahn請給我一個鏈接到mysql參考 – Hamidreza

回答

1

如果你想存儲布爾值或標誌,基本上有三個選項:

  1. 單獨列

這反映在你上面的例子。其優點是您可以將索引放置在最常用於查找的標誌上。缺點是這會佔用更多的空間(因爲可以分配的最小列大小是1個字節)。

但是,如果列名真的是field_20,field_21等。那麼這個絕對不是要走的路。編號列是您應該使用其他兩種方法中的一種。

  1. 位掩碼

作爲建議上面可以存儲在一個整數列的多個值。一個BIGINT列會給你多達64個可能的標誌。

值將類似於: UPDATE表SET flags = b'100'; UPDATE表SET flags = b'10000';

則字段會看起來像:10100

這將是有設置兩個標誌值。要查詢任何特定的標誌值集合,你會做

SELECT flags FROM table WHERE flags & b'100';

這樣做的好處是您的標誌在空間上非常緊湊。缺點是你不能在字段上放置索引,這有助於提高搜索特定標誌的性能。

  1. 一個一對多的關係

這是你創建另一個表,每一行也就有它的鏈接到該行的ID和標誌:

CREATE TABLE main( main_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, );

CREATE TABLE標誌( main_id INT UNSIGNED NOT NULL, name VARCHAR(16) );

然後你會插入多行到標誌表。

其優點是您可以使用索引進行查找,並且每行可以有任意數量的標誌而無需更改模式。這適用於稀疏值,其中大多數行沒有設置值。如果每行都需要定義所有的標誌,那麼這不是非常有效。

出於性能comparisson你可以閱讀博客文章我的話題說: Set Performance Compare

而且當你問這是「最好的」,這是一個非常主觀問題。最擅長什麼?這一切都取決於你的數據是什麼樣的,你的需求是什麼以及你想如何查詢它。

請記住,如果你想要做這樣的查詢: SELECT * FROM表WHERE some_flag =真

指標只會幫助你,如果幾行具有值集。如果表中的大部分行都有some_flag = true,那麼mysql將忽略索引並改爲執行全表掃描。

+0

我找不到比你更好的答案,謝謝你的回答:) – Hamidreza

0

您要查詢多少行數據?您可以將布爾值存儲在整數值中,並使用位操作來測試它們。它不可轉位,但存儲非常好。在索引中使用TINYINT字段將選擇一個索引來使用並從那裏進行掃描。

+0

我有超過100萬的記錄在這張表中,選擇語句上的禁食和低使用cpu和內存對我來說太重要了。不是磁盤存儲或插入延遲 – Hamidreza

+1

[set](http://dev.mysql.com/doc/refman/5.5/en/set.html)? – scriptin

+0

@DmitryScriptin,感謝**設置**鏈接,這對我很有幫助:) – Hamidreza

相關問題