<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                &emsp;&emsp;短鏈顧名思義是一種很短的地址,應用廣泛,例如頁面中有一張二維碼圖片,包含的是一個原始地址(如下所示),如果二維碼中的鏈接需要修改,那么就得發代碼替換掉。 * 原始地址:[https://github.com/pwstrick/daily](https://github.com/pwstrick/daily) * 短鏈:http://t.cn/4fYKXF &emsp;&emsp;但如果二維碼圖包含的是一條短鏈,那么只要修改短鏈中的映射關系,就能不發代碼了。當然了,前提是有一套短鏈系統維護著他們之間的關系,下圖15和圖16分別是列表和新增的界面。 :-: ![](https://img.kancloud.cn/96/a7/96a79a41ccc3201527d1ea7d286cbde4_1894x1030.png =800x) 圖 15 :-: ![](https://img.kancloud.cn/a3/fc/a3fc68054b01dd9fef8723b0cdb5b505_1608x526.png =600x) 圖 16 &emsp;&emsp;前端界面的代碼省略了,直接看短鏈用Node.js實現的后端代碼。 ## 一、MySQL &emsp;&emsp;在 web\_short\_chain 表中,主鍵 id 是一個自增的整數,short 字段存儲著短鏈中的 key,也就是 http://t.cn/4fYKXF 中的 4fYKXF 之類的數據,并且是全表唯一的,目前還未對其建索引。 ~~~ CREATE TABLE `web_short_chain` ( `id` int(11) NOT NULL AUTO_INCREMENT, `short` varchar(10) COLLATE utf8mb4_bin NOT NULL COMMENT '短鏈地址中的key', `url` varchar(200) COLLATE utf8mb4_bin NOT NULL COMMENT '原始地址', `ctime` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `mtime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '狀態', PRIMARY KEY (`id`), UNIQUE KEY `short_UNIQUE` (`short`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='短鏈存儲' ~~~ ## 二、計算 short 的值 &emsp;&emsp;需要兩步才能將原始地址映射成短鏈地址,第一步是使用[MurmurHash](https://baike.baidu.com/item/Murmur%E5%93%88%E5%B8%8C/22689658?fr=aladdin)(么么哈希)算法,由Austin Appleby在2008年發明,可將原始地址轉換成一個哈希值,算法如下(最新版本 MurmurHash3)。 ~~~ function MurmurHashV3(key, seed) { if (typeof key === "string") key = createBuffer(key); var remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i; remainder = key.length & 3; // key.length % 4 bytes = key.length - remainder; h1 = seed; c1 = 0xcc9e2d51; c2 = 0x1b873593; i = 0; while (i < bytes) { k1 = (key[i] & 0xff) | ((key[++i] & 0xff) << 8) | ((key[++i] & 0xff) << 16) | ((key[++i] & 0xff) << 24); ++i; k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; k1 = (k1 << 15) | (k1 >>> 17); k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; h1 ^= k1; h1 = (h1 << 13) | (h1 >>> 19); h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff; h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16); } k1 = 0; switch (remainder) { case 3: k1 ^= (key[i + 2] & 0xff) << 16; case 2: k1 ^= (key[i + 1] & 0xff) << 8; case 1: k1 ^= key[i] & 0xff; k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; k1 = (k1 << 15) | (k1 >>> 17); k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; h1 ^= k1; } h1 ^= key.length; h1 ^= h1 >>> 16; h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff; h1 ^= h1 >>> 13; h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff; h1 ^= h1 >>> 16; return h1 >>> 0; } ~~~ &emsp;&emsp;在得到一個整型的哈希值后,就得轉換成字符,像上面短鏈中的字符是 6 個,也就是將10進制轉換成62進制,如下所示。 ~~~ function string10to62(n) { if (n === 0) { return "0"; } var digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; var result = ""; while (n > 0) { result = digits[n % digits.length] + result; n = parseInt(n / digits.length, 10); } return result; } ~~~ ## 三、緩存 &emsp;&emsp;在將映射關系存入數據庫時,可將其直接存入[redis](http://www.redis.cn/)緩存中,采用哈希的數據結構,也就是將計算出的 short 作為 key,原始地址作為 value。 &emsp;&emsp;假設每條關系所占空間是50字節,那么2000W條記錄大概占用 1G左右,為了節省空間,緩存的超時時間會設為 7 天。 &emsp;&emsp;每次在訪問短鏈時,首先從緩存中讀取,若有,就直接跳轉;若無,則查詢數據庫,再將映射關系存入緩存中。 ~~~ //讀取redis let url = await services.common.redisShortChainGet(short); ctx.status = 302; //臨時跳轉 if(url) { ctx.redirect(getCompleteUrl(url, querystring)); return; } //緩存中不存在,則讀取數據庫 const data = await services.common.getOneShortChain({ short }); if(!data) { ctx.body = "短鏈不存在"; return; } //將數據庫中讀取的短鏈緩存起來 await services.common.redisShortChainSet(short, data.url); ctx.redirect(getCompleteUrl(data.url, querystring)); ~~~ &emsp;&emsp;網上的一些文章在判斷短鏈是否存在時,會采用[布隆過濾器](https://baike.baidu.com/item/%E5%B8%83%E9%9A%86%E8%BF%87%E6%BB%A4%E5%99%A8/5384697)。 &emsp;&emsp;它實際上是一個很長的二進制向量和一系列隨機映射函數。布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的算法,長度是 10 億的布隆過濾器,也只需要 125MB左右的內存空間。 &emsp;&emsp;布隆過濾器的缺點是有一定的誤識別率和刪除困難,例如下圖中的 A 和 E 是存在于布隆過濾器中的,它們的映射位置都設成了 1,而 B 并不存在,但它的映射指向了兩個是 1 的位置,從而就造成了誤識別。 :-: ![](https://img.kancloud.cn/b6/26/b626d44780e570f6a074c70eaba0c267_620x618.png =300x) 圖 17 ***** > 原文出處: [博客園-Node.js躬行記](https://www.cnblogs.com/strick/category/1688575.html) [知乎專欄-Node.js躬行記](https://zhuanlan.zhihu.com/pwnode) 已建立一個微信前端交流群,如要進群,請先加微信號freedom20180706或掃描下面的二維碼,請求中需注明“看云加群”,在通過請求后就會把你拉進來。還搜集整理了一套[面試資料](https://github.com/pwstrick/daily),歡迎閱讀。 ![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200) 推薦一款前端監控腳本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不僅能監控前端的錯誤、通信、打印等行為,還能計算各類性能參數,包括 FMP、LCP、FP 等。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看