第一百零四期:搞清这些陷阱,NULL和三值逻辑再也不作妖

NULL 用于表示缺失的值或遗漏的未知数据,不是某种具体类型的值。数据表中的 NULL 值表示该值所处的字段为空,值为 NULL 的字段没有值,尤其要明白的是:NULL 值与 0 或者空字符串是不同的。

作者:youzhibing2904

 

NULL

NULL 用于表示缺失的值或遗漏的未知数据,不是某种具体类型的值。数据表中的 NULL 值表示该值所处的字段为空,值为 NULL 的字段没有值,尤其要明白的是:NULL 值与 0 或者空字符串是不同的。

两种NULL

这种说法大家可能会觉得很奇怪,因为 SQL 里只存在一种 NULL 。然而在讨论 NULL 时,我们一般都会将它分成两种类型来思考:“未知”(unknown)和“不适用”(not applicable,inapplicable)。

以“不知道戴墨镜的人眼睛是什么颜色”这种情况为例,这个人的眼睛肯定是有颜色的,但是如果他不摘掉眼镜,别人就不知道他的眼睛是什么颜色。这就叫作未知。

而“不知道冰箱的眼睛是什么颜色”则属于“不适用”。因为冰箱根本就没有眼睛,所以“眼睛的颜色”这一属性并不适用于冰箱。“冰箱的眼睛的颜色”这种说法和“圆的体积”“男性的分娩次数”一样,都是没有意义的。

平时,我们习惯了说“不知道”,但是“不知道”也分很多种。“不适用”这种情况下的 NULL ,在语义上更接近于“无意义”,而不是“不确定”。

这里总结一下:“未知”指的是“虽然现在不知道,但加上某些条件后就可以知道”;而“不适用”指的是“无论怎么努力都无法知道”。

关系模型的发明者 E.F. Codd 最先给出了这种分类。下图是他对“丢失的信息”的分类。

“IS NULL”而非“= NULL”?

为什么必须写成“IS NULL”,而不是“= NULL”?我相信不少人有这样的困惑吧,尤其是相信刚学 SQL 的小伙伴。我们来看个具体的案例,假设我们有如下表以及数据:

DROP TABLE IF EXISTS t_sample_null; 
CREATE TABLE t_sample_null ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', name VARCHAR(50) NOT NULL COMMENT '名称', remark VARCHAR(500) COMMENT '备注', primary key(id) 
) COMMENT 'NULL样例'; INSERT INTO t_sample_null(name, remark) 
VALUES('zhangsan', '张三'),('李四', NULL); 

我们要查询备注为 NULL 的记录(为 NULL 这种叫法本身是不对的,只是我们日常中已经叫习惯了,具体往下看),怎么查,很多新手会写出这样的 SQL:

- SQL 不报错,但查不出结果 
SELECT * FROM t_sample_null WHERE remark = NULL; 

执行时不报错,但是查不出我们想要的结果, 这是为什么 ?这个问题我们先放着,我们往下看。

三值逻辑

这个三值逻辑不是三目运算,指的是三个逻辑值,有人可能有疑问了,逻辑值不是只有真(true)和假(false)吗,哪来的第三个?

说这话时我们需要注意所处的环境,在主流的编程语言中(C、JAVA、Python、JS等)中,逻辑值确实只有 2 个,但在 SQL 中却存在第三个逻辑值:unknown。这有点类似于我们平时所说的:对、错、不知道。

逻辑值 unknown 和作为 NULL 的一种的 UNKNOWN (未知)是不同的东西。前者是明确的布尔型的逻辑值,后者既不是值也不是变量。

为了便于区分,前者采用小写字母 unknown ,后者用大写字母 UNKNOWN 来表示。为了让大家理解两者的不同,我们来看一个 x=x 这样的简单等式。x 是逻辑值 unknown 时,x=x 被判断为 true ,而 x 是 UNKNOWN 时被判断为 unknown 。

- 这个是明确的逻辑值的比较 
unknown = unknown → true -- 这个相当于NULL = NULL 
UNKNOWN = UNKNOWN → unknown 

三值逻辑的逻辑值表

NOT:

AND:

OR:

图中蓝色部分是三值逻辑中独有的运算,这在二值逻辑中是没有的。其余的 SQL 谓词全部都能由这三个逻辑运算组合而来。从这个意义上讲,这个几个逻辑表可以说是 SQL 的母体(matrix)。

NOT 的话,因为逻辑值表比较简单,所以很好记;但是对于 AND 和 OR,因为组合出来的逻辑值较多,所以全部记住非常困难。为了便于记忆,请注意这三个逻辑值之间有下面这样的优先级顺序:

  • AND 的情况:false > unknown > true;
  • OR 的情况:true > unknown > false。

优先级高的逻辑值会决定计算结果。例如 true AND unknown ,因为 unknown 的优先级更高,所以结果是 unknown 。而 true OR unknown 的话,因为 true 优先级更高,所以结果是 true 。

记住这个顺序后就能更方便地进行三值逻辑运算了。特别需要记住的是,当 AND 运算中包含 unknown 时,结果肯定不会是 true (反之,如果AND 运算结果为 true ,则参与运算的双方必须都为 true )。

-- 假设 a = 2, b = 5, c = NULL,下列表达式的逻辑值如下 a < b AND b > c  → unknown 
a > b OR b < c   → unknown 
a < b OR b < c   → true 
NOT (b <> c)     → unknown 

“IS NULL” 而非 “= NULL”

我们再回到问题:为什么必须写成“IS NULL”,而不是“= NULL”?

对 NULL 使用比较谓词后得到的结果总是 unknown 。而查询结果只会包含 WHERE 子句里的判断结果为 true 的行,不会包含判断结果为 false 和 unknown 的行。不只是等号,对 NULL 使用其他比较谓词,结果也都是一样的。

所以无论 remark 是不是 NULL ,比较结果都是 unknown ,那么永远没有结果返回。以下的式子都会被判为 unknown:

-- 以下的式子都会被判为 unknown

-- 以下的式子都会被判为 unknown 
= NULL 
> NULL 
< NULL 
<> NULL 
NULL = NULL 

那么,为什么对 NULL 使用比较谓词后得到的结果永远不可能为真呢?

这是因为,NULL 既不是值也不是变量。NULL 只是一个表示“没有值”的标记,而比较谓词只适用于值。

因此,对并非值的 NULL 使用比较谓词本来就是没有意义的。“列的值为 “NULL ”、“NULL 值” 这样的说法本身就是错误的。因为 NULL不是值,所以不在定义域(domain)中。

相反,如果有人认为 NULL 是值,那么我们可以倒过来想一下:它是什么类型的值?关系数据库中存在的值必然属于某种类型,比如字符型或数值型等。所以,假如 NULL 是值,那么它就必须属于某种类型。

NULL 容易被认为是值的原因有两个。

第一个是高级编程语言里面,NULL 被定义为了一个常量(很多语言将其定义为了整数0),这导致了我们的混淆。但是,SQL 里的 NULL 和其他编程语言里的 NULL 是完全不同的东西。

第二个原因是,IS NULL 这样的谓词是由两个单词构成的,所以我们容易把 IS 当作谓词,而把 NULL 当作值。特别是 SQL 里还有 IS TRUE 、IS FALSE 这样的谓词,我们由此类推,从而这样认为也不是没有道理。但是正如讲解标准 SQL 的书里提醒人们注意的那样,我们应该把 IS NULL 看作是一个谓词。因此,写成 IS_NULL 这样也许更合适。

温柔的陷阱

比较谓词和 NULL

排中律不成立。排中律指同一个思维过程中,两个相互矛盾的思想不能同假,必有一真,即“要么A要么非A”。

假设我们有学生表:t_student:

