web開發中,查詢搜尋時,常見需要根據一定字段進行排序後取得的查詢結果,有時排序規則複雜時,簡單的sql語句不能實現,需要用搜尋引擎或排名的元件才能實現功能。
如:取得訂單列表,實現訂單狀態指定為「待處理」的訂單排名靠前,我們用sql語句實現如下:
select 1 sort,a.* from order a where a.orderstatus='initial' union select 2 sor,a.* from order a where a.orderstatus!='initial' order by asc;
談到搜尋,一般就想起了sql server的fulltextsearch(全文搜尋)功能,它確實強大,但使用起來也要做一些較為繁瑣的準備工作,一般小型的專案或者對搜尋要求(包括效能需求)不是很高的情況下實用它還是有點太重型了。簡單的搜尋用sql查詢即可,但一般面臨的乙個問題就是如何對搜尋結果按匹配字段進行優先順序排序。
例如有個產品表(products),它的字段包:括產品id、產品名稱、產品類別、產品品牌、產品簡介、產品詳細介紹。
字段型別
prodid
intprodname
nvarchar
categoryname
nvarchar
prodbrand
nvarchar
prodintro
nvarchar
proddescription
nvarchar
現在我們要求通過某個關鍵字從products表中搜尋包含該關鍵字的記錄,凡是以下任何乙個字段包含該關鍵字的記錄都列出來:prodname, categoryname , prodbrand, prodintro, proddescription。 並且搜尋結果按照前述欄位的匹配優先順序進行排序:
1)先列出欄位prodname匹配關鍵字的記錄,然後列出欄位categoryname匹配關鍵字的記錄,依此類推,最後列出欄位proddescription匹配關鍵字的記錄;
2)在字段prodname匹配關鍵字的所有記錄中,先列出欄位categoryname也匹配關鍵字的記錄,然後列出欄位prodbrand也匹配關鍵字的記錄,依次類推…
3)按照規則2遞迴排序每個記錄分組……
搜尋匹配該關鍵字的所有記錄的sql語句倒很簡單:
select *
from products
where prodname like
'%keyword%'
or categoryname like
'%keyword%'
or prodbrand like
'%keyword%'
or prodintro like
'%keyword%'
or proddescription like
'%keyword%'
但對搜尋出的結果進行匹配優先順序排序稍微有點困難。在用簡單的sql進行搜尋時有兩種方式來達到這個排序的目的:加權法和多欄位排序法(我瞎取的名字^-^)。
一、加權法
對搜尋的每條記錄計算出乙個排序權值來,然後將所有搜尋結果按照這個排序權值進行降序排列即可。每條被搜尋出的記錄的排序權值為該記錄所有欄位的權值之和。某個欄位的權值取決於該欄位是否匹配關鍵字,如果不匹配則為0,如果匹配則為改字段的匹配權值。欄位的匹配權值計算方式為:
fieldpriority = 2的i次冥(i為該字段在所有被搜尋的字段優先順序排序中倒排的位置)
例如,在我們示例中各字段的匹配權值為:
字段
倒排位置
匹配權值
prodname416
categoryname38
prodbrand24
prodintro12
proddescription01
之所以採用這種演算法,是為了確保某個字段匹配的記錄的排序權值不會低於另外一條不匹配該欄位但後續欄位都匹配的記錄的排序權值。例如記錄a中僅僅prodname匹配關鍵字,所以它的排序權值為16,而記錄b中除了欄位prodname外其他欄位都匹配,則其排序權值為15(8+4+2+1=15)。但記錄a仍然會排在記錄b前面。
相應的sql大致如下:
select *, (
(case
when charindex(prodname,keyword)>-1 then 16 else 0 end) +
(case
when charindex(categoryname,keyword)>-1 then 8 else 0 end) +
(case
when charindex(prodbrand,keyword)>-1 then 4 else 0 end) +
(case
when charindex(prodintro,keyword)>-1 then 2 else 0 end) +
(case
when charindex(proddescription,keyword)>-1 then 1 else 0 end)
) as orderpriority
from products
where prodname like 『%keyword%' or
categoryname like 『%keyword%'
orprodbrand like 『%keyword%' or
prodintro like 『%keyword%'
orproddescription like 『%keyword%'
order
by orderpriority desc
二、多欄位排序法
加權法實在是有點囉嗦,倒不如直接利用sql可以對多個字段進行排序來實現更清晰更直接。實際上我們把每個字段是否匹配的權值分散到sql的order裡即可,大致sql如下:
select *
from products
where prodname like 『%keyword%' or
categoryname like 『%keyword%'
orprodbrand like 『%keyword%' or
prodintro like 『%keyword%'
orproddescription like 『%keyword%'
order
by (case
when charindex(prodname,keyword)>-1 then 0 else 1 end),
(case
when charindex(categoryname,keyword)>-1 then 0 else 1 end),
(case
when charindex(prodbrand,keyword)>-1 then 0 else 1 end),
(case
when charindex(prodintro,keyword)>-1 then 0 else 1 end),
(case
when charindex(proddescription,keyword)>-1 then 0 else 1 end)
web開發之快取
以資料為驅動的web站點,當訪問量增大後,由於頻繁的從db中讀取資料,使得db伺服器的壓力大增,從而影響系統的效能。為了緩解這種來自於大訪問量的頻繁讀取db的壓力,我們可以把一些資料快取起來,當請求過來後,不需要去db中獲取資料,在快取中讀取即可 快取不存在,在到db中取 這樣大大減輕了db的壓力,...
web開發之介面開發流程
web開發很多專案有不同的開發流程,有些專案直接由程式設計師將前端 後台全部包攬開發製作完成。而乙個高質量的web開發專案,應該由需求人員 產品人員 ue設計人員 視覺人員 美工人員 ui製作人員 前端工程師 程式設計師等人員的參與,共同合作完成。下面講一下我公司的開發流程。1.首先由需求人員 產品...
web開發之資料安全
關於介面安全,一般非常簡單的作用,只是使用者驗證,即合法性檢查。我乙個老同事一直這樣用 個人感覺也未嘗不可 每次請求 介面的時候 驗證下access token,比如這個token是個 md5值,再在這個值上面加幾個隨機數,這這值就不是md5的值了,可破解的難道就大大增加了。if post acce...