程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 在MySQL字段中應用逗號分隔符的辦法分享

在MySQL字段中應用逗號分隔符的辦法分享

編輯:MySQL綜合教程

在MySQL字段中應用逗號分隔符的辦法分享。本站提示廣大學習愛好者:(在MySQL字段中應用逗號分隔符的辦法分享)文章只能為提供參考,不一定能成為您想要的結果。以下是在MySQL字段中應用逗號分隔符的辦法分享正文


被朋分的字段必定是無限並且數目較少的,我們弗成能在一個字符串中存儲無窮多個字符
這個字段所屬的表與這個字段聯系關系的表,必定是一對多的關系
好比上面這個表構造所代表的content與tag這兩個對象

mysql> SELECT * FROM content;
+----+------+| id | tags | +----+------+| 1 | 1,2 | | 2 | 2,3 | +----+------+
2 rows in set (0.01 sec)
mysql> SELECT * FROM tag;
+----+-------+| id | name | +----+-------+| 1 | php | | 2 | mysql | | 3 | java | +----+-------+
3 rows in set (0.00 sec)

這些准繩成績,信任年夜家在開辟進程中曾經很熟習了。然則你在應用這類辦法來處置現實成績時,心坎必定照樣有些許忐忑,由於這類辦法或多或少看上去有點像野門路。在那本厚厚的《數據庫》教材中,也沒有提到這類設計辦法,尺度的辦法仿佛是應當應用一個關系映照表在這兩個表之間插一槓子,雖然如許會應用效力低下的銜接查詢。

每一個開辟者都曾糾結於尺度與效力,但我想我們的盡力能使這類辦法的應用看起來加倍尺度。留意,以下評論辯論的應用辦法僅限於mysql,但其它數據庫應當可以移植。

相干性檢索
許多開辟者還在應用陳舊的LIKE辦法來完成相干性檢索,好比下面誰人數據庫構造中,content表中的兩筆記錄都有2這個tag,那末如何在我掏出記載1時,把與它tag相干的記載也顯示出來呢。其實這也是CMS須要面臨的一個根本成績,也就是相干內容的查詢。

假如你是一個菜鳥,你能夠只會想到LIKE辦法,好比先把記載1掏出來,然後再把tags字段按逗號朋分,最初做一個輪回用LIKE檢索content表中一切tags字段中包括2的記載,相似如許

SELECT * FROM content WHERE tag LIKE '%2%' AND id <> 1

但這類辦法其實是太慢了,查詢次數多不說,LIKE查詢原來就是一個比擬慢的辦法。並且你還要處置前後逗號的成績,總之費事是一年夜堆。

所以讓我們靜下心來翻翻mysql手冊,看看有無甚麼欣喜。這個時刻,一個名為FIND_IN_SET的函數,會閃著金光映入你的視線。讓我們看看這個函數的界說


FIND_IN_SET(str,strlist)
Returns a value in the range of 1 to N if the string str is in the string list strlist consisting of N substrings. A string list is a string composed of substrings separated by “,” characters. If the first argument is a constant string and the second is a column of type SET, the FIND_IN_SET() function is optimized to use bit arithmetic. Returns 0 if str is not in strlist or if strlist is the empty string. Returns NULL if either argument is NULL. This function does not work properly if the first argument contains a comma (“,”) character.

哦,PERFECT! 簡略說來就是尋覓一個字符串能否在另外一個以逗號朋分的字符串中存在的函數,這的確是為我們量身定做的。那末我們的sql就釀成

SELECT * FROM content WHERE FIND_IN_SET('2', tags) AND id <> 1

在翻這些函數的進程中,你應當曾經深深地領會到mysql的設計者對以逗號朋分存儲字段辦法的確定,由於有許多辦法就是設計用來處置這類成績的。

如許看起來很多多少了,一切仿佛完善了,是如許嗎?其實還沒有,假如你的tag比擬多,你須要創立多個sql語句,並且有的記載聯系關系的tag比擬多,有的比擬少,怎樣能依照相干性停止分列呢。

這個時刻,你可以存眷mysql的全文檢索功效。這個詞你確定看見過有數回了,然則這麼應用的確定很少,讓我們直接看語句吧

SELECT * FROM content WHERE MATCH(tags) AGAINST('1,2') AND id <> 1

這 個語句的優勢是不言而喻的,你不須要對tags字段做再次朋分。那末這類查詢的道理是甚麼呢,略微懂得下MATCH AGAINST的用法就曉得,全文檢索的默許分隔符是標點符號和stopwords,個中前者恰是我們須要的特征。全文檢索依照逗號將MATCH和 AGAINST裡的字符串做朋分,然後將它們婚配。

須要留意的是下面sql僅僅是個例子,假如你直接這麼履行,是沒法獲得任何成果的。緣由在以下

  1. 你須要對tags字段樹立fulltext索引(假如僅僅是測試,可以不做,建索引只是進步機能,對成果沒有影響)
  2. 每一個被標點符號朋分的word長度必需在3個字符以上,這才是症結,我們的tag id太短了,會被主動疏忽失落,這個時刻你可以斟酌讓id從一個比擬年夜值開端自增,好比1000,如許它就夠長了。
  3. 你撞到了stopwords,好比你的tags字段是如許的'hello,nobody',nobody是mysql的一個默許的stop words,它會被主動疏忽。stop words是英文中的一些有意義詞,搜刮的時刻不須要它們,相似漢語中的助詞等等。但在我們的應用中明顯不是用來做搜刮的,是以可以在my.cnf文件 裡,加上ft_stopword_file=''來禁用它

跟著WEB技巧的成長,相干搜刮走SQL的情形愈來愈少,許多時刻只須要用搜刮引擎便可以了。但本文的目標其實不只是評論辯論這類辦法,而是表現完成這一成果的進程。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved