2014-06-19 39 views
2

如果我有一張充滿記錄的表格,它們可能是付款,預訂或多個其他實體,是否有最佳做法將每條記錄的狀態保存爲一個簡單的0表示不活動,1表示活動?將簡單的0或1之外的記錄狀態保存在MySQL表中的最佳方式是什麼?

例如,付款可能具有「掛起」,「已完成」或「失敗」狀態。我之前做過的方法是在另一個表中包含一系列值/文本對的定義,即。 0 ='失敗',1 ='等待'和2 ='完成'。然後,我將在支付表中存儲0,1或2,並根據需要使用內部聯接從定義表中讀取文本。

此方法有時看起來過於複雜和不必要,我一直在考慮將我的方法直接更改爲直接在付款表的狀態字段中保存單詞'completed'。

這是否被認爲是不好的做法,如果是這樣,最佳做法是什麼?

回答

2

這些似乎是交易記錄,因此可能有很多這樣的記錄,查詢性能將成爲問題。因此,組織狀態列或列的方式可能很明智,因爲複合索引對您所需記錄的訪問將很簡單。

很難讓您在不知道您的查詢模式的情況下「做到這一點,不要那樣做」的建議,所以這裏有幾個場景。

假設您需要在本月獲得所有有效的預訂。你會希望表單

SELECT whatever 
    FROM xactions 
    WHERE active = 1 and type = 2 /*bookings*/ 
    AND xaction_date >= CURDATE() - INTERVAL DAY(CURDATE()) DAY 

的查詢這將在(active,type,xaction_date)與化合物BTREE指數進行大。查詢可以通過隨機訪問索引到第一個合格的記錄,然後順序掃描來滿足。

但是,如果你有一個類型= 2的含義活躍預訂和類型= 12意味着非激活預訂,並希望所有預訂都主動和這個月不活躍,你的查詢將是這樣的:

SELECT whatever 
    FROM xactions 
    WHERE type IN (2,12) 
    AND xaction_date >= CURDATE() - INTERVAL DAY(CURDATE()) DAY 

這億韓元由於IN(2,12)子句需要不相交的值範圍,所以能夠非常容易地掃描複合索引。

tl; dr在MySQL中,更容易爲各種狀態項索引單獨的列以獲得更好的查詢性能。但如果不瞭解查詢模式,很難知道。

+0

我不熟悉複合指標,並且沒有聽過術語BTREE。你是否說我應該使用定義表方法,但除此之外,還應該將狀態列聲明爲索引? – Marc

+0

是的。你應該閱讀複合索引。現在不要擔心BTREE;幾乎每個MySQL索引都已經是BTREE。 –

1

如果狀態超過開/關布爾類型,那麼我總是會有一個查找表,如您所描述的。除了(我相信)更好的規範化設計之外,它還使得基於數據實體的對象更易於編碼和使用。

1

對於您提到的具體情況,MySQL支持ENUM datatypes

在你的例子中,一個ENUM看起來是合適的 - 它限制了有效選項的範圍,它在結果中被翻譯回人類可讀的文本,並創建可讀的代碼。它在查詢時具有一些性能優勢。 但是,請參閱this answer以瞭解可能的缺點。

相關問題