DROP TABLE IF EXISTS t_student; 
CREATE TABLE t_student ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', name VARCHAR(50) NOT NULL COMMENT '名称', age INT(3) COMMENT '年龄', remark VARCHAR(500) NOT NULL DEFAULT '' COMMENT '备注', primary key(id) 
) COMMENT '学生信息'; INSERT INTO t_student(name, age) 
VALUE('zhangsan', 25),('wangwu', 60),('bruce', 32),('yzb', NULL),('boss', 18); SELECT * FROM t_student; 

表中数据 yzb 的 age 是 NULL,也就是说 yzb 的年龄未知。在现实世界里,yzb 是 20 岁,或者不是 20 岁,二者必居其一,这毫无疑问是一个真命题。那么在 SQL 的世界里了,排中律还适用吗? 我们来看一个 SQL :

SELECT * FROM t_student 
WHERE age = 20 OR age <> 20; 

咋一看,这不就是查询表中全部记录吗?我们来看下实际结果:

yzb 没查出来,这是为什么?我们来分析下,yzb 的 age 是 NULL,那么这条记录的判断步骤如下:

-- 1. 约翰年龄是 NULL (未知的 NULL !) 
SELECT * 
FROM t_student 
WHERE age = NULL 
OR age <> NULL; -- 2. 对 NULL 使用比较谓词后,结果为unknown 
SELECT * 
FROM t_student 
WHERE unknown 
OR unknown; -- 3.unknown OR unknown 的结果是unknown (参考三值逻辑的逻辑值表) 
SELECT * 
FROM t_student 
WHERE unknown; 

SQL 语句的查询结果里只有判断结果为 true 的行。要想让 yzb 出现在结果里,需要添加下面这样的 “第 3 个条件”:

-- 添加 3 个条件:年龄是20 岁,或者不是20 岁,或者年龄未知。

    -- 添加 3 个条件:年龄是20 岁,或者不是20 岁,或者年龄未知 SELECT * FROM t_student WHERE age = 20  OR age <> 20 OR age IS NULL; CASE 表达式和 NULL。简单 CASE 表达式如下:CASE col_1 WHEN = 1 THEN 'o' WHEN NULL THEN 'x' END 

这个 CASE 表达式一定不会返回 ×。这是因为,第二个 WHEN 子句是 col_1 = NULL 的缩写形式。正如我们所知,这个式子的逻辑值永远是 unknown ,而且 CASE 表达式的判断方法与 WHERE 子句一样,只认可逻辑值为 true 的条件。正确的写法是像下面这样使用搜索 CASE 表达式:

CASE WHEN col_1 = 1 THEN 'o' WHEN col_1 IS NULL THEN 'x' 
END 

NOT IN 和 NOT EXISTS 并非等价

我们在对 SQL 语句进行性能优化时,经常用到的一个技巧是将 IN 改写成 EXISTS ,这是等价改写,并没有什么问题。但是,将 NOT IN 改写成 NOT EXISTS 时,结果未必一样。

我们来看个例子,我们有如下两张表:t_student_A 和 t_student_B,分别表示 A 班学生与 B 班学生。

