Redis では、set や getbit などのコマンドがよく使用されます。注意してください。setbit や getbit という類似したコマンドがいくつかあることに気づきましたか? これらは何に使用されますか?
BitMapとは
ビットを使って要素に対応する値や状態を表し、キーは対応する要素そのものです。 8 ビットでバイトを形成できることがわかっているため、ビットマップ自体によりストレージ スペースが大幅に節約されます。
Redis の BitMap
Redis は、バージョン 2.2.0 以降、 setbit
、getbit
、bitcount
などのビットマップ関連のコマンドをいくつか追加しました。これは新しいコマンドですが、setbit
などのコマンドは set
の単なる拡張であるため、新しいデータ型は追加されません。 setbit
,getbit
,bitcount
等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit
等命令只不过是在set
上的扩展。
setbit命令介绍
指令 SETBIT key offset value
复杂度 O(1)
设置或者清空key的value(字符串)在offset处的bit值(只能只0或者1)。
空间占用、以及第一次分配空间需要的时间
在一台2010MacBook Pro上,offset为2^32-1(分配512MB)需要~300ms,offset为2^30-1(分配128MB)需要~80ms,offset为2^28-1(分配32MB)需要~30ms,offset为2^26-1(分配8MB)需要8ms。
大概的空间占用计算公式是:($offset/8/1024/1024)MB
使用场景一:用户签到
很多网站都提供了签到功能(这里不考虑数据落地事宜),并且需要展示最近一个月的签到情况,如果使用bitmap我们怎么做?一言不合亮代码!
<?php $redis = new Redis(); $redis->connect('127.0.0.1'); //用户uid $uid = 1; //记录有uid的key $cacheKey = sprintf("sign_%d", $uid); //开始有签到功能的日期 $startDate = '2017-01-01'; //今天的日期 $todayDate = '2017-01-21'; //计算offset $startTime = strtotime($startDate); $todayTime = strtotime($todayDate); $offset = floor(($todayTime - $startTime) / 86400); echo "今天是第{$offset}天" . PHP_EOL; //签到 //一年一个用户会占用多少空间呢?大约365/8=45.625个字节,好小,有木有被惊呆? $redis->setBit($cacheKey, $offset, 1); //查询签到情况 $bitStatus = $redis->getBit($cacheKey, $offset); echo 1 == $bitStatus ? '今天已经签到啦' : '还没有签到呢'; echo PHP_EOL; //计算总签到次数 echo $redis->bitCount($cacheKey) . PHP_EOL; /** * 计算某段时间内的签到次数 * 很不幸啊,bitCount虽然提供了start和end参数,但是这个说的是字符串的位置,而不是对应"位"的位置 * 幸运的是我们可以通过get命令将value取出来,自己解析。并且这个value不会太大,上面计算过一年一个用户只需要45个字节 * 给我们的网站定一个小目标,运行30年,那么一共需要1.31KB(就问你屌不屌?) */ //这是个错误的计算方式 echo $redis->bitCount($cacheKey, 0, 20) . PHP_EOL;
使用场景二:统计活跃用户
使用时间作为cacheKey,然后用户ID为offset,如果当日活跃过就设置为1
那么我该如果计算某几天/月/年的活跃用户呢(暂且约定,统计时间内只有有一天在线就称为活跃),有请下一个redis的命令
命令 BITOP operation destkey key [key ...]
说明:对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
说明:BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种参数
//日期对应的活跃用户 $data = array( '2017-01-10' => array(1,2,3,4,5,6,7,8,9,10), '2017-01-11' => array(1,2,3,4,5,6,7,8), '2017-01-12' => array(1,2,3,4,5,6), '2017-01-13' => array(1,2,3,4), '2017-01-14' => array(1,2) ); //批量设置活跃状态 foreach($data as $date=>$uids) { $cacheKey = sprintf("stat_%s", $date); foreach($uids as $uid) { $redis->setBit($cacheKey, $uid, 1); } } $redis->bitOp('AND', 'stat', 'stat_2017-01-10', 'stat_2017-01-11', 'stat_2017-01-12') . PHP_EOL; //总活跃用户:6 echo "总活跃用户:" . $redis->bitCount('stat') . PHP_EOL; $redis->bitOp('AND', 'stat1', 'stat_2017-01-10', 'stat_2017-01-11', 'stat_2017-01-14') . PHP_EOL; //总活跃用户:2 echo "总活跃用户:" . $redis->bitCount('stat1') . PHP_EOL; $redis->bitOp('AND', 'stat2', 'stat_2017-01-10', 'stat_2017-01-11') . PHP_EOL; //总活跃用户:8 echo "总活跃用户:" . $redis->bitCount('stat2') . PHP_EOL;
假设当前站点有5000W用户,那么一天的数据大约为50000000/8/1024/1024=6MB
使用场景三:用户在线状态
前段时间开发一个项目,对方给我提供了一个查询当前用户是否在线的接口。不了解对方是怎么做的,自己考虑了一下,使用bitmap是一个节约空间效率又高的一种方法,只需要一个key,然后用户ID为offset,如果在线就设置为1,不在线就设置为0,和上面的场景一样,5000W用户只需要6MB的空间。
//批量设置在线状态 $uids = range(1, 500000); foreach($uids as $uid) { $redis->setBit('online', $uid, $uid % 2); } //一个一个获取状态 $uids = range(1, 500000); $startTime = microtime(true); foreach($uids as $uid) { echo $redis->getBit('online', $uid) . PHP_EOL; } $endTime = microtime(true); //在我的电脑上,获取50W个用户的状态需要25秒 echo "total:" . ($endTime - $startTime) . "s"; /** * 对于批量的获取,上面是一种效率低的办法,实际可以通过get获取到value,然后自己计算 * 具体计算方法改天再写吧,之前写的代码找不见了。。。 */
其实BitMap可以运用的场景很多很多(当然也会受到一些限制),思维可以继续扩散~欢迎小伙伴给我留言探讨~
在Redis中我们经常用到set,get等命令,细心的你有没有发现,还有几个相似的命令叫setbit,getbit,它们是用来干嘛的?
BitMap是什么
就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。
Redis中的BitMap
Redis从2.2.0版本开始新增了setbit
,getbit
,bitcount
等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit
等命令只不过是在set
上的扩展。
setbit命令介绍
指令 SETBIT key offset value
复杂度 O(1)
设置或者清空key的value(字符串)在offset处的bit值(只能只0或者1)。
空间占用、以及第一次分配空间需要的时间
在一台2010MacBook Pro上,offset为2^32-1(分配512MB)需要~300ms,offset为2^30-1(分配128MB)需要~80ms,offset为2^28-1(分配32MB)需要~30ms,offset为2^26-1(分配8MB)需要8ms。
大概的空间占用计算公式是:($offset/8/1024/1024)MB
SETBITキーオフセット値
複雑度
O(1)
キー(文字列)の値を設定またはクリアしますオフセットのビット値 (0 または 1 のみ)。 スペース占有と初めてスペースを割り当てるのに必要な時間🎜🎜 2010 MacBook Pro では、オフセット 2^32-1 (512MB 割り当て) の場合は ~300ms、オフセット 2^30 の場合は ~300ms かかります。 -1 (128MB 割り当て) ~ 80 ミリ秒、オフセットが 2^28-1 (32MB 割り当て) の場合は ~ 30 ミリ秒、オフセットが 2^26-1 (8MB 割り当て) の場合は 8 ミリ秒かかります。
おおよそのスペース占有計算式は次のとおりです:
($offset/8/1024/1024)MB
🎜🎜使用シナリオ 1: ユーザーのサインイン🎜🎜多くの Web サイトチェックイン機能が提供されています(ここではデータの実装は考慮されていません)。ビットマップを使用する場合、過去 1 か月のチェックイン状況を表示する必要があります。暗号は一言で判明! 🎜<?php $redis = new Redis(); $redis->connect('127.0.0.1'); //用户uid $uid = 1; //记录有uid的key $cacheKey = sprintf("sign_%d", $uid); //开始有签到功能的日期 $startDate = '2017-01-01'; //今天的日期 $todayDate = '2017-01-21'; //计算offset $startTime = strtotime($startDate); $todayTime = strtotime($todayDate); $offset = floor(($todayTime - $startTime) / 86400); echo "今天是第{$offset}天" . PHP_EOL; //签到 //一年一个用户会占用多少空间呢?大约365/8=45.625个字节,好小,有木有被惊呆? $redis->setBit($cacheKey, $offset, 1); //查询签到情况 $bitStatus = $redis->getBit($cacheKey, $offset); echo 1 == $bitStatus ? '今天已经签到啦' : '还没有签到呢'; echo PHP_EOL; //计算总签到次数 echo $redis->bitCount($cacheKey) . PHP_EOL; /** * 计算某段时间内的签到次数 * 很不幸啊,bitCount虽然提供了start和end参数,但是这个说的是字符串的位置,而不是对应"位"的位置 * 幸运的是我们可以通过get命令将value取出来,自己解析。并且这个value不会太大,上面计算过一年一个用户只需要45个字节 * 给我们的网站定一个小目标,运行30年,那么一共需要1.31KB(就问你屌不屌?) */ //这是个错误的计算方式 echo $redis->bitCount($cacheKey, 0, 20) . PHP_EOL;🎜使用シナリオ 2: アクティブ ユーザーをカウントします🎜🎜時間をキャッシュキーとして使用し、その日にアクティブな場合はユーザー ID をオフセットします
特定の日/月のアクティブ ユーザーをどのように計算すればよいですか。 /years? (当面は、統計期間内の 1 日のオンライン時間のみがアクティブと呼ばれることに同意します) 次の redis コマンド
Command
BITOP 操作 destkey key [key .. .]
説明: バイナリ ビットを格納する 1 つ以上の文字列キーに対してビット操作を実行し、結果を destkey に保存します。
注: BITOP コマンドは、AND、OR、NOT、および 6MB の 4 つの操作の任意のパラメーターをサポートします🎜🎜使用シナリオ 3: ユーザーのオンライン ステータス🎜🎜 しばらく前にプロジェクトを開発し、相手が私に提供したもの現在のユーザーがオンラインかどうかを問い合わせるインターフェイス。相手がどうやっているのか分からないので、自分で考えたのですが、ビットマップを使うのが省スペースで効率的ですし、オンラインであればユーザーIDもオフセットされます。は 1 に設定され、オンラインでない場合は 1.0 に設定されます。上記のシナリオと同様に、5000W ユーザーには 6MB のスペースのみが必要です。 🎜
//日期对应的活跃用户 $data = array( '2017-01-10' => array(1,2,3,4,5,6,7,8,9,10), '2017-01-11' => array(1,2,3,4,5,6,7,8), '2017-01-12' => array(1,2,3,4,5,6), '2017-01-13' => array(1,2,3,4), '2017-01-14' => array(1,2) ); //批量设置活跃状态 foreach($data as $date=>$uids) { $cacheKey = sprintf("stat_%s", $date); foreach($uids as $uid) { $redis->setBit($cacheKey, $uid, 1); } } $redis->bitOp('AND', 'stat', 'stat_2017-01-10', 'stat_2017-01-11', 'stat_2017-01-12') . PHP_EOL; //总活跃用户:6 echo "总活跃用户:" . $redis->bitCount('stat') . PHP_EOL; $redis->bitOp('AND', 'stat1', 'stat_2017-01-10', 'stat_2017-01-11', 'stat_2017-01-14') . PHP_EOL; //总活跃用户:2 echo "总活跃用户:" . $redis->bitCount('stat1') . PHP_EOL; $redis->bitOp('AND', 'stat2', 'stat_2017-01-10', 'stat_2017-01-11') . PHP_EOL; //总活跃用户:8 echo "总活跃用户:" . $redis->bitCount('stat2') . PHP_EOL;🎜実際、BitMap は多くのシナリオで使用でき (もちろん、いくつかの制限はありますが)、アイデアは広がり続けることができます~友達は私にメッセージを残して議論することを歓迎します~🎜🎜Redis では、set、get などのコマンドがよく使用されます。注意していれば、いくつかのコマンドがあることに気づきましたか? setbit と getbit という同様のコマンドです。これは何に使用されますか? 🎜🎜BitMap🎜🎜🎜🎜とは、要素に対応する値や状態をビットで表現するもので、キーは対応する要素そのものです。 8 ビットでバイトを形成できることがわかっているため、ビットマップ自体によりストレージ スペースが大幅に節約されます。 🎜🎜Redis の BitMap🎜🎜Redis は、バージョン 2.2.0 以降、
setbit
、getbit
、bitcount
などのビットマップ関連のコマンドをいくつか追加しました。これは新しいコマンドですが、setbit
などのコマンドは set
の単なる拡張であるため、新しいデータ型は追加されません。 🎜🎜setbitコマンド紹介🎜🎜 コマンド SETBITキーオフセット値
複雑度
O(1)
キー(文字列)の値を設定またはクリアしますオフセットのビット値 (0 または 1 のみ)。 🎜🎜スペース占有と初めてスペースを割り当てるのに必要な時間🎜🎜 2010 MacBook Pro では、オフセット 2^32-1 (512MB 割り当て) の場合は ~300ms、オフセット 2^30 の場合は ~300ms かかります。 -1 (128MB 割り当て) ~ 80 ミリ秒、オフセットが 2^28-1 (32MB 割り当て) の場合は ~ 30 ミリ秒、オフセットが 2^26-1 (8MB 割り当て) の場合は 8 ミリ秒かかります。
おおよそのスペース占有計算式は次のとおりです:
($offset/8/1024/1024)MB
🎜🎜使用シナリオ 1: ユーザーのサインイン🎜🎜多くの Web サイトチェックイン機能が提供されています(ここではデータの実装は考慮されていません)。ビットマップを使用する場合、過去 1 か月のチェックイン状況を表示する必要があります。暗号は一言で判明! 🎜<?php $redis = new Redis(); $redis->connect('127.0.0.1'); //用户uid $uid = 1; //记录有uid的key $cacheKey = sprintf("sign_%d", $uid); //开始有签到功能的日期 $startDate = '2017-01-01'; //今天的日期 $todayDate = '2017-01-21'; //计算offset $startTime = strtotime($startDate); $todayTime = strtotime($todayDate); $offset = floor(($todayTime - $startTime) / 86400); echo "今天是第{$offset}天" . PHP_EOL; //签到 //一年一个用户会占用多少空间呢?大约365/8=45.625个字节,好小,有木有被惊呆? $redis->setBit($cacheKey, $offset, 1); //查询签到情况 $bitStatus = $redis->getBit($cacheKey, $offset); echo 1 == $bitStatus ? '今天已经签到啦' : '还没有签到呢'; echo PHP_EOL; //计算总签到次数 echo $redis->bitCount($cacheKey) . PHP_EOL; /** * 计算某段时间内的签到次数 * 很不幸啊,bitCount虽然提供了start和end参数,但是这个说的是字符串的位置,而不是对应"位"的位置 * 幸运的是我们可以通过get命令将value取出来,自己解析。并且这个value不会太大,上面计算过一年一个用户只需要45个字节 * 给我们的网站定一个小目标,运行30年,那么一共需要1.31KB(就问你屌不屌?) */ //这是个错误的计算方式 echo $redis->bitCount($cacheKey, 0, 20) . PHP_EOL;
使用シナリオ 2: アクティブ ユーザーをカウントします
時間をキャッシュキーとして使用し、ユーザー ID がオフセットされます。その日にアクティブな場合は、1 に設定します
それでは、特定の日/月/年 (暫定) のアクティブ ユーザーを計算するにはどうすればよいですか?同意)、統計期間内のオンラインの 1 日のみがアクティブと呼ばれます)、次の redis コマンドを実行してください
コマンドBITOP operation destkey key [key ...]
説明: バイナリ ビットを格納する 1 つ以上の文字列キーに対してビット操作を実行し、結果を上位の destkey に保存します。
注: BITOP コマンドは、AND、OR、NOT、および使用シナリオ 3 の 4 つの操作の任意のパラメーターをサポートします: ユーザーのオンライン ステータス
私は少し前にプロジェクトを開発しましたが、相手は、現在のユーザーはオンラインです。相手がどうやっているのか分からないので、自分で考えたのですが、ビットマップを使うのが省スペースで効率的ですし、オンラインであればユーザーIDもオフセットされます。は 1 に設定され、オンラインでない場合は 1.0 に設定されます。上記のシナリオと同様に、5000W ユーザーには 6MB のスペースのみが必要です。
//日期对应的活跃用户 $data = array( '2017-01-10' => array(1,2,3,4,5,6,7,8,9,10), '2017-01-11' => array(1,2,3,4,5,6,7,8), '2017-01-12' => array(1,2,3,4,5,6), '2017-01-13' => array(1,2,3,4), '2017-01-14' => array(1,2) ); //批量设置活跃状态 foreach($data as $date=>$uids) { $cacheKey = sprintf("stat_%s", $date); foreach($uids as $uid) { $redis->setBit($cacheKey, $uid, 1); } } $redis->bitOp('AND', 'stat', 'stat_2017-01-10', 'stat_2017-01-11', 'stat_2017-01-12') . PHP_EOL; //总活跃用户:6 echo "总活跃用户:" . $redis->bitCount('stat') . PHP_EOL; $redis->bitOp('AND', 'stat1', 'stat_2017-01-10', 'stat_2017-01-11', 'stat_2017-01-14') . PHP_EOL; //总活跃用户:2 echo "总活跃用户:" . $redis->bitCount('stat1') . PHP_EOL; $redis->bitOp('AND', 'stat2', 'stat_2017-01-10', 'stat_2017-01-11') . PHP_EOL; //总活跃用户:8 echo "总活跃用户:" . $redis->bitCount('stat2') . PHP_EOL;
実際、BitMap は多くのシナリオで使用でき (もちろん、いくつかの制限はありますが)、アイデアは広がり続けることができます~友達は私にメッセージを残して議論することを歓迎します~
もっと素晴らしい用途のためにRedis のビットマップについては、PHP 中国語 Web サイトの関連記事に注目してください。

まだ人気があるのは、使いやすさ、柔軟性、強力なエコシステムです。 1)使いやすさとシンプルな構文により、初心者にとって最初の選択肢になります。 2)Web開発、HTTP要求とデータベースとの優れた相互作用と密接に統合されています。 3)巨大なエコシステムは、豊富なツールとライブラリを提供します。 4)アクティブなコミュニティとオープンソースの性質は、それらを新しいニーズとテクノロジーの傾向に適応させます。

PHPとPythonはどちらも、Web開発、データ処理、自動化タスクで広く使用されている高レベルのプログラミング言語です。 1.PHPは、ダイナミックウェブサイトとコンテンツ管理システムの構築によく使用されますが、PythonはWebフレームワークとデータサイエンスの構築に使用されることがよくあります。 2.PHPはエコーを使用してコンテンツを出力し、Pythonは印刷を使用します。 3.両方ともオブジェクト指向プログラミングをサポートしますが、構文とキーワードは異なります。 4。PHPは弱いタイプの変換をサポートしますが、Pythonはより厳しくなります。 5. PHPパフォーマンスの最適化には、Opcacheおよび非同期プログラミングの使用が含まれますが、PythonはCprofileおよび非同期プログラミングを使用します。

PHPは主に手順プログラミングですが、オブジェクト指向プログラミング(OOP)もサポートしています。 Pythonは、OOP、機能、手続き上のプログラミングなど、さまざまなパラダイムをサポートしています。 PHPはWeb開発に適しており、Pythonはデータ分析や機械学習などのさまざまなアプリケーションに適しています。

PHPは1994年に発信され、Rasmuslerdorfによって開発されました。もともとはウェブサイトの訪問者を追跡するために使用され、サーバー側のスクリプト言語に徐々に進化し、Web開発で広く使用されていました。 Pythonは、1980年代後半にGuidovan Rossumによって開発され、1991年に最初にリリースされました。コードの読みやすさとシンプルさを強調し、科学的コンピューティング、データ分析、その他の分野に適しています。

PHPはWeb開発と迅速なプロトタイピングに適しており、Pythonはデータサイエンスと機械学習に適しています。 1.PHPは、単純な構文と迅速な開発に適した動的なWeb開発に使用されます。 2。Pythonには簡潔な構文があり、複数のフィールドに適しており、強力なライブラリエコシステムがあります。

PHPは、多数のWebサイトとアプリケーションをサポートし、フレームワークを通じて開発ニーズに適応するため、近代化プロセスで依然として重要です。 1.PHP7はパフォーマンスを向上させ、新機能を紹介します。 2。Laravel、Symfony、Codeigniterなどの最新のフレームワークは、開発を簡素化し、コードの品質を向上させます。 3.パフォーマンスの最適化とベストプラクティスは、アプリケーションの効率をさらに改善します。

phphassiblasifly-impactedwebdevevermentandsbeyondit.1)itpowersmajorplatformslikewordpratsandexcelsindatabase interactions.2)php'sadaptableability allowsitale forlargeapplicationsusingframeworkslikelavel.3)

PHPタイプは、コードの品質と読みやすさを向上させるためのプロンプトがあります。 1)スカラータイプのヒント:php7.0であるため、基本データ型は、int、floatなどの関数パラメーターで指定できます。 3)ユニオンタイプのプロンプト:PHP8.0であるため、関数パラメーターまたは戻り値で複数のタイプを指定することができます。 4)Nullable Typeプロンプト:null値を含めることができ、null値を返す可能性のある機能を処理できます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 中国語版
中国語版、とても使いやすい

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール
