MySQL中Bit數(shù)據(jù)類型的使用方式
Mysql Bit字段類型用來存儲二進(jìn)制的位值,Bit(M)代表可存儲M位的二進(jìn)制數(shù)據(jù),M取值為區(qū)間為1-64。
數(shù)據(jù)庫Bit類型常用來存儲Boolean類型的狀態(tài),也就是可以使用一個字段來存最多64個狀態(tài),如果你的系統(tǒng)狀態(tài)夠多或者將來可能會有擴(kuò)展?fàn)顟B(tài),那推薦使用這個類型進(jìn)行處理,查詢或更新某個狀態(tài)時按位操作即可。
舉個例子:
某個系統(tǒng)需要保存對用戶發(fā)送短信的狀態(tài),有10幾種不同類型的短信,每種都要標(biāo)記發(fā)過沒有,這時候用bit類型就很方便。
1、準(zhǔn)備測試表
CREATE TABLE `bit_demo` ( `id` int NOT NULL, `name` varchar(100) DEFAULT NULL, `flag` bit(3) DEFAULT NULL COMMENT '從低到高位依次為移動,電信,聯(lián)通', PRIMARY KEY (`id`), KEY `idx_bit` (`flag`) )
為了將來可擴(kuò)展,我們一般先從低位開始使用,此處我們設(shè)計三個位,從低到高位依次為移動,電信,聯(lián)通短信渠道是否完成發(fā)送,各位值上1表示true,0表示false。3個位,一共8種情況,二進(jìn)制值范圍:000->111,十進(jìn)制范圍:0->7,
如下表格:
二進(jìn)制 | 十進(jìn)制 | 說明 |
---|---|---|
000 | 0 | 所有渠道都未發(fā)送 |
001 | 1 | 移動渠道已發(fā)送 |
010 | 2 | 電信渠道已發(fā)送 |
011 | 3 | 移動、電信渠道已發(fā)送 |
100 | 4 | 聯(lián)通渠道已發(fā)送 |
101 | 5 | 移動、聯(lián)通渠道已發(fā)送 |
110 | 6 | 聯(lián)通、電信渠道已發(fā)送 |
111 | 7 | 移動、電信、聯(lián)通渠道已發(fā)送 |
2、如何寫入bit數(shù)據(jù)
位值字面值用 b
或者 0b
做前綴,后接以 0
跟 1
組成的二進(jìn)制數(shù)字。
其中 0b
是區(qū)分大小寫的, 0B
則會報錯。
合法的 Bit-value:
- b’01’
- B’01’
- 0b01
非法的 Bit-value:
- b’2’ (2 不是二進(jìn)制數(shù)值, 必須為 0 或 1)
- 0B01 (0B 必須是小寫 0b)
以下三條sql插入了相同位值:
insert into bit_demo(`id`,`name`,`flag`) values(1,'張三',3); insert into bit_demo(`id`,`name`,`flag`) values(2,'李四',b'011'); insert into bit_demo(`id`,`name`,`flag`) values(3,'三五',0b011);
3、bit數(shù)據(jù)查詢展示
位值是作為二進(jìn)制返回的,輸出到 MySQL Client 可能會顯示不出來**(有些client桌面工具默認(rèn)展示10進(jìn)制),**
如果要轉(zhuǎn)換為可打印的字符,可以使用內(nèi)建函數(shù) BIN()
或者 HEX(
)來進(jìn)行查詢,
如下內(nèi)置函數(shù):
- flag+0 10進(jìn)制
- BIN(flag) 二進(jìn)制
- OCT(flag)八進(jìn)制
- HEX(flag) 十六進(jìn)制
內(nèi)置函數(shù)使用案例如下:
SELECT name,flag+0, BIN(flag), OCT(flag), HEX(flag) FROM bit_demo
高位為0,轉(zhuǎn)換函數(shù)不會顯示,從上圖業(yè)務(wù)數(shù)據(jù)看出,所有用戶已發(fā)送移動和電信渠道的短信.
4、修改指定位狀態(tài)
- 如果張三用戶已發(fā)送聯(lián)通渠道短信,如何update數(shù)據(jù)?
- 如果張三用戶取消電信渠道短信,如何update數(shù)據(jù)?
- 先把張三數(shù)據(jù)查出來,變更數(shù)據(jù),再整體寫回去?
正確姿勢應(yīng)該如下:
4.1、使用或運(yùn)算寫1值
說明:運(yùn)用任何值和0做或運(yùn)算,不改變原值特性,例如將011的最高位改為1的運(yùn)算如下:
// 011|100=111 update bit_demo set flag=flag|100 where id=1
查詢結(jié)果:
從上圖業(yè)務(wù)數(shù)據(jù)看出,張三用戶所有渠道短信已發(fā)送.
4.2、使用與運(yùn)算寫0值
說明:運(yùn)用任何值和1做與運(yùn)算,不改變原值特性,例如將111的最高位改為0的運(yùn)算如下:
// 111&011=011 update bit_demo set flag=flag&011 where id=1
查詢結(jié)果:
從上圖業(yè)務(wù)數(shù)據(jù)看出,張三用戶聯(lián)通渠道短信還未發(fā)送.
4.3、使用異或運(yùn)算寫0或1值
說明:用異或運(yùn)算修改,只會在原值基礎(chǔ)上進(jìn)行變更,最終值有可能是0也有可能是1
法則回顧:異或也叫半加運(yùn)算,其運(yùn)算法則相當(dāng)于不帶進(jìn)位的二進(jìn)制加法,例子:
110 ^ 100 = 010
update bit_demo set flag=flag^b'100' where id=1;
5、如何根據(jù)某位狀態(tài)查詢
- 如何查詢所有已發(fā)送過電信渠道短信的數(shù)據(jù)?
- 如何查詢所有未發(fā)送電信渠道短信的數(shù)據(jù)?
原理:將數(shù)據(jù)庫值先作位運(yùn)算,再作對比
任意數(shù)據(jù)xxx和010作&運(yùn)算,都等于0x0格式
# 查詢已發(fā)送電信渠道數(shù)據(jù) SELECT id,name,flag+0, BIN(flag) FROM bit_demo where flag&010=b'010' 或 SELECT id,name,flag+0, BIN(flag) FROM bit_demo where flag&010=2
# 查詢未送電信渠道數(shù)據(jù) SELECT id,name,flag+0, BIN(flag) FROM bit_demo where flag&010=b'000' 或 SELECT id,name,flag+0, BIN(flag) FROM bit_demo where flag&010=0
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MYSQL 一個巧用字符函數(shù)做數(shù)據(jù)篩選的題
這篇文章主要介紹了MYSQL 一個巧用字符函數(shù)做數(shù)據(jù)篩選的題,需要的朋友可以參考下2017-05-05實(shí)操M(fèi)ySQL+PostgreSQL批量插入更新insertOrUpdate
這篇文章主要介紹了MYsql和PostgreSQL優(yōu)勢對比以及如何實(shí)現(xiàn)MySQL + PostgreSQL批量插入更新insertOrUpdate,附含詳細(xì)的InserOrupdate代碼實(shí)例,需要的朋友可以參考下2021-08-08MySql 字符串中提取數(shù)字的實(shí)現(xiàn)示例
在MySQL中,有時需要從字符串中提取數(shù)字,本文就來介紹一下MySql 字符串中提取數(shù)字的實(shí)現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2023-09-09mysql中整數(shù)數(shù)據(jù)類型tinyint詳解
大家好,本篇文章主要講的是mysql中整數(shù)數(shù)據(jù)類型tinyint詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12MySQL深度分頁(千萬級數(shù)據(jù)量如何快速分頁)
后端開發(fā)中經(jīng)常需要分頁展示,個時候就需要用到MySQL的LIMIT關(guān)鍵字。LIMIT在數(shù)據(jù)量大的時候極可能造成的一個問題就是深度分頁。本文就介紹一下解決方法,感興趣的可以了解一下2021-07-07