DROP TABLE IF EXISTS t_student_A; 
CREATE TABLE t_student_A ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', name VARCHAR(50) NOT NULL COMMENT '名称', age INT(3) COMMENT '年龄', city VARCHAR(50) NOT NULL COMMENT '城市', remark VARCHAR(500) NOT NULL DEFAULT '' COMMENT '备注', primary key(id) 
) COMMENT '学生信息'; INSERT INTO t_student_A(name, age, city) 
VALUE 
('zhangsan', 25,'深圳市'),('wangwu', 60, '广州市'), 
('bruce', 32, '北京市'),('yzb', NULL, '深圳市'), 
('boss', 43, '深圳市'); DROP TABLE IF EXISTS t_student_B; 
CREATE TABLE t_student_B ( id INT(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', name VARCHAR(50) NOT NULL COMMENT '名称', age INT(3) COMMENT '年龄', city VARCHAR(50) NOT NULL COMMENT '城市', remark VARCHAR(500) NOT NULL DEFAULT '' COMMENT '备注', primary key(id) 
) COMMENT '学生信息'; INSERT INTO t_student_B(name, age, city) 
VALUE 
('马化腾', 45, '深圳市'),('马三', 25, '深圳市'), 
('马云', 43, '杭州市'),('李彦宏', 41, '深圳市'), 
('年轻人', 25, '深圳市'); SELECT * FROM t_student_A; 
SELECT * FROM t_student_B; 

需求:查询与 A 班住在深圳的学生年龄不同的 B 班学生,也就说查询出 :马化腾 和 李彦宏,这个 SQL 该如何写,像这样?

-- 查询与 A  班住在深圳的学生年龄不同的 B 班学生 ? 
SELECT * FROM t_student_B 
WHERE age NOT IN ( SELECT age FROM t_student_A  WHERE city = '深圳市' 
); 

我们来看下执行结果:

我们发现结果是空,查询不到任何数据,这是为什么 ?这里 NULL 又开始作怪了,我们一步一步来看看究竟发生了什么。

-- 1. 执行子查询,获取年龄列表 
SELECT * FROM t_student 
WHERE age NOT IN(43, NULL, 25); -- 2. 用NOT 和IN 等价改写NOT IN 
SELECT * FROM t_student 
WHERE NOT age IN (43, NULL, 25); -- 3. 用OR 等价改写谓词IN 
SELECT * FROM t_student 
WHERE NOT ( (age = 43) OR (age = NULL) OR (age = 25) ); -- 4. 使用德· 摩根定律等价改写 
SELECT * FROM t_student 
WHERE NOT (age = 43) AND NOT(age = NULL) AND NOT (age = 25); -- 5. 用<> 等价改写 NOT 和 = 
SELECT * FROM t_student 
WHERE (age <> 43) AND (age <> NULL) AND (age <> 25); -- 6. 对NULL 使用<> 后,结果为 unknown 
SELECT * FROM t_student 
WHERE (age <> 43) AND unknown AND (age <> 25); -- 7.如果 AND 运算里包含 unknown,则结果不为true(参考三值逻辑的逻辑值表) 
SELECT * FROM t_student 
WHERE false 或 unknown; 

可以看出,在进行了一系列的转换后,没有一条记录在 WHERE 子句里被判断为 true 。也就是说,如果 NOT IN 子查询中用到的表里被选择的列中存在 NULL ,则 SQL 语句整体的查询结果永远是空。这是很可怕的现象!

为了得到正确的结果,我们需要使用 EXISTS 谓词。

-- 正确的SQL 语句:马化腾和李彦宏将被查询到 
SELECT * FROM t_student_B B 
WHERE NOT EXISTS (  SELECT * FROM t_student_A A WHERE B.age = A.age AND A.city = '深圳市'  
); 

执行结果如下:

同样地,我们再来一步一步地看看这段 SQL 是如何处理年龄为 NULL 的行的:

-- 1. 在子查询里和 NULL 进行比较运算,此时 A.age 是 NULL 
SELECT * FROM t_student_B B 
WHERE NOT EXISTS (  SELECT * FROM t_student_A A WHERE B.age = NULL AND A.city = '深圳市'  
); -- 2. 对NULL 使用“=”后,结果为 unknown 
SELECT * FROM t_student_B B 
WHERE NOT EXISTS (  SELECT * FROM t_student_A A WHERE unknown AND A.city = '深圳市'  
); -- 3. 如果AND 运算里包含 unknown,结果不会是true 
SELECT * FROM t_student_B B 
WHERE NOT EXISTS (  SELECT * FROM t_student_A A WHERE false 或 unknown 
); -- 4. 子查询没有返回结果,因此相反地,NOT EXISTS 为 true 
SELECT * FROM t_student_B B 
WHERE true; 

也就是说,yzb 被作为 “与任何人的年龄都不同的人” 来处理了。EXISTS 只会返回 true 或者false,永远不会返回 unknown。因此就有了 IN 和 EXISTS 可以互相替换使用,而 NOT IN和 NOT EXISTS 却不可以互相替换的混乱现象。

还有一些其他的陷阱,比如:限定谓词和 NULL、限定谓词和极值函数不是等价的、聚合函数和 NULL 等等。

总结

1、NULL 用于表示缺失的值或遗漏的未知数据,不是某种具体类型的值,不能对其使用谓词。

2、对 NULL 使用谓词后的结果是 unknown,unknown 参与到逻辑运算时,SQL 的运行会和预想的不一样。

3、 IS NULL 整个是一个谓词,而不是:IS 是谓词,NULL 是值;类似的还有 IS TRUE、IS FALSE。

4、要想解决 NULL 带来的各种问题,最佳方法应该是往表里添加 NOT NULL 约束来尽力排除 NULL。

我的项目中有个硬性规定:所有字段必须是 NOT NULL,建表的时候就加上此约束。

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期科技领域知识)

