2012-10-01 79 views
4

我有一個固定的表,不會改變。我有超過80,000行。添加排名值到我的MySQL表

CREATE TABLE `word_list_master` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `word` varchar(64) NOT NULL, 
    `created` int(11) NOT NULL, 
    `frequency` int(11) NOT NULL, 
    `number_of_files` int(11) NOT NULL, 
    `combined_frequency` bigint(24) NOT NULL, 
    PRIMARY KEY (`id`) 
) 

我想創建一個第7列「等級」,它將確定由combined_frequency列排序的行的等級。我這樣做是爲了減少數據庫在線時的開銷。

我可以通過MySQL語句來完成嗎?還是必須在PHP中編寫一堆SELECT/INSERT語句(例如)?到目前爲止,我一直在做PHP的大部分工作,但在桌面上執行操作需要長達24小時的時間。

我在看RANK函數,但由於我的MySQL能力只有公平的容量,我遇到了問題。

回答

1

這是你如何rank字段添加到您的表:

SET @rownum = 0; 

SELECT *, (@rownum := @rownum + 1) AS rank 
FROM word_list_master 
ORDER BY combined_frequency DESC; 

更新:如果你想寫針對等級字段的查詢,你必須使用上表像派生表所以:

SET @rownum = 0; 
SELECT * 
FROM 
(
    SELECT *, (@rownum := @rownum + 1) AS rank 
    FROM word_list_master 
    ORDER BY combined_frequency DESC; 
) t 
WHERE rank = 5 

如果你想分頁查詢,像這樣:

SET @rownum = 0; 
SELECT * 
FROM 
(
    SELECT *, (@rownum := @rownum + 1) AS rank 
    FROM word_list_master 
    ORDER BY combined_frequency DESC; 
) t 
WHERE rank BETWEEN ((@PageNum - 1) * @PageSize + 1) 
AND (@PageNum * @PageSize) 

更新:

注意,已經有一個BUIT式的方式做的,而不是這種可怕的查詢這是[LIMIT {[offset,] row_count }],這是標準的mysql-方式做到這一點本。如果您只想從查詢中獲取有限的結果集,請不要使用以前的方法。

+0

有沒有辦法永久添加列「排名」的表? – Banners

+0

是的(通過PHP的),但它不是更快 –

+0

@Banners我認爲你的表中的AUTO_INCREMENT''id'會像這樣工作。但是,爲什麼你想在一個領域存儲排名。不推薦。行的順序在關係模型中不重要。你不應該考慮這些數據的順序。你應該把你的桌子當成一套。 –

2

通常情況下,我不會認爲「不這樣做」是對這樣一個問題的有效答案,但是你不會通過添加一個新的列來幫助你的情況。您已經有數字列可以用來訂購您的數據。爲此目的添加第二個數字列不僅是過度殺戮,它是糟糕的設計。

如果它採取「長達24小時」做任何操作上只包含80000行的表(這是不是很多),那麼你需要add indexes的列被用於搜索/排序/加入。

+0

例如,如果我正在尋找選擇「WHERE rank = 5」的行,對已經預先確定的列執行此操作會不會更好?該表是靜態的,即使在一年內也不會改變。 – Banners

+2

正確的方法是'select * from ... order by ... limit(5,1)'。這將選擇一行,將5行偏移到結果集中;也就是有序結果的第5行。一旦你正確索引你的表,它也將是高性能的。 – meagar