0%

相信不管是做前端开发还是后端开发的同学,或多或少在开发过程中接触过缓存的概念。最简单的例子就是前端对于静态资源–即css、js、图片等文件资源进行缓存。但是大部分同学知道的可能就是设置Cache-Control: max-age=xxx来设置资源的过期时间,然而缓存的运用在互联网中可谓是无处不在,一个好的缓存方案可以大大提升服务的性能,而一个不好的缓存方案可能会导致网站的可用性降低。所以今天我们就来聊聊HTTP协议中的缓存。

首先HTTP协议中主要涉及缓存的Header就是Cache-ControlExpires,目前阶段来说Expires已经渐渐被淘汰了,所以我们主要讲讲Cache-Control

Cache-Control并不是只有指定max-age过期时间这么一种使用方式,事实上这只是Cache-Control最基础的用法,我们来看看Cache-Control有哪些可以设置的值

  1. private、public和no-cache用来指定客户端和代理缓存的可缓存性
  2. max-age和s-maxage用来指定客户端和代理缓存的缓存时间
  3. must-revalidate和proxy-revalidate用来指定缓存过期后是否必须验证才能使用
  4. no-store用来表明任何地方都不应该缓存内容
  5. 其他一些不常用的设置

首先大家必须要弄清楚的一点是,缓存不仅仅只有浏览器可以缓存,互联网中存在着各式各样的代理缓存。HTTP仅仅是一个应用层的协议,在数据传输的过程中逃不开各种中继的设备,而本身HTTP是明文传输的,所以每个中继设备都可以解析HTTP数据包中的内容,所以如果某个中继设备想,他就可以成为一个代理缓存(想想曾经的某些运行商做的事)。当然HTTP的代理缓存更多还是服务假设者自己做的,但是本质上是一个意思。

那么相对于大家都知道的客户端缓存,代理缓存有什么好处呢?最明显的优势就是:客户端缓存是一对一的,但是代理缓存是一对多的。

从这张图中我们可以看到,对于同一个源服务器可以存在不同的代理(有些CDN就近获取资源就有用到缓存的知识)。如果这些代理都开启来缓存功能,那么用户一在第一次访问数据的时候,代理通过源服务器获取资源返回给用户,并同时缓存来这个请求,这时候用户二再次来请求的时候,就不需要经过源服务器,直接从代理缓存读取就可以来。

所以对于耗时操作而且数据修改不频繁的数据,开启代理缓存对于性能的提升是非常明显的,哪怕你每次缓存的时间只有5秒,对于并发量很高请求带来的性能提升也是不可估量的。

当然这个操作源服务器通过自己设置缓存也可以实现,但是代理缓存的好处是,如果你的代理离用户足够近,那么减少的延时也是非常明显的。比如如果你的服务器在美国纽约,如果你不在国内设置一个代理缓存,那么所有数据都要跨国半个地球再绕回来,而有代理缓存的情况就不一样来。

那么说回来,怎么控制代理缓存的使用?还是靠HTTP协议,在HTTP协议的发展历史中,已经有非常多的实践让协议进行修改和发展,所以目前的缓存方案可以说已经比较完善了。一般来说,代理缓存服务器都会对最新的HTTP协议的标准进行实现,并且适当兼容老得标准,一般不会出现一些魔改实现。所以只要你对HTTP协议的缓存方案充分了解,那么你就可以很好得使用代理服务器的缓存了。

最主要的你需要知道:

  1. 如何控制代理服务是否缓存或者缓存多少时间
  2. 代理缓存时候可以提供过期缓存的内容
  3. 如何进行缓存验证

知道这些之后,配合一个好用的代理缓存,相信能对你的服务带来很大的性能提升。

最后,HTTP协议是所有WEB相关开发的同学都必须要牢牢掌握的基础,仅仅知道POST、GET、Content-Type并不算理解HTTP协议,HTTP协议中还有非常多好玩又好用的内容等着大家去发掘。

错误现象

Sublime Text 3 在安装Package Control的时候会出现类似如下错误:

Sublime Text 3 Package Control ERROR

开启debug时,console里会出现如下提示:

1
2
3
4
5
6
Package Control: Found previously exported CA bundle at /Users/.../Library/Application Support/Sublime Text 3/Packages/User/oscrypto-ca-bundle.crt (272085 bytes)

Package Control: Urllib HTTPS Debug General
Upgrading connection to SSL using CA certs file at /Users/.../Library/Application Support/Sublime Text 3/Packages/User/Package Control.merged-ca-bundle
Using hostname "packagecontrol.io" for TLS SNI extension
Package Control: Error downloading channel. HTTP exception InvalidCertificateException (Host 127.0.0.1:9090 returned an invalid certificate ([SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:548))) downloading https://packagecontrol.io/channel_v3.json.

特别是用了代理的时候。

解决办法

很多Google中找到的办法都不能解决,可以尝试以下的粗暴办法:

  1. 清空 /Users/…/Library/Application Support/Sublime Text 3/Packages/User/oscrypto-ca-bundle.crt
  2. 将console中提示有SSL问题的域名根证书加入到oscrypto-ca-bundle.crt即可

以packagecontrol.io为例,
packagecontrol.io证书信息

channel_v3.json里涉及的相关公钥

GeoTrust Global CA

相关域名
packagecontrol.io
sublimerge.com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----

via: https://www.geotrust.com/resources/root_certificates/certificates/GeoTrust_Global_CA.pem

DigiCert High Assurance EV Root CA

相关域名
codeload.github.com
bitbucket.org
github.com
s3.amazonaws.com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----

via: https://ev-root.chain-demos.digicert.com/info/index.html

DST Root CA X3

相关域名:
packages.monokai.pro
downloads.sourceforge.net
sublime.wbond.net

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

via: https://letsencrypt.org/certificates/

Certum Trusted Network CA

相关域名:
serwer1784570.home.pl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
6GAqm4VKQPNriiTsBhYscw==
-----END CERTIFICATE-----

via: https://www.certum.eu/en/cert_expertise_root_certificates/#CTNCA

MWeb 是一款Mac上专业的Markdown写作、记笔记、静态博客生成软件,是一站式的 Markdown 编辑和静态网站生成解决方案,支持大量 Markdown 扩展语法,很不错!

[MWeb 在 Mac App Store上售价人民币98元]