歌谣带你看java面试题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424193.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring mvc学习(19):cookievalue注解(显示cookie的值,默认必须有值)

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

spring mvc学习(20):RequestHeader(获取请求头中某一部分值)

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

spring mvc学习(21):testparam请求参数和请求头表达式

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

spring mvc学习(22):/textpath/*/helen

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

第一百零五期:5年前,跳槽涨薪,你笑了,5年后,跳槽降薪,你慌了!

去年&#xff0c;我在年度绩效面谈中与某中年技术男就 “从测试转向产品经理” 的这个话题上进行了一些探讨与分析。 作者&#xff1a;王晔倞 图片来自 Pexels 或许是因为分析的角度比较客观、真实&#xff0c;再加上俩人都比较会演戏&#xff0c;我激情&#xff0c;他投入&a…

第一百零六期:长相不讨AI喜欢面试就会挂?全球百万求职者经历AI“看脸”面试

AI不仅会筛选你的简历&#xff0c;还会通过看脸决定你能否通过面试。这不是将来时。全球已有超过一百万求职者&#xff0c;经历过AI面试官的冷酷“凝视”。 作者&#xff1a;鱼羊 本文经AI新媒体量子位&#xff08;公众号ID:QbitAI&#xff09;授权转载&#xff0c;转载请联系…

服务器控件HtmlTable下控件赋值问题

在程序开发过程中&#xff0c;碰到这样的问题&#xff1a; 1<table>2<tr>3<td><asp:DropDownList iddropdownlist1 runatserver></td>4</tr>5</table>在基类页中有如下代码&#xff1a;1foreach(Control pagectl inPage.Controls[1]…

Foundry feats. MultiverseStudio

https://www.foundry.com/news-awards/foundry-jcube-announcement 经过这么多年的过程&#xff0c;本周本产品终于发布了PR&#xff0c;这次是由Foundry独家代理销售。 目前本产品已经在全球第一线的工作室的流程内使用&#xff0c;用来装配无法想象巨大的场景&#xff0c;如果…

第一百零七期:她说,嫁人就选程序员!

又是一年双十一&#xff0c;单身狗们还好吗?想脱单?找个程序猿/程序媛是不错的选择&#xff0c;要不要了解一下? 作者&#xff1a;李二狗 图片来自 Pexels 程序员&#xff0c;已经渐渐成当代相亲市场的一只主力军。甚至可以说是“香饽饽”。 越来越多的妹子&#xff0c;在…

第一百零八期:比较容易理解的Hbase架构全解,10分钟学会,建议收藏

依然是Hadoop组件的讲解&#xff0c;今天说到HBase 架构&#xff0c;都是一字一句打出来的&#xff0c;希望各位转发加关注&#xff0c;会一直给大家写优质的内容。 作者&#xff1a;IT技术管理那些事儿 依然是Hadoop组件的讲解&#xff0c;今天说到HBase 架构&#xff0c;都…

315. Count of Smaller Numbers After Self

文章目录1 题目理解2 暴力解法3 分治法1 题目理解 输入&#xff1a;int[] nums 输出&#xff1a;计数的数组int[] counts 规则&#xff1a;counts[i]表示nums中下标大于i&#xff0c;值小于nums[i]的个数 Example 1: Input: nums [5,2,6,1] Output: [2,1,1,0] Explanation: T…

SQL Server执行计划那些事儿(3)——书签查找

接下来的文章是记录自己曾经的盲点&#xff0c;同时也透漏了自己的发展历程&#xff08;可能发展也算不上&#xff0c;只能说是瞎混&#xff09;。当然&#xff0c;一些盲点也在工作和探究过程中慢慢有些眉目&#xff0c;现在也愿意发扬博客园的奉献精神&#xff0c;拿出来和大…

第一百零九期:双十一光棍节调试一个商城必备功能,Java Springboot开源秒杀系统

秒杀系统在电商系统中是非常重要的&#xff0c;不是因为秒杀这个功能重要&#xff0c;而是因为秒杀提现的是一个系统的并发负载能力。例如阿里巴巴或者京东&#xff0c;每年的双十一的峰值&#xff0c;其实就是下一年的常态&#xff0c;双十一各项技术指标&#xff0c;已经作为…

【名额有限】云开发AI拓展能力等你来体验!

这次来了个超厉害的新能力&#xff01; 人脸智能打马赛克、人脸智能裁剪……各种操作&#xff0c;都能一步到位! 迫不及待想体验&#xff0c;戳链接&#xff1a;https://wj.qq.com/s2/3986990/e0ef/ 还没有搞懂&#xff0c;继续往下看—— 基于云开发&#xff0b;AI人脸检测与分…

第一百一十期:详解SpringBoot应用跨域访问解决方案

说到跨域访问&#xff0c;必须先解释一个名词&#xff1a;同源策略。所谓同源策略就是在浏览器端出于安全考量&#xff0c;向服务端发起请求必须满足&#xff1a;协议相同、Host(ip)相同、端口相同的条件&#xff0c;否则访问将被禁止&#xff0c;该访问也就被称为跨域访问。 …

spring mvc学习(23):eclipse创建Maven项目没有src/main/java并不能新建的问题

eclipse里第一次创建Maven项目时&#xff0c;src/main/java与src/test/java目录都不会出现&#xff0c;这是因为eclipse里的一个默认配置。这两个目录是真实存在的&#xff0c;只是隐藏了。 这时候想要让这两个目录出现&#xff0c;就需要修改以下配置&#xff1a; 右击项目-…

spring mvc学习(24):配置maven环境和创建maven项目(建议收藏,超全超详细)

1本次歌谣就对如何创建一个maven项目做一个详细的讲解&#xff0c;毕竟卡了我三天&#xff0c;久久不能入眠&#xff0c;也搜了网上很多的博客 都没有顺利的解决maven项目的创建。这篇建议大家收藏&#xff0c;总会用到的。不然大家看网上的博客也是一脸懵逼。 2首先工具使用…

Torque2D MIT 实战记录: 塔防进度(1)

前言 Torque2D虽然工具不齐全,而且加入MIT不久,但是有老底在,所以即使是第一版也是非常好用和完善的,这几天准备开发一款塔防类的游戏. :) 熟悉了TorqueScript的用法后,写东西还是很快的. 进度 1. 完成了道具库模块 2. 场景系统 3. 阵营逻辑 4. 攻击系统雏形 截图 效果还不错吧…

第一百一十一期:思考 | 一文说透秒杀系统如何设计

秒杀大家都不陌生。自2011年首次出现以来&#xff0c;无论是双十一购物还是 12306 抢票&#xff0c;秒杀场景已随处可见。简单来说&#xff0c;秒杀就是在同一时刻大量请求争抢购买同一商品并完成交易的过程。从架构视角来看&#xff0c;秒杀系统本质是一个高性能、高一致、高可…

第一百一十二期:96秒100亿!如何抗住双11高并发流量?

今年双 11 全民购物狂欢节进入第十一个年头&#xff0c;1 分 36 秒&#xff0c;交易额冲到 100 亿 !比 2018 年快了近 30 秒&#xff0c;比 2017 年快了近 1 分半!这个速度再次刷新天猫双 11 成交总额破 100 亿的纪录。 作者&#xff1a;邴越 今年双 11 全民购物狂欢节进入第…