MWeb for Mac 2.2.4 介绍


  • 「MWeb 获得少数派 2015 年度 Mac App」(http://sspai.com/topic/best-apps-2015/)

  • “ MWeb 是一站式的 Markdown 编辑和静态网站生成解决方案 - Mac玩儿法(www.waerfa.com)”

  • “ MWeb 是一款性价比很高的 Markdown 编辑器,它所能做的事绝对让你物有所值。 - 少数派(sspai.com)”

点这里

第一步:使用npm安装n模块

n模块是专门用来管理nodejs版本的

1
sudo npm install -g n

提示 : 如果不使用sudo作为前缀,很可能出现权限访问异常导致安装失败

第二步:升级nodejs

升级nodejs是有两种方法:
第一种是升级到最新版本

1
sudo n latest

第二种是升级到稳定版本

1
sudo n stable

提示 : 建议是稳定版本
更多n模块管理请搜索【nodejs n模块使用说明】

权限相关的异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
npm ERR! Darwin 16.4.0
npm ERR! argv "/usr/local/Cellar/node/6.4.0/bin/node" "/usr/local/bin/npm" "update" "-g"
npm ERR! node v6.4.0
npm ERR! npm v4.1.2
npm ERR! path /usr/local/lib/node_modules/cnpm/node_modules/agentkeepalive
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall access

npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules/cnpm/node_modules/agentkeepalive'
npm ERR! at Error (native)
npm ERR! { Error: EACCES: permission denied, access '/usr/local/lib/node_modules/cnpm/node_modules/agentkeepalive'
npm ERR! at Error (native)
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'access',
npm ERR! path: '/usr/local/lib/node_modules/cnpm/node_modules/agentkeepalive' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! Please include the following file with any support request:
npm ERR! /Users/
admin/Projects/CoPilot/npm-debug.log

提示 : 解决方案是在命令前加sudo

From: Andreas Stieger andreas.stieger@gmx.de
Date: 2013-01-28 19:18:21 +0000
Subject: [PATCH] fix compiler warning about isatty()
Upstream: sent to lar@quicklz.com

Fix compiler error
qpress.cpp: In function ‘int main(int, char**)’:
qpress.cpp:1039:39: error: ‘isatty’ was not declared in this scope

1
2
3
4
5
6
7
8
9
10
--- a/qpress.cpp	2010-09-23 20:09:26.000000000 +0100
+++ b/qpress.cpp 2013-01-28 19:18:21.000000000 +0000
@@ -89,6 +89,7 @@
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
#include "aio.hpp"
#include <stdarg.h>
#include <string>

via. https://build.opensuse.org/package/view_file/Archiving/qpress/qpress-1.1-isatty-include.patch?expand=1

Aliyun

MongoDB

1
2
3
4
5
[mongodb]
name=MongoDB Repository
baseurl=https://mirrors.aliyun.com/mongodb/yum/redhat/$releasever/mongodb-org/stable/x86_64/
gpgcheck=0
enabled=1

众所周知,目前的mysql版本中并不支持直接的递归查询,但是通过递归到迭代转化的思路,还是可以在一句SQL内实现树的递归查询的。这个得益于Mysql允许在SQL语句内使用@变量。以下是示例代码。

创建表格

1
2
3
4
5
CREATE TABLE `treenodes` (
`id` int , -- 节点ID
`nodename` varchar (60), -- 节点名称
`pid` int -- 节点父ID
);

插入测试数据

1
2
3
4
5
6
7
8
INSERT INTO `treenodes` (`id`, `nodename`, `pid`) VALUES
('1','A','0'),('2','B','1'),('3','C','1'),
('4','D','2'),('5','E','2'),('6','F','3'),
('7','G','6'),('8','H','0'),('9','I','8'),
('10','J','8'),('11','K','8'),('12','L','9'),
('13','M','9'),('14','N','12'),('15','O','12'),
('16','P','15'),('17','Q','15'),('18','R','3'),
('19','S','2'),('20','T','6'),('21','U','8');

查询语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 SELECT id AS ID,pid AS 父ID ,levels AS 父到子之间级数, paths AS 父到子路径 FROM (
SELECT id,pid,
@le:= IF (pid = 0 ,0,
IF( LOCATE( CONCAT('|',pid,':'),@pathlevel) > 0 ,
SUBSTRING_INDEX( SUBSTRING_INDEX(@pathlevel,CONCAT('|',pid,':'),-1),'|',1) +1
,@le+1) ) levels
, @pathlevel:= CONCAT(@pathlevel,'|',id,':', @le ,'|') pathlevel
, @pathnodes:= IF( pid =0,',0',
CONCAT_WS(',',
IF( LOCATE( CONCAT('|',pid,':'),@pathall) > 0 ,
SUBSTRING_INDEX( SUBSTRING_INDEX(@pathall,CONCAT('|',pid,':'),-1),'|',1)
,@pathnodes ) ,pid ) )paths
,@pathall:=CONCAT(@pathall,'|',id,':', @pathnodes ,'|') pathall
FROM treenodes,
(SELECT @le:=0,@pathlevel:='', @pathall:='',@pathnodes:='') vv
ORDER BY pid,id
) src
ORDER BY id;

最后的结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    ID   父ID  父到子之间级数  父到子路径
------ ------ ------------ ---------------
1 0 0 ,0
2 1 1 ,0,1
3 1 1 ,0,1
4 2 2 ,0,1,2
5 2 2 ,0,1,2
6 3 2 ,0,1,3
7 6 3 ,0,1,3,6
8 0 0 ,0
9 8 1 ,0,8
10 8 1 ,0,8
11 8 1 ,0,8
12 9 2 ,0,8,9
13 9 2 ,0,8,9
14 12 3 ,0,8,9,12
15 12 3 ,0,8,9,12
16 15 4 ,0,8,9,12,15
17 15 4 ,0,8,9,12,15
18 3 2 ,0,1,3
19 2 2 ,0,1,2
20 6 3 ,0,1,3,6
21 8 1 ,0,8

via. http://www.cnblogs.com/dukou/p/4691543.html

关于UTF-8

UTF-8 Unicode Transformation Format-8bit。是用以解决国际上字符的一种多字节编码。

它对英文使用8位(即一个字节) ,中文使用24位(三个字节)来编码。
UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。

UTF-8编码的文字可以在各国支持UTF8字符集额的浏览器上显示。 如果是UTF8编码,则在外国人的英文IE也能显示中文,他们无需下载IE的中文语言支持包。

关于GBK

GBK 是国家标准GB2312基础上扩容后兼容GB2312的标准。
GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。
GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大。

关于utf8mb4

MySql 5.5 之前,UTF8 编码只支持1-3个字节,只支持BMP这部分的unicode编码区,BMP是从哪到哪? [戳这里] (http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters)基本就是 0000 ~ FFFF 这一区。

从MySQL 5.5 开始,可支持4个字节UTF编码utf8mb4,一个字符最多能有4字节,所以能支持更多的字符集。

utf8mb4 is a superset of utf8

tf8mb4兼容utf8,且比utf8能表示更多的字符。
至于什么时候用,看你做的什么项目了。。。 在做移动应用时,会遇到IOS用户在文本的区域输入emoji表情,如果不做一定处理,就会导致插入数据库异常。

汉字长度与编码有关

MySql 5.0 以上的版本:

  1. 一个汉字占多少长度与编码有关:
编码 一个汉字 一个英文
UTF-8 3字节 1字节
GBK 2字节 1字节
  1. varchar(n) 表示n个字符,无论汉字和英文,MySql都能存入 n 个字符,仅实际字节长度有所区别。

  2. MySQL检查长度,可用SQL语言

    1
    SELECT LENGTH(fieldname) FROM tablename

实际测试

首先使用utf8

创建 str_test 表。

1
2
3
4
CREATE TABLE `str_test` (
`name_chn` varchar(20) NOT NULL,
`name_en` varchar(20) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

然后插入值

1
2
mysql> insert into  str_test values ('我爱Ruby', 'I Love Ruby!');
Query OK, 1 row affected (0.02 sec)

打开irb

1
2
3
4
5
>> "我爱Ruby".size
=> 6
>> "I Love Ruby!".size
=> 12
>>

从MySQL中查询出来的结果,对比

1
2
3
4
5
6
7
mysql> select * from str_test;
+------------+--------------+
| name_chn | name_en |
+------------+--------------+
| 我爱Ruby | I Love Ruby! |
+------------+--------------+
1 row in set (0.02 sec)

UTF-8 中文是三个字节,英文是一个字节。

1
2
3
4
5
6
7
mysql> select length(name_chn) from str_test;
+------------------+
| length(name_chn) |
+------------------+
| 10 |
+------------------+
1 row in set (0.01 sec)

3[一个汉字三字节] * 2 + 1[一个英文一字节] * 4 = 10

1
2
3
4
5
6
7
mysql> select length(name_en) from str_test;
+-----------------+
| length(name_en) |
+-----------------+
| 12 |
+-----------------+
1 row in set (0.00 sec)

1[一个英文一字节] * 10 + 1[空格一字节] * 2 = 12

使用 GBK 做测试

创建表

1
2
3
4
CREATE TABLE `str_test` (
`name_chn` varchar(20) NOT NULL,
`name_en` varchar(20) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=62974 DEFAULT CHARSET=gbk

插入数据,并且测试

1
2
mysql> insert into  str_test values ('我爱Ruby', 'I Love Ruby!');
Query OK, 1 row affected (0.00 sec)
1
2
3
4
5
6
7
mysql> select * from str_test;
+------------+--------------+
| name_chn | name_en |
+------------+--------------+
| 我爱Ruby | I Love Ruby! |
+------------+--------------+
1 row in set (0.01 sec)

GBK 中文是两个字节,英文是一个字节。

1
2
3
4
5
6
7
mysql> select length(name_chn) from str_test;
+------------------+
| length(name_chn) |
+------------------+
| 8 |
+------------------+
1 row in set (0.00 sec)

2[中文两个字节] * 2 + 1[英文一个字节] * 4 = 8

1
2
3
4
5
6
7
mysql> select length(name_en) from str_test;
+-----------------+
| length(name_en) |
+-----------------+
| 12 |
+-----------------+
1 row in set (0.00 sec)

1[英文一个字节] * 10 + 1[空格一个字节] * 2 = 12

关于varchar 最多能存多少值

mysql的记录行长度是有限制的,不是无限长的,这个长度是64K,即65535个字节,对所有的表都是一样的。
MySQL对于变长类型的字段会有1-2个字节来保存字符长度。
当字符数小于等于255时,MySQL只用1个字节来记录,因为2的8次方减1只能存到255。
当字符数多余255时,就得用2个字节来存长度了。
在utf-8状态下的varchar,最大只能到 (65535 - 2) / 3 = 21844 余 1。
在gbk状态下的varchar, 最大只能到 (65535 - 2) / 2 = 32766 余 1

使用 utf-8 创建

1
2
3
4
5
mysql> CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(21845) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

使用gbk创建

1
2
3
4
5
mysql>     CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(21844) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.06 sec)

当存储长度为 32768 失败~

1
2
3
4
5
mysql> CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(32768) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;
ERROR 1074 (42000): Column length too big for column 'name_chn' (max = 32767); use BLOB or TEXT instead

当存储长度为 32767 失败~

1
2
3
4
5
mysql> CREATE TABLE `str_test`(
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(32767) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

当存储长度为 32766 成功~

1
2
3
4
5
mysql> CREATE TABLE `str_test` (
-> `id` tinyint(1) NOT NULL,
-> `name_chn` varchar(32766) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;
Query OK, 0 rows affected (0.03 sec)

smallint 用两个字节存储,所以

2[smallint] + 32766 * 2[varchar GBK存储长度] + 2[2个字节来存长度] > 65535

所以失败~

1
2
3
4
5
mysql> CREATE TABLE `str_test` (
-> `id` smallint(1) NOT NULL,
-> `name_chn` varchar(32766) NOT NULL
-> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

数值类型所占的字节

类型 所占字节
int 4 字节
smallint 2 字节
tinyint 1 字节
decimal 变长

官方关于decimal 的描述如下:

Values for DECIMAL (and NUMERIC) columns are represented using a binary format that packs nine decimal (base 10) digits into four bytes.
Storage for the integer and fractional parts of each value are determined separately.
Each multiple of nine digits requires four bytes, and the “leftover” digits require some fraction of four bytes.
The storage required for excess digits is given by the following table.

翻译为中文

使用二进制格式将9个十进制(基于10)数压缩为4个字节来表示DECIMAL列值。
每个值的整数和分数部分的存储分别确定。
每个9位数的倍数需要4个字节,并且“剩余的”位需要4个字节的一部分。
下表给出了超出位数的存储需求:

> Leftover Digits Number Of Bytes
0 0
1 1
2 1
3 2
4 2
5 3
6 3
7 4
8 4

那:decimal(10,2)占几个字节?

  1. 首先 10 指的是整数与小数部分的总长度, 2指的是小数部分的长度。那么整数部分就只有 10 - 2 = 8 位
  2. 因为整数与小数的存储市各自独立确定的,所以他们各自所占用空间的综合就是所占的总空间了。
  3. 对表可知,整数部分8位占了4个字节,小数部分2位占了1个字节,所以decimal(10,2)总共占了 4 + 1 = 5 个字节。
  4. decimal(6,2) 整数部分(6 - 2 = 4) 位占2字节,小数部分2位占1字节,总共占3字节。

总结

varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节),因此最大长度不能超过65535。

在utf-8状态下,汉字最多可以存 21844个字符串, 英文也为 21844个字符串。

在gbk状态下,汉字最多可以存 32766个字符串,英文也为 32766个字符串。

参考

mysql utf8mb4与emoji表情
关于GBK、GB2312、UTF8
阿里云 Rails 项目调整 RDS MySQL 编码为 utf8mb4 的详细步骤
MySQL下varchar类型最大长度是多少

via. https://ruby-china.org/topics/24920

无法打开新数据库 ‘Dong’。CREATE DATABASE 中止。
文件激活失败。物理文件名称’E:\SqlServer\MSSQL\Data\Dong_log.LDF’可能不正确。

无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。如果事务日志文件被手动删除或者由于硬件或环境问题而丢失,则可能出现此错误。 (Microsoft SQL Server,错误: 1813)

解决方案:

  1. 新建一个同名数据库。

  2. 停止数据库服务,覆盖新建的数据库主文件(小技巧:最好放在同一个磁盘里面,把新建的数据库主文件删掉或移开,再把要恢复的数据库主文件剪切过去,这样就可以节省时间。)

  3. 启动数据库服务,数据库变为置疑或可疑状态。然后在查询分析器中运行:

    1
    alter database 无日志文件的数据库名称 set emergency

    设置为紧急状态。

  4. 再运行:

    1
    alter database 无日志文件的数据库名称 set single_user

    或者:

    1
    Sp_dboption '无日志文件的数据库名称', 'single user', 'true'

    设置为单用户模式。

  5. 检查并重建日志文件,运行:

    1
    dbcc checkdb('无日志文件的数据库名称',REPAIR_ALLOW_DATA_LOSS)

    这个时间比较长。耐心等待!如果有错误提示,再运行:

    1
    dbcc checkdb('无日志文件的数据库名称',REPAIR_REBUILD)

    进行修复。如果没有错误,可以跳过。

  6. 恢复成多用户模式

    1
    alter database 无日志文件的数据库名称 set multi_user

    或者:

    1
    Sp_dboption '无日志文件的数据库名称', 'single user', 'false'

    刷新数据库,你就可以看到已经修复好的数据库了。

via. http://www.cnblogs.com/lyl6796910/p/3628066.html

浏览器默认下载器下载百度云的文件速度大多不理想,非客户端下载限速,大文件下载中途失败,让人体验非常不友好。Windows 平台独享百度云管家下载工具,大文件的上下传速度都比较理想,Mac 平台的同步盘功能少,体验差,直到配合下载工具 aria2 下载速度和大文件下载才有所改善。下面是几步简单的教程。

安装

请首先自行安装 Homebrew。Homebrew 安装 aria2

1
brew install aria2

配置

参照以下配置新建 aria2.conf 配置文件,自行设定配置文件路径。

必须要修改的地方有两处:

  1. 下载文件保存路径。用户名填写本机当前用户名。
  2. 最后一行。如果是 SSD 则不用改,如果是传统硬盘,就改成 file-allocation=prealloc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#允许rpc
enable-rpc=true
#允许非外部访问
rpc-listen-all=true
#RPC端口, 仅当默认端口被占用时修改
rpc-listen-port=6800

#最大同时下载数(任务数), 路由建议值: 3
max-concurrent-downloads=10
#断点续传
continue=true
#同服务器连接数
max-connection-per-server=10
#最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要
min-split-size=10M
#单文件最大线程数, 路由建议值: 5
split=10
#下载速度限制
max-overall-download-limit=0
#单文件速度限制
max-download-limit=0
#上传速度限制
max-overall-upload-limit=0
#单文件速度限制
max-upload-limit=0

#文件保存路径, 默认为当前启动位置
dir=/Users/用户名/Downloads

#允许所有来源, web界面跨域权限需要
rpc-allow-origin-all=true

#文件预分配, 能有效降低文件碎片, 提高磁盘性能. 缺点是预分配时间较长
#所需时间 none < falloc ? trunc << prealloc, falloc和trunc需要文件系统和内核支持
# !!仅针对传统磁盘,SSD 降低文件碎片并不是什么好事。
file-allocation=none

打开终端,执行以下命令:

1
echo "alias aria2rpc='aria2c --conf-path=/Users/用户名/.../aria2.conf -D'" >> ~/.bash_profile

记得替换你设置的配置文件 aria2.conf 的路径。

最后执行:

1
source ~/.bash_profile

运行

Terminal 执行命名运行 aria2:

1
aria2rpc

每次开机均执行一次即可。

使用
aria2 是一个命令行工具,为了方便,有几种图形界面工具可以配合使用:

  1. 网页 YAAW
    打开网页 Yet Another Aria2 Web Frontend
    点右上角的扳手按钮,修改 JSON-RPC Path 内容为 http://127.0.0.1:6800/jsonrpc

  2. GUI 客户端
    下载 aria2gui
    默认 JSON-RPC 为 http://localhost:6800/jsonrpc,不需要修改。

使用时按 +Add+添加 按钮,输入 HTTP、FTP 或 Magnet 进行下载。

如果嫌每次复制粘贴链接麻烦,浏览器有 百度网盘助手 插件,可以在百度云网页生成 导出下载 按钮,点击 ARIA2 RPC 即可自动在打开的 YAAW 网页或 GUI 客户端上进行下载。

Chrome 插件
Firefox 插件

原文链接:http://www.jianshu.com/p/33b0a9504a04