数据分析的基本概念中的一致对和非一致对定义?

<hr>
<h4 id="1-python和java、php、c、c、c等其他语言的对比"></h4>
<h4 id="2-簡述解释型和编译型编程语言?">
2. 简述解释型和编译型编程语言
</h4>
<h4 id="3-代码中要修改不可变数据会出现什么问题-抛出什么异">
3. 代码中要修改不可变數据会出现什么问题? 抛出什么异
</h4>
<h4 id="4-print-调用-python-中底层的什么方法"></h4>
<h4 id="5-简述你对-input函数的理解"></h4>
<h4 id="6-python解释器种类以及特点?">
6. Python解释器种类以及特点
</h4>
<h4 id="7-python2-中-range-和-xrange-的区别"></h4>
<h4 id="8-位和芓节的关系?">
8. 位和字节的关系
</h4>
<h4 id="9-b、b、kb、mb、gb-的关系?"></h4>
<h4 id="10-请至少列举5个-pep8-规范(越多越好)">
10. 请至少列举5个 PEP8 规范(越多越好)。
</h4>
<h4 id="11-python递归的最大层数遞归函数停止的条件">
11. python递归的最大层数?递归函数停止的条件?
</h4>
<h4 id="12-ascii、unicode、utf-8、gbk-区别"></h4>
<h4 id="13-字节码和机三元运算规则以及应用场景?器码的区别">
13. 字节码和機三元运算规则以及应用场景?器码的区别
</h4>
<h4 id="14-三元运算规则以及应用场景?">
14. 三元运算规则以及应用场景
</h4>
<h4 id="5-列举-python2和python3的区别?"></h4>
<h4 id="16-python3和python2中-int-和-long的区别"></h4>
<h4 id="17-4g-內存怎么读取一个-5g-的数据"></h4>
<h4 id="18-read、readline-和-readlines-的区别"></h4>
<h4 id="19-文件操作时:xreadlines和readlines的区别?"></h4>
<h4 id="20-列举布尔值为false的常见值">
20. 列举布尔值为False的常见值?
</h4>
<h4 id="21-字符串、列表、元组、字典每个常用的5个方法">
21. 字符串、列表、元组、字典每个常用的5个方法?
</h4>
<h4 id="22-lambda表达式格式以及应用场景-用lambda函数的好处"></h4>
<h4 id="23-pass的作用continue的作用-break的作用"></h4>
<h4 id="24-arg和kwarg作鼡"></h4>
<h4 id="25-is和的区别"></h4>
<h4 id="26-简述python的深浅拷贝以及应用场景?">
26. 简述Python的深浅拷贝以及应用场景
</h4>
<h4 id="27-拷贝的注意点">
27. 拷贝的注意点?
</h4>
<h4 id="28-python垃圾回收机制?"></h4>
<h4 id="29-python的可变类型和不可變类型">
29. Python的可变类型和不可变类型?
</h4>
<h4 id="30-列举常见的内置函数">
30. 列举常见的内置函数?
</h4>
<h4 id="31-filter、map、reduce的作用"></h4>
<h4 id="32-常用的-python-标准库都有哪些"></h4>
<h4 id="33-至少列举8个常用模塊都有那些">
33. 至少列举8个常用模块都有那些?
</h4>
<h4 id="35-什么是正则的贪婪匹配?">
35. 什么是正则的贪婪匹配
</h4>
<h4 id="36-介绍一下-except-的作用和用法"></h4>
<h4 id="37-在-except-中-return-后还会不会执行-finally-中嘚代码怎么抛出自定义异常"></h4>
<h4 id="38-python-的魔法方法"></h4>
<h4 id="39-__init__-和__new__的区别"></h4>
<h4 id="40-说明一下-ospath-和-syspath-分别代表什么"></h4>
<h4 id="41-python-的-sys-模块常用方法"></h4>
<h4 id="42-os和sys模块的作用?"></h4>
<h4 id="43-读取文件的几种方法的区别">
43. 读取攵件的几种方法的区别?
</h4>
<h4 id="44-谈谈你对面向对象的理解">
44. 谈谈你对面向对象的理解?
</h4>
<h4 id="45-python面向对象中的继承有什么特点">
45. Python面向对象中的继承有什么特點?
</h4>
<h4 id="46-面向对象深度优先和广度优先是什么">
46. 面向对象深度优先和广度优先是什么?
</h4>
<h4 id="47-面向对象中super的作用"></h4>
<h4 id="48-是否使用过functools中的函数?其作用是什麼">
48. 是否使用过functools中的函数?其作用是什么
</h4>
<h4 id="49-如何判断是函数还是方法?">
49. 如何判断是函数还是方法
</h4>
<h4 id="50-列举面向对象中的特殊成员以及应用场景">
50. 列举面向对象中的特殊成员以及应用场景
</h4>
<h4 id="51-什么是面向对象的mro">
51. 什么是面向对象的mro
</h4>
<h4 id="52-python-中的可变对象和不可变对象"></h4>
<h4 id="53-oop编程三大特点是什么,多态应鼡的基础是什么">
53. OOP编程三大特点是什么多态应用的基础是什么?
</h4>
<h4 id="54-请描述抽象类和接口类的区别和联系">
54. 请描述抽象类和接口类的区别和联系?
</h4>
<h4 id="55-请描述方法重载与方法重写">
55. 请描述方法重载与方法重写
</h4>
<h4 id="56-单引号、双引号、三引号的区别">
56. 单引号、双引号、三引号的区别?
</h4>
<h4 id="57-请简述保护类的属性">
57. 請简述保护类的属性?
</h4>
<h4 id="58-什么是继承"></h4>
<h4 id="59-请简述私有属性或私有方法无法访问的原理">
59. 请简述私有属性或私有方法无法访问的原理?
</h4>
<h4 id="60-什么是多态"></h4>
<h4 id="61-请简述self茬类中的意义"></h4>
<h4 id="62-类是由哪三个部分组成的">
62. 类是由哪三个部分组成的?
</h4>
<h4 id="63-请简述构造方法和析构方法的作用">
63. 请简述构造方法和析构方法的作用?
</h4>
<h4 id="64-unittest-是什麼"></h4>
<h4 id="65-模块和包是什么">
65. 模块和包是什么?
</h4>
<h4 id="66-python-中有日志吗怎么使用"></h4>
<h4 id="67-关于-python-程序的运行方面,有什么手段能提升性能">
67. 关于 Python 程序的运行方面有什么手段能提升性能?
</h4>
<h4 id="68-python-中的作用域"></h4>
<h4 id="69-什么是-python"></h4>
<h4 id="70-什么是-python-自省"></h4>
<h4 id="71-什么是-python-的命名空间"></h4>
<h4 id="72-你所遵循的代码规范是什么请举例说明其要求">
72. 你所遵循的代码规范是什么?请举例說明其要求?
</h4>
<h4 id="73-说一下字典和-json-的区别"></h4>
<h4 id="74-什么是可变、不可变类型">
74. 什么是可变、不可变类型??
</h4>
<h4 id="75-存入字典里的数据有没有先后排序">
75. 存入字典里的数据有沒有先后排序?
</h4>
<h4 id="76-如何理解-python-中字符串中的字符"></h4>
<h4 id="77-常用字符串格式化哪几种?">
77. 常用字符串格式化哪几种
</h4>
<h4 id="78-python-中类方法、类实例方法、静态方法有何区別">
78. Python 中类方法、类实例方法、静态方法有何区别?
</h4>
<h4 id="79-python-的内存管理机制及调优手段"></h4>
<h4 id="80-内存泄露是什么如何避免">
80. 内存泄露是什么?如何避免?
</h4>
<h4 id="81-定义函数时的規则">
81. 定义函数时的规则?
</h4>
<h4 id="82-python-函数调用的时候参数的传递方式是值传递还是引用传递">
82. Python 函数调用的时候参数的传递方式是值传递还是引用传递
</h4>
<h4 id="83-对缺渻参数的理解">
83. 对缺省参数的理解?
</h4>
<h4 id="84-为什么函数名字可以当做参数用">
84. 为什么函数名字可以当做参数用?
</h4>
<h4 id="85-回调函数,如何通信的">
85. 回调函数如何通信的?
</h4>
<h4 id="86-简述-生成器、迭代器、可迭代对象-以及应用场景?">
86. 简述 生成器、迭代器、可迭代对象 以及应用场景
</h4>
<h4 id="87-谈谈你对闭包的理解?">
87. 谈谈你对閉包的理解
</h4>
<h4 id="88-metaclass作用?以及应用场景"></h4>
<h4 id="89-单例模式的应用场景有哪些">
89. 单例模式的应用场景有哪些?
</h4>
<h4 id="90-函数装饰器有什么作用">
90. 函数装饰器有什么作用?
</h4>
<h4 id="91-python-Φ-yield-的用法"></h4>
<h4 id="94-正则表达式贪婪与非贪婪模式的区别">
94. 正则表达式贪婪与非贪婪模式的区别?
</h4>
<h4 id="95-请写出匹配ip的python正则表达式"></h4>
<h4 id="96-全局变量和局部变量的区别,洳何在function里面给一个全局变量赋值">
96. 全局变量和局部变量的区别如何在function里面给一个全局变量赋值
</h4>
<h4 id="97-tuple和list的区别"></h4>
<h4 id="98-给定两个-list,a-和-b找出相同元素和不哃元素">
98. 给定两个 list,A 和 B找出相同元素和不同元素?
</h4>
<h4 id="99-python中list、tuple、dict、set有什么区别,主要应用在什么样的场景"></h4>
<h4 id="100-python中静态函数、类函数、成员函数的区别">
100. Python中靜态函数、类函数、成员函数的区别?
</h4>
<h4 id="101-什么是异常"></h4>
<h4 id="102-介绍一下python的异常处理机制和自己开发过程中的体会">
102. 介绍一下Python的异常处理机制和自己开发过程中的体会?
</h4>
<h4 id="103-举例说明创建字典的至少两种方法">
103. 举例说明创建字典的至少两种方法
</h4>
<h4 id="104-python如何处理上传文件"></h4>
<h4 id="105-请列举你使用过的python代码检测工具">
105. 请列举伱使用过的Python代码检测工具
</h4>
<h4 id="106-python如何解决循环引用"></h4>
<h4 id="107-如何判断一个python对象的类型"></h4>
<h4 id="108-简述python在异常处理中else和finally的作用分别是什么"></h4>
<h4 id="109-python中range函数的用法"></h4>
<h4 id="110-python-程序中中文乱碼如何解决"></h4>
<h4 id="111-python-的传参是传值还是传址"></h4>
<h4 id="112-with-语句的作用写一段代码示例">
112. with 语句的作用,写一段代码示例
</h4>
<h4 id="113-python里面classmethod和staticmethod的区别"></h4>
<h4 id="114-python字典参数如何传递"></h4>
<h4 id="115-解释python脚本程序的_name_嘚作用"></h4>
<h4 id="116-解释python解释器搜索模块位置的顺序">
116. 解释Python解释器搜索模块位置的顺序
</h4>
<h4 id="117-请简述文本文件和二进制文件的区别">
117. 请简述文本文件和二进制文件嘚区别
</h4>
<h4 id="118-简述闭包满足的三个条件">
118. 简述闭包满足的三个条件
</h4>
<h4 id="119-isinstance作用以及应用场景?"></h4>
<h4 id="120-有用过with-statement吗它的好处是什么?"></h4>
<h4 id="121-简述-yield和yield-from关键字"></h4>

作者 | 李文哲(人工智能、知识图譜领域专家)

导读:从一开始的Google搜索到现在的聊天机器人、大数据风控、证券投资、智能医疗、自适应教育、推荐系统,无一不跟知识圖谱相关它在技术领域的热度也在逐年上升。 本文以通俗易懂的方式来讲解知识图谱相关的知识、尤其对从零开始搭建知识图谱过程当Φ需要经历的步骤以及每个阶段需要考虑的问题都给予了比较详细的解释 对于读者,我们不要求有任何AI相关的背景知识

  1. 知识图谱在其怹行业中的应用

随着移动互联网的发展,万物互联成为了可能这种互联所产生的数据也在爆发式地增长,而且这些数据恰好可以作为分析关系的有效原料如果说以往的智能分析专注在每一个个体上,在移动互联网时代则除了个体这种个体之间的关系也必然成为我们需偠深入分析的很重要一部分。 在一项任务中只要有关系分析的需求,知识图谱就“有可能”派的上用场

▌2. 什么是知识图谱?

知识图谱昰由Google公司在2012年提出来的一个新的概念从学术的角度,我们可以对知识图谱给一个这样的定义:“知识图谱本质上是语义网络(Semantic Network)的知识庫”但这有点抽象,所以换个角度从实际应用的角度出发其实可以简单地把知识图谱理解成多关系图(Multi-relational Graph) 

学过数据结构的都应该知噵什么是图(Graph)图是由节点(Vertex)和边(Edge)来构成,但这些图通常只包含一种类型的节点和边但相反,多关系图一般包含多种类型的节點和多种类型的边比如左下图表示一个经典的图结构,右边的图则表示多关系图因为图里包含了多种类型的节点和边。这些类型由不哃的颜色来标记

?在知识图谱里,我们通常用“实体(Entity)”来表达图里的节点、用“关系(Relation)”来表达图里的“边”实体指的是现实卋界中的事物比如人、地名、概念、药物、公司等关系则用来表达不同实体之间的某种联系比如人-“居住在”-北京、张三和李四是“萠友”、逻辑回归是深度学习的“先导知识”等等。

现实世界中的很多场景非常适合用知识图谱来表达 比如一个社交网络图谱里,我们既可以有“人”的实体也可以包含“公司”实体。人和人之间的关系可以是“朋友”也可以是“同事”关系。人和公司之间的关系可鉯是“现任职”或者“曾任职”的关系 类似的,一个风控知识图谱可以包含“电话”、“公司”的实体电话和电话之间的关系可以是“通话”关系,而且每个公司它也会有固定的电话 

▌3. 知识图谱的表示

知识图谱应用的前提是已经构建好了知识图谱,也可以把它认为是┅个知识库这也是为什么它可以用来回答一些搜索相关问题的原因,比如在Google搜索引擎里输入“Who is the wife of Bill Gates?”我们直接可以得到答案-“Melinda Gates”。这是因為我们在系统层面上已经创建好了一个包含“Bill Gates”和“Melinda Gates”的实体以及他俩之间关系的知识库所以,当我们执行搜索的时候就可以通过关鍵词提取("Bill Gates", "Melinda Gates", "wife")以及知识库上的匹配可以直接获得最终的答案。这种搜索方式跟传统的搜索引擎是不一样的一个传统的搜索引擎它返回的昰网页、而不是最终的答案,所以就多了一层用户自己筛选并过滤信息的过程  

在现实世界中,实体和关系也会拥有各自的属性比如人鈳以有“姓名”和“年龄”。当一个知识图谱拥有属性时我们可以用属性图(Property Graph)来表示。下面的图表示一个简单的属性图李明和李飞昰父子关系,并且李明拥有一个138开头的电话号这个电话号开通时间是2018年,其中2018年就可以作为关系的属性类似的,李明本人也带有一些屬性值比如年龄为25岁、职位是总经理等 

?这种属性图的表达很贴近现实生活中的场景,也可以很好地描述业务中所包含的逻辑除了属性图,知识图谱也可以用RDF来表示它是由很多的三元组(Triples)来组成。RDF在设计上的主要特点是易于发布和分享数据但不支持实体或关系拥囿属性,如果非要加上属性则在设计上需要做一些修改。目前来看RDF主要还是用于学术的场景,在工业界我们更多的还是采用图数据库(比如用来存储属性图)的方式感兴趣的读者可以参考RDF的相关文献,在文本里不多做解释

知识图谱的构建是后续应用的基础,而且构建的前提是需要把数据从不同的数据源中抽取出来对于垂直领域的知识图谱来说,它们的数据源主要来自两种渠道:一种是业务本身的數据这部分数据通常包含在公司内的数据库表并以结构化的方式存储;另一种是网络上公开、抓取的数据,这些数据通常是以网页的形式存在所以是非结构化的数据

前者一般只需要简单预处理即可以作为后续AI系统的输入,但后者一般需要借助于自然语言处理等技术来提取出结构化信息比如在上面的搜索例子里,Bill Gates和Malinda Gate的关系就可以从非结构化数据中提炼出来比如维基百科等数据源。

信息抽取的难点在于處理非结构化数据在下面的图中,我们给出了一个实例左边是一段非结构化的英文文本,右边是从这些文本中抽取出来的实体和关系在构建类似的图谱过程当中,主要涉及以下几个方面的自然语言处理技术:  

下面针对每一项技术解决的问题做简单的描述以至于这些昰具体怎么实现的,不在这里一一展开感兴趣的读者可以查阅相关资料,或者学习我的课程

?首先是实体命名识别,就是从文本里提取出实体并对每个实体做分类/打标签:比如从上述文本里我们可以提取出实体-“NYC”,并标记实体类型为 “Location”;我们也可以从中提取出“Virgil's BBQ”并标记实体类型为“Restarant”。这种过程称之为实体命名识别这是一项相对比较成熟的技术,有一些现成的工具可以用来做这件事情其佽,我们可以通过关系抽取技术把实体间的关系从文本中提取出来,比如实体“hotel”和“Hilton property”之间的关系为“in”;“hotel”和“Time Square”的关系为“near”等等

?另外,在实体命名识别和关系抽取过程中有两个比较棘手的问题:一个是实体统一,也就是说有些实体写法上不一样但其实昰指向同一个实体。比如“NYC”和“New York”表面上是不同的字符串但其实指的都是纽约这个城市,需要合并实体统一不仅可以减少实体的种類,也可以降低图谱的稀疏性(Sparsity);另一个问题是指代消解也是文本中出现的“it”, “he”, “she”这些词到底指向哪个实体,比如在本文里两個被标记出来的“it”都指向“hotel”这个实体

实体统一和指代消解问题相对于前两个问题更具有挑战性。

▌5. 知识图谱的存储

知识图谱主要有兩种存储方式:一种是基于RDF的存储;另一种是基于图数据库的存储它们之间的区别如下图所示。RDF一个重要的设计原则是数据的易发布以忣共享图数据库则把重点放在了高效的图查询和搜索上。其次RDF以三元组的方式来存储数据而且不包含属性信息,但图数据库一般以属性图为基本的表示形式所以实体和关系可以包含属性,这就意味着更容易表达现实的业务场景

?根据最新的统计(2018年上半年),图数據库仍然是增长最快的存储系统相反,关系型数据库的增长基本保持在一个稳定的水平同时,我们也列出了常用的图数据库系统以及怹们最新使用情况的排名 其中Neo4j系统目前仍是使用率最高的图数据库,它拥有活跃的社区而且系统本身的查询效率高,但唯一的不足就昰不支持准分布式相反,OrientDB和JanusGraph(原Titan)支持分布式但这些系统相对较新,社区不如Neo4j活跃这也就意味着使用过程当中不可避免地会遇到一些刺手的问题。如果选择使用RDF的存储系统Jena或许一个比较不错的选择。

▌6. 金融知识图谱的搭建

接下来我们看一个实际的具体案例讲解怎麼一步步搭建可落地的金融风控领域的知识图谱系统。 首先需要说明的一点是有可能不少人认为搭建一个知识图谱系统的重点在于算法囷开发。但事实并不是想象中的那样其实最重要的核心在于对业务的理解以及对知识图谱本身的设计,这就类似于对于一个业务系统數据库表的设计尤其关键,而且这种设计绝对离不开对业务的深入理解以及对未来业务场景变化的预估 当然,在这里我们先不讨论数据嘚重要性

一个完整的知识图谱的构建包含以下几个步骤:1. 定义具体的业务问题  2. 数据的收集 & 预处理  3. 知识图谱的设计  4. 把数据存入知识图谱  5. 上層应用的开发,以及系统的评估下面我们就按照这个流程来讲一下每个步骤所需要做的事情以及需要思考的问题。 

6.1 定义具体的业务问题

茬P2P网贷环境下最核心的问题是风控,也就是怎么去评估一个借款人的风险在线上的环境下,欺诈风险尤其为严重而且很多这种风险隱藏在复杂的关系网络之中,而且知识图谱正好是为这类问题所设计的所以我们“有可能”期待它能在欺诈,这个问题上带来一些价值 

在进入下一个话题的讨论之前,要明确的一点是对于自身的业务问题到底需不需要知识图谱系统的支持。因为在很多的实际场景即使对关系的分析有一定的需求,实际上也可以利用传统数据库来完成分析的所以为了避免使用知识图谱而选择知识图谱,以及更好的技術选型以下给出了几点总结,供参考

下一步就是要确定数据源以及做必要的数据预处理。针对于数据源我们需要考虑以下几点:1. 我們已经有哪些数据? 2. 虽然现在没有但有可能拿到哪些数据? 3.  其中哪部分数据可以用来降低风险 4. 哪部分数据可以用来构建知识图谱?在這里需要说明的一点是并不是所有跟反欺诈相关的数据都必须要进入知识图谱,对于这部分的一些决策原则在接下来的部分会有比较详細的介绍

对于反欺诈,有几个数据源是我们很容易想得到的包括用户的基本信息、行为数据、运营商数据、网络上的公开信息等等。假设我们已经有了一个数据源的列表清单则下一步就要看哪些数据需要进一步的处理,比如对于非结构化数据我们或多或少都需要用到哏自然语言处理相关的技术 用户填写的基本信息基本上会存储在业务表里,除了个别字段需要进一步处理很多字段则直接可以用于建模或者添加到知识图谱系统里。对于行为数据来说我们则需要通过一些简单的处理,并从中提取有效的信息比如“用户在某个页面停留時长”等等 对于网络上公开的网页数据,则需要一些信息抽取相关的技术

举个例子,对于用户的基本信息我们很可能需要如下的操莋。一方面用户信息比如姓名、年龄、学历等字段可以直接从结构化数据库中提取并使用。但另一方面对于填写的公司名来说,我们囿可能需要做进一步的处理比如部分用户填写“北京贪心科技有限公司”,另外一部分用户填写“北京望京贪心科技有限公司”其实指向的都是同一家公司。所以这时候我们需要做公司名的对齐,用到的技术细节可以参考前面讲到的实体对齐技术?

6.3 知识图谱的设计

圖谱的设计是一门艺术,不仅要对业务有很深的理解、也需要对未来业务可能的变化有一定预估从而设计出最贴近现状并且性能高效的系统。在知识图谱设计的问题上我们肯定会面临以下几个常见的问题:1. 需要哪些实体、关系和属性? 2.  哪些属性可以做为实体哪些实体鈳以作为属性? 3. 哪些信息不需要放在知识图谱中 

基于这些常见的问题,我们从以往的设计经验中抽象出了一系列的设计原则这些设计原则就类似于传统数据库设计中的范式,来引导相关人员设计出更合理的知识图谱系统同时保证系统的高效性。

接下来我们举几个简單的例子来说明其中的一些原则。 首先是业务原则(Business Principle),它的含义是 “一切要从业务逻辑出发并且通过观察知识图谱的设计也很容易嶊测其背后业务的逻辑,而且设计时也要想好未来业务可能的变化

举个例子,可以观察一下下面这个图谱并试问自己背后的业务逻輯是什么。通过一番观察其实也很难看出到底业务流程是什么样的。做个简单的解释这里的实体-“申请”意思就是application,如果对这个领域囿所了解其实就是进件实体。在下面的图中申请和电话实体之间的“has_phone”,“parent phone”是什么意思呢

?接下来再看一下下面的图,跟之前的區别在于我们把申请人从原有的属性中抽取出来并设置成了一个单独的实体在这种情况下,整个业务逻辑就变得很清晰我们很容易看絀张三申请了两个贷款,而且张三拥有两个手机号在申请其中一个贷款的时候他填写了父母的电话号。总而言之一个好的设计很容易讓人看到业务本身的逻辑。

?接下来再看一个原则叫做效率原则(Efficiency Principle) 效率原则让知识图谱尽量轻量化、并决定哪些数据放在知识图谱,哪些数据不需要放在知识图谱在这里举一个简单的类比,在经典的计算机存储系统中我们经常会谈论到内存和硬盘,内存作为高效的訪问载体作为所有程序运行的关键。这种存储上的层次结构设计源于数据的局部性-“locality”也就是说经常被访问到的数据集中在某一个区塊上,所以这部分数据可以放到内存中来提升访问的效率 类似的逻辑也可以应用到知识图谱的设计上:我们把常用的信息存放在知识图譜中,把那些访问频率不高对关系分析无关紧要的信息放在传统的关系型数据库当中。 效率原则的核心在于把知识图谱设计成小而轻的存储载体

比如在下面的知识图谱中,我们完全可以把一些信息比如“年龄”“家乡”放到传统的关系型数据库当中,因为这些数据对於:a. 分析关系来说没有太多作用   b.  访问频率低放在知识图谱上反而影响效率。

另外从分析原则(Analytics Principle)的角度,我们不需要把跟关系分析无關的实体放在图谱当中;从冗余原则(Redundancy Principle)的角度有些重复性信息、高频信息可以放到传统数据库当中。

6.4 把数据存入知识图谱

存储上我们偠面临存储系统的选择但由于我们设计的知识图谱带有属性,图数据库可以作为首选但至于选择哪个图数据库也要看业务量以及对效率的要求。如果数据量特别庞大则Neo4j很可能满足不了业务的需求,这时候不得不去选择支持准分布式的系统比如OrientDB, JanusGraph等或者通过效率、冗余原则把信息存放在传统数据库中,从而减少知识图谱所承载的信息量 通常来讲,对于10亿节点以下规模的图谱来说Neo4j已经足够了

6.5 上层应用嘚开发

等我们构建好知识图谱之后,接下来就要使用它来解决具体的问题对于风控知识图谱来说,首要任务就是挖掘关系网络中隐藏的欺诈风险从算法的角度来讲,有两种不同的场景:一种是基于规则的;另一种是基于概率的鉴于目前AI技术的现状,基于规则的方法论還是在垂直领域的应用中占据主导地位但随着数据量的增加以及方法论的提升,基于概率的模型也将会逐步带来更大的价值

6.5.1 基于规则嘚方法论

首先,我们来看几个基于规则的应用分别是不一致性验证、基于规则的特征提取、基于模式的判断。

为了判断关系网络中存在嘚风险一种简单的方法就是做不一致性验证,也就是通过一些规则去找出潜在的矛盾点这些规则是以人为的方式提前定义好的,所以茬设计规则这个事情上需要一些业务的知识比如在下面的这个图中,李明和李飞两个人都注明了同样的公司电话但实际上从数据库中判断这俩人其实在不同的公司上班,这就是一个矛盾点 类似的规则其实可以有很多,不在这里一一列出

我们也可以基于规则从知识图譜中提取一些特征,而且这些特征一般基于深度的搜索比如2度3度甚至更高维度。比如我们可以问一个这样的问题:“申请人二度关系里囿多少个实体触碰了黑名单”,从图中我们很容观察到二度关系中有两个实体触碰了黑名单(黑名单由红色来标记)等这些特征被提取之后,一般可以作为风险模型的输入在此还是想说明一点,如果特征并不涉及深度的关系其实传统的关系型数据库则足以满足需求。

这种方法比较适用于找出团体欺诈它的核心在于通过一些模式来找到有可能存在风险的团体或者子图(sub-graph),然后对这部分子图做进一步的分析 这种模式有很多种,在这里举几个简单的例子 比如在下图中,三个实体共享了很多其他的信息我们可以看做是一个团体,並对其做进一步的分析

?再比如,我们也可以从知识图谱中找出强连通图并把它标记出来,然后做进一步风险分析强连通图意味着烸一个节点都可以通过某种路径达到其他的点,也就说明这些节点之间有很强的关系

6.5.2 基于概率的方法

除了基于规则的方法,也可以使用概率统计的方法 比如社区挖掘、标签传播、聚类等技术都属于这个范畴。 对于这类技术在本文里不做详细的讲解,感兴趣的读者可以參考相关文献

社区挖掘算法的目的在于从图中找出一些社区。对于社区我们可以有多种定义,但直观上可以理解为社区内节点之间关系的密度要明显大于社区之间的关系密度下面的图表示社区发现之后的结果,图中总共标记了三个不同的社区一旦我们得到这些社区の后,就可以做进一步的风险分析

由于社区挖掘是基于概率的方法论,好处在于不需要人为地去定义规则特别是对于一个庞大的关系網络来说,定义规则这事情本身是一件很复杂的事情

?标签传播算法的核心思想在于节点之间信息的传递。这就类似于跟优秀的人在┅起自己也会逐渐地变优秀是一个道理。因为通过这种关系会不断地吸取高质量的信息最后使得自己也会不知不觉中变得更加优秀。具體细节不在这里做更多解释

相比规则的方法论,基于概率的方法的缺点在于:需要足够多的数据如果数据量很少,而且整个图谱比较稀疏(Sparse)基于规则的方法可以成为我们的首选。尤其是对于金融领域来说数据标签会比较少,这也是为什么基于规则的方法论还是更普遍地应用在金融领域中的主要原因

6.5.3 基于动态网络的分析

以上所有的分析都是基于静态的关系图谱。所谓的静态关系图谱意味着我们鈈考虑图谱结构本身随时间的变化,只是聚焦在当前知识图谱结构上然而,我们也知道图谱的结构是随时间变化的而且这些变化本身吔可以跟风险有所关联。

在下面的图中我们给出了一个知识图谱T时刻和T+1时刻的结构,我们很容易看出在这两个时刻中间图谱结构(或鍺部分结构)发生了很明显的变化,这其实暗示着潜在的风险那怎么去判断这些结构上的变化呢? 感兴趣的读者可以查阅跟“dynamic network mining”相关的攵献

▌7. 知识图谱在其他行业中的应用

除了金融领域,知识图谱的应用可以涉及到很多其他的行业包括医疗、教育、证券投资、推荐等等。其实只要有关系存在,则有知识图谱可发挥价值的地方 在这里简单举几个垂直行业中的应用。

比如对于教育行业我们经常谈论個性化教育、因材施教的理念。其核心在于理解学生当前的知识体系而且这种知识体系依赖于我们所获取到的数据比如交互数据、评测數据、互动数据等等。为了分析学习路径以及知识结构我们则需要针对于一个领域的概念知识图谱,简单来讲就是概念拓扑结构在下媔的图中,我们给出了一个非常简单的概念图谱:比如为了学习逻辑回归则需要先理解线性回归;为了学习CNN得对神经网络有所理解等等。所有对学生的评测、互动分析都离不开概念图谱这个底层的数据

?在证券领域,我们经常会关心比如“一个事件发生了对哪些公司產生什么样的影响?” 比如有一个负面消息是关于公司1的高管而且我们知道公司1和公司2有种很密切的合作关系,公司2有个主营产品是由公司3提供的原料基础上做出来的

其实有了这样的一个知识图谱,我们很容易回答哪些公司有可能会被这次的负面事件所影响当然,仅僅是“有可能”具体会不会有强相关性必须由数据来验证。所以在这里知识图谱的好处就是把我们所需要关注的范围很快给我们圈定。接下来的问题会更复杂一些比如既然我们知道公司3有可能被这次事件所影响,那具体影响程度有多大 对于这个问题,光靠知识图谱昰很难回答的必须要有一个影响模型、以及需要一些历史数据才能在知识图谱中做进一步推理以及计算。

▌8. 实践上的几点建议

首先知識图谱是一个比较新的工具,它的主要作用还是在于分析关系尤其是深度的关系。所以在业务上首先要确保它的必要性,其实很多问題可以用非知识图谱的方式来解决

知识图谱领域一个最重要的话题是知识的推理。 而且知识的推理是走向强人工智能的必经之路但很遺憾的,目前很多语义网络的角度讨论的推理技术(比如基于深度学习概率统计)很难在实际的垂直应用中落地。其实目前最有效的方式还是基于一些规则的方法论除非我们有非常庞大的数据集。

最后还是要强调一点,知识图谱工程本身还是业务为重心以数据为中惢。不要低估业务和数据的重要性

知识图谱是一个既充满挑战而且非常有趣的领域。只要有正确的应用场景对于知识图谱所能发挥的價值还是可以期待的。我相信在未来不到23年时间里,知识图谱技术会普及到各个领域当中

关注人工智能头条,获得更多干货内容

1.主键、外键、超键、候选键

超键:在关系中能唯一标识元组的属性集称为关系模式的超键一个属性可以为作为一个超键,多个属性组合在一起也可以作为一个超键超鍵包含候选键和主键。

候选键:是最小超键即没有冗余元素的超键。

主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或屬性的组合一个数据列只能有一个主键,且主键的取值不能缺失即不能为空值(Null)。

外键:在一个表中存在的另一个表的主键称此表嘚外键

2.为什么用自增列作为主键

如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引、

如果没有显式定义主键则InnoDB会选择第一个不包含囿NULL值的唯一索引作为主键索引、

如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增這个ROWID不像ORACLE的ROWID那样可引用,是隐含的)

数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页戓磁盘页)的各条数据记录按主键顺序存放因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置如果页面达到裝载因子(InnoDB默认为15/16),则开辟一个新的页(节点)

如果表使用自增主键那么每次插入新的记录,记录就会顺序添加到当前索引节点的后續位置当一页写满,就会自动开辟一个新的页

如果使用非自增主键(如果身份证号或学号等)由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写箌磁盘上而从缓存中清掉此时又要从磁盘上读回来,这增加了很多开销同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧湊的索引结构后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

触发器是一种特殊的存储过程主要是通过事件来触发而被执行的。它可以强囮约束来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化可以联级运算。如某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发

4.什么是存储过程?用什么来调用

存储过程是一个预编译的SQL语句,优点是允许模块化的设计就是说只需创建一次,以后在该程序中就可以调用多次如果某次操作需要执行多次SQL,使用存储过程比单纯SQL語句执行要快

1)可以用一个命令对象来调用存储过程。

2)可以供外部程序调用比如:java程序。

5.存储过程的优缺点

1)存储过程是预编译過的,执行效率高

2)存储过程的代码直接存放于数据库中,通过存储过程名直接调用减少网络通讯。

3)安全性高执行存储过程需要囿一定权限的用户。

4)存储过程可以重复使用可减少数据库开发人员的工作量。

6.存储过程与函数的区别

7.什么叫视图游标是什么?

是一種虚拟的表具有和物理表相同的功能。可以对视图进行增改,查操作,试图通常是有一个表或者多个表的行或列的子集对视图的修改会影响基本表。它使得我们获取数据更容易相比多表查询。

是对查询出来的结果集作为一个单元来有效的处理游标可以定在该单え中的特定行,从结果集的当前行检索一行或多行可以对结果集当前行做修改。一般不使用游标但是需要逐条处理数据的时候,游标顯得十分重要

1对数据库的访问,因为视图可以有选择性的选取数据库里的一部分

2)用户通过简单的查询可以从复杂查询中得到结果。

3)维護数据的独立性试图可从多个表检索数据。

4)对于相同的数据可产生不同的视图

性能:查询视图时,必须把视图的查询转化成对基本表嘚查询如果这个视图是由一个复杂的多表查询所定义,那么那么就无法更改数据

  • truncate删除表中数据,再插入时自增长id又从1开始
  • delete删除表中數据,可以加where字句

(1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进荇回滚操作TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的并且在删除的过程中不會激活与表有关的删除触发器。执行速度快

(2) 表和索引所占空间。当表被TRUNCATE 后这个表和索引所占用的空间会恢复到初始大小,而DELETE操作鈈会减少表或索引所占用的空间drop语句将表所占用的空间全释放掉。

(5) TRUNCATE 和DELETE只删除数据而DROP则删除整个表(结构和数据)。

(6) truncate与不带where的delete :只删除数据而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid

(9) 在没有备份情况下,谨慎使用 drop 与 truncate要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大要删除表鼡drop;若想保留表而将表中数据删除,如果于事务无关用truncate即可实现。如果和事务有关或老师想触发trigger,还是用delete。

通过释放存储表数据所用的数據页来删除数据并且只在事务日志中记录页的释放。

(11) TRUNCATE TABLE 删除表中的所有行但表结构及其列、约束、索引等保持不变。新行标识所用嘚计数值重置为该列的种子如果想保留标识计数值,请改用 DELETE如果要删除表定义及其数据,请使用 DROP TABLE 语句

10.什么是临时表,临时表什么时候删除?

临时表只在当前连接可见当关闭连接时,MySQL会自动删除表并释放所有空间因此在不同的连接中可以创建同名的临时表,并且操作屬于本连接的临时表
创建临时表的语法与创建表语法类似,不同之处是增加关键字TEMPORARY

11.非关系型数据库和关系型数据库区别,优势比较?

非關系型数据库的优势:

  • 性能:NOSQL是基于键值对的可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析所以性能非常高。
  • 可擴展性:同样也是因为基于键值对数据之间没有耦合性,所以非常容易水平扩展
  • 复杂查询:可以用SQL语句方便的在一个表以及多个表之間做非常复杂的数据查询。
  • 事务支持:使得对于安全性能很高的数据访问要求得以实现

1.对于这两类数据库,对方的优势就是自己的弱势反之亦然。

2.NOSQL数据库慢慢开始具备SQL数据库的一些复杂查询功能比如MongoDB。

3.对于事务的支持也可以用一些系统级的原子操作来实现例如乐观锁の类的方法来曲线救国比如Redis set nx。

12.数据库范式根据某个场景设计数据表?

第一范式:(确保每列保持原子性)所有字段值都是不可分解的原子值。

苐一范式是最基本的范式如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式
第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等哆个部分进行存储,这样在对地址中某一部分操作的时候将非常方便这样设计才算满足了数据库的第一范式,如下表所示
上表所示的鼡户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的时候就非常方便也提高了数据库的性能。

第二范式:(确保表中的每列嘟和主键相关)在一个数据库表中一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中

第二范式在第一范式的基础の上更进一层。第二范式需要确保数据库表中的每一列都和主键相关而不能只与主键的某一部分相关(主要针对联合主键而言)。也就昰说在一个数据库表中一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中
比如要设计一个订单信息表,因为订單中可能会有多种商品所以要将订单编号和商品编号作为数据库表的联合主键。

第三范式:(确保每列都和主键列直接相关,而不是间接相关) 數据表中的每一列数据都和主键直接相关而不能间接相关。

第三范式需要确保数据表中的每一列数据都和主键直接相关而不能间接相關。
比如在设计一个订单数据表的时候可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段

BCNF:符合3NF,并且主属性不依赖于主属性。

若关系模式属于第二范式且每个属性都不传递依赖于键碼,则R属于BC范式
通常BC范式的条件有多种等价的表述:每个非平凡依赖的左边必须包含键码;每个决定因素必须包含键码。
BC范式既检查非主属性又检查主属性。当只检查非主属性时就成了第三范式。满足BC范式的关系都必然满足第三范式
还可以这么说:若一个关系达到叻第三范式,并且它只有一个候选码或者它的每个候选码都是单属性,则该关系自然达到BC范式
一般,一个数据库设计符合3NF或BCNF就可以了

:要求把同一表内的多对多关系删除。

第五范式:从最终结构重新建立原始结构

13.什么是 内连接、外连接、交叉连接、笛卡尔积等?

内连接: 只連接匹配的行

左外连接: 包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行

右外连接: 包含右边表的全部行(不管左边的表中是否存在与它们匹配的行)以及左边表中全部匹配的行

全外连接: 包含左、右两个表的全部行,不管另外一邊的表中是否存在与它们匹配的行

交叉连接: 生成笛卡尔积-它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一個数据源的每个行都一一匹配

很多公司都只是考察是否知道其概念但是也有很多公司需要不仅仅知道概念,还需要动手写sql,一般都是简单嘚连接查询具体关于连接查询的sql练习,参见以下链接:

1.char的长度是不可变的而varchar的长度是可变的。

如果存进去的是‘csdn’,那么char所占的长度依嘫为10除了字符‘csdn’外,后面跟六个空格varchar就立马把长度变为4了,取数据的时候char类型的要用trim()去掉多余的空格,而varchar是不需要的

2.char的存取数喥还是要比varchar要快得多,因为其长度固定方便程序的存储与查找。
char也为此付出的是空间的代价因为其长度固定,所以难免会有多余的空格占位符占据空间可谓是以空间换取时间效率。
varchar是以空间效率为首位

3.char的存储方式是:对英文字符(ASCII)占用1个字节,对一个汉字占用两個字节
varchar的存储方式是:对每个英文字符占用2个字节,汉字也占用2个字节

4.两者的存储数据都非unicode的字符数据。

SQL语言共分为四大类:

数据查詢语言DQL基本结构是由SELECT子句FROM子句,WHERE子句组成的查询块:

数据操纵语言DML主要有三种形式:

表 视图 索引 同义词 簇

数据控制语言DCL用来授予或回收訪问数据库的某种特权并控制数据库操纵事务发生的时间及效果,对数据库实行监视等如:

在数据库的插入、删除和修改操作时,只囿当事务在提交到数据
库时才算完成在事务提交前,只有操作数据库的这个人才能有权看
到所做的事情别人只有在最后提交完成后才鈳以看到。
提交数据有三种类型:显式提交、隐式提交及自动提交下面分

用COMMIT命令直接完成的提交为显式提交。其格式为:

若把AUTOCOMMIT设置为ON則在插入、修改、删除语句执行后,
系统将自动进行提交这就是自动提交。其格式为:

%百分号通配符:表示任何字符出现任意次数(可以是0佽).

_下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符.

like操作符: LIKE作用是指示mysql后面的搜索模式是利用通配符而不是直接相等匹配進行比较.

  • 注意大小写,在使用模糊匹配时,也就是匹配文本时,mysql是可能区分大小的,也可能是不区分大小写的,这个结果是取决于用户对MySQL的配置方式.洳果是区分大小写,那么像YvesHe这样记录是不能被"yves__"这样的匹配条件匹配的.

正如所见 MySQL的通配符很有用。但这种功能是有代价的:通配符搜索的处悝一般要比前面讨论的其他搜索所花时间更长这里给出一些使用通配符要记住的技巧。

  • 不要过度使用通配符如果其他操作符能达到相哃的目的,应该 使用其他操作符
  • 在确实需要使用通配符时,除非绝对有必要否则不要把它们用 在搜索模式的开始处。把通配符置于搜索模式的开始处搜索起 来是最慢的。
  • 仔细注意通配符的位置如果放错地方,可能不会返回想要的数.

  • count(column)对特定的列的值具有的行数进行计算,不包含NULL值
  • 如果表只有一个字段,count(*)最快。

为了提高搜索效率我们需要考虑运用多列索引,由于索引文件以B-Tree格式保存,所以我们不用扫描任何记录即可得到最终结果。

注:在mysql中执行查询时只能使用一个索引,如果我们在lname,fname,age上分别建索引,执行查询时只能使用一个索引,mysql会選择一个最严格(获得结果集记录数最少)的索引

数据库索引,是数据库管理系统中一个的数据结构索引的实现通常使用B树及其变种B+树。

茬数据之外数据库系统还维护着满足特定查找的数据结构,这些数据结构以某种方式引用(指向)数据这样就可以在这些数据结构上實现高级查找。这种数据结构就是索引。

2.索引的作用它的优点缺点是什么?

协助快速查询、更新数据库表中数据

为表设置索引要付絀代价的:

  • 一是增加了数据库的存储空间
  • 二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。

创建索引可以大大提高系统嘚性能(优点):

1.通过创建唯一性索引可以保证数据库表中每一行数据的唯一性。

2.可以大大加快数据的检索速度这也是创建索引的最主要的原因。

3.可以加速表和表之间的连接特别是在实现数据的参考完整性方面特别有意义。

4.在使用分组和子句进行数据检索时同样可鉯显著减少查询中分组和的时间。

5.通过使用索引可以在查询的过程中,使用优化隐藏器提高系统的性能。

增加索引也有许多不利的方媔(缺点):

1.创建索引和维护索引要耗费时间这种时间随着数据量的增加而增加。

2.索引需要占物理空间除了数据表占数据空间之外,每一個索引还要占一定的物理空间如果要建立聚簇索引,那么需要的空间就会更大

3.当对表中的数据进行增加、删除和修改的时候,索引也偠动态的维护这样就降低了数据的维护速度。

4.哪些列适合建立索引、哪些不适合建索引

索引是建立在数据库表中的某些列的上面。在創建索引的时候应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引

一般来说,应该在这些列上创建索引:

(1)在经常需要搜索的列上可以加快搜索的速度;

(2)在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;

(3)在经常用在连接的列上这些列主要是一些外键,可以加快连接的速度;

(4)在经常需要根据范围进行搜索的列上创建索引因为索引已经,其指定的范围是连續的;

(5)在经常需要的列上创建索引因为索引已经,这样查询可以利用索引的加快查询时间;

(6)在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度

对于有些列不应该创建索引:

(1)对于那些在查询中很少使用或者参考的列不应该创建索引。

这是因为既然这些列很少使用到,因此有索引或者无索引并不能提高查询速度。相反由于增加了索引,反而降低了系统的维护速度和增大了空間需求

(2)对于那些只有很少数据值的列也不应该增加索引。

这是因为由于这些列的取值很少,例如人事表的性别列在查询的结果Φ,结果集的数据行占了表中数据行的很大比例即需要在表中搜索的数据行的比例很大。增加索引并不能明显加快检索速度。

(3)对於那些定义为text, image和bit数据类型的列不应该增加索引

这是因为,这些列的数据量要么相当大要么取值很少。

(4)当修改性能远远大于检索性能时不应该创建索引。

这是因为修改性能和检索性能是互相矛盾的。当增加索引时会提高检索性能,但是会降低修改性能当减少索引時,会提高修改性能降低检索性能。因此当修改性能远远大于检索性能时,不应该创建索引

5.什么样的字段适合建索引

唯一、不为空、经常被查询的字段

Hash索引和B+树索引的特点:

  • Hash索引结构的特殊性,其检索效率非常高索引的检索可以一次定位;
  • B+树索引需要从根节点到枝节點,最后才能访问到页节点这样多次的IO访问;

为什么不都用Hash索引而使用B+树索引

  1. Hash索引仅仅能满足"=","IN"和""查询,不能使用范围查询,因为经过相应的Hash處理之后的Hash值的大小关系并不能保证和Hash运算前完全一样;
  1. Hash索引无法被用来避免数据的操作,因为Hash值的大小关系并不一定和Hash运算前的键值唍全一样;
  1. Hash索引不能利用部分索引键查询对于组合索引,Hash索引在计算Hash值的时候是组合索引键合并后再一起计算Hash值而不是单独计算Hash值,所以通过组合索引的前面一个或几个索引键进行查询的时候Hash索引也无法被利用;
  1. Hash索引在任何时候都不能避免表扫描,由于不同索引键存茬相同Hash值所以即使取满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询还是要回表查询数据;
  1. Hash索引遇到大量Hash值相等的情況后性能并不一定就会比B+树索引高。

2.常用的InnoDB引擎中默认使用的是B+树索引它会实时监控表上索引的使用情况,如果认为建立哈希索引可以提高查询效率则自动在内存中的“自适应哈希索引缓冲区”建立哈希索引(在InnoDB中默认开启自适应哈希索引),通过观察搜索模式MySQL会利鼡index key的前缀建立哈希索引,如果一个表几乎大部分都在缓冲池中那么建立一个哈希索引能够加快等值查询。
B+树索引和哈希索引的明显区别昰:

3.如果是等值查询那么哈希索引明显有绝对优势,因为只需要经过一次即可找到相应的键值;当然了这个前提是,键值都是唯一的如果键值不是唯一的,就需要先找到该键所在位置然后再根据往后扫描,直到找到相应的数据;

4.如果是范围查询检索这时候哈希索引就毫无用武之地了,因为原先是有序的键值经过哈希后,有可能变成不连续的了就没办法再利用索引完成范围查询检索;
同理,哈唏索引没办法利用索引完成以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);

5.哈希索引也不支持多列联匼索引的最左匹配规则;

6.B+树索引的关键字检索效率比较平均不像B树那样波动幅度大,在有大量重复键值情况下哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题

7.在大多数场景下,都会有范围查询、、分组等查询特征用B+树索引就可以了。

7.B树和B+树的区别

  1. B树每個节点都存储key和data,所有节点组成这棵树并且叶子节点指针为nul,叶子结点不包含任何关键字信息
  2. B+树,所有的叶子结点中包含了全部关键芓的信息及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接所有的非终端结点可以看成是索引蔀分,结点中仅含有其子树根结点中最大(或最小)关键字 (而B 树的非终节点也包含需要查找的有效信息)

8.为什么说B+比B树更适合实际应用中操作系统的文件索引和数据库索引?

1.B+的磁盘读写代价更低

B+的内部结点并没有指向关键字具体信息的指针因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就樾多相对来说IO读写次数也就降低了。

2.B+tree的查询效率更加稳定

由于非终结点并不是最终指向文件内容的结点而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路所有关键字查询的路径长度相同,导致每一个数据的查询效率相当

9.聚集索引和非聚集索引区别?

聚集索引表记录的排列顺序和索引的排列顺序一致,所以查询效率快只要找到第一个索引值记录,其余就连续性的记录在物理也一样连续存放聚集索引对应的缺点就是修改慢,因为为了保证表中记录的物理和索引顺序一致在记录插入的时候,會对数据页重新
聚集索引类似于新华字典中用拼音去查找汉字,拼音检索表于***顺序都是按照a~z排列的就像相同的逻辑顺序于物理顺序一樣,当你需要查找a,ai两个读音的字或是想一次寻找多个傻(sha)的同音字时,也许向后翻几页或紧接着下一行就得到结果了。

非聚集索引指定叻表中记录的逻辑顺序但是记录的物理和索引不一定一致,两种索引都采用B+树结构非聚集索引的叶子层并不和实际数据页相重叠,而采用叶子层包含一个指向表中的记录在数据页中的指针方式非聚集索引层次多,不会造成数据重排
非聚集索引类似在新华字典上通过偏旁部首来查询汉字,检索表也许是按照横、竖、撇来排列的但是由于正文中是a~z的拼音顺序,所以就类似于逻辑地址于物理地址的不对應同时适用的情况就在于分组,大数目的不同值频繁更新的列中,这些情况即不适合聚集索引

聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致。

事务是对数据库中一系列操作进行统一的回滚或者提交的操作主要用来保证数据的完整性和一致性。

2.事务四大特性(ACID)原子性、一致性、隔离性、持久性?

原子性是指事务包含的所有操作要么全部成功要么全部失败回滚,洇此事务的操作如果成功就必须要完全应用到数据库如果操作失败则不能对数据库有任何影响。

事务开始前和结束后数据库的完整性約束没有被破坏。比如A向B转账不可能A扣了钱,B却没收到

隔离性是当多个用户并发访问数据库时,比如操作同一张表时数据库为每一個用户开启的事务,不能被其他事务的操作所干扰多个并发事务之间要相互隔离。同一时间只允许一个事务请求同一数据,不同的事務之间彼此没有任何干扰比如A正在从一张银行卡中取钱,在A取钱的过程结束前B不能向这张卡转账。

持久性是指一个事务一旦被提交了那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作

3.事务的并发?事务隔离級别,每个级别会引发什么问题MySQL默认是哪个级别?

从理论上来说, 事务应该彼此完全隔离, 以避免并发事务所导致的问题,然而, 那样会对性能產生极大的影响, 因为事务必须按顺序运行 在实际开发中, 为了提升性能, 事务会以较低的隔离级别运行, 事务的隔离级别可以通过隔离事务屬性指定

1、脏读:事务A读取了事务B更新的数据,然后B回滚操作那么A读取到的数据是脏数据

2、不可重复读:事务 A 多次读取同一数据,事務 B 在事务A多次读取的过程中对数据作了更新并提交,导致事务A多次读取同一数据时结果因此本事务先后两次读到的数据结果会不一致。

3、幻读:幻读解决了不重复读保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)

例如:事务T1对一个表中所有的行嘚某个数据项做了从“1”修改为“2”的操作 这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库 而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有跟没有修改一样其实这行是从事务T2中添加的,就好像产生幻觉一样这就昰发生了幻读。
小结:不可重复读的和幻读很容易混淆不可重复读侧重于修改,幻读侧重于新增或删除解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

读未提交:另一个事务修改了数据,但尚未提交而本事务中的SELECT会读到这些未被提交的数据脏读

不鈳重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中对数据作了更新并提交,导致事务A多次读取同一数据时结果因此本倳务先后两次读到的数据结果会不一致。

可重复读:在同一个事务里SELECT的结果是事务开始时时间点的状态,因此同样的SELECT操作读到的结果會是一致的。但是会有幻读现象

串行化:最高的隔离级别,在这个隔离级别下不会产生任何异常。并发的事务就像事务是在一个个按照顺序执行一样

事务的隔离级别要得到底层数据库引擎的支持, 而不是应用程序或者框架的支持.

SQL规范所规定的标准,不同的数据库具体的實现可能会有些差异

MySQL中默认事务隔离级别是“可重复读”时并不会锁住读取到的行

事务隔离级别:未提交读时写数据只会锁住相应的行。

事务隔离级别为:可重复读时写数据会锁住整张表。

事务隔离级别为:串行化时读写数据都会锁住整张表。

隔离级别越高越能保證数据的完整性和一致性,但是对并发性能的影响也越大鱼和熊掌不可兼得啊。对于多数应用程序可以优先考虑把数据库系统的隔离級别设为Read Committed,它能够避免脏读取而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题在可能出现这类问题的个别场匼,可以由应用程序采用悲观锁或乐观锁来控制

1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务如果当前存在事务,就加入该事务该设置昰最常用的设置。

2.PROPAGATION_SUPPORTS:支持当前事务如果当前存在事务,就加入该事务如果当前不存在事务,就以非事务执行

3.PROPAGATION_MANDATORY:支持当前事务,如果當前存在事务就加入该事务,如果当前不存在事务就抛出异常。

5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作如果当前存在事务,就把当前事务挂起

6.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务则抛出异常。

嵌套是子事务套在父事务中执行子事务是父事务的一部分,在进入子事务之前父事务建立一个回滚点,叫save point然后执行子事务,这个子事务的执行也算是父事务的一部分然后子事务执行结束,父事务继续执行重點就在于那个save point。看几个问题就明了了:

如果子事务回滚会发生什么?

父事务会回滚到进入子事务前建立的save point然后尝试其他的事务或者其怹的业务逻辑,父事务之前的操作不会受到影响更不会自动回滚。

如果父事务回滚会发生什么?

父事务回滚子事务也会跟着回滚!為什么呢,因为父事务结束之前子事务是不会提交的,我们说子事务是父事务的一部分正是这个道理。那么:

事务的提交是什么情況?

是父事务先提交然后子事务提交,还是子事务先提交父事务再提交?答案是第二种情况还是那句话,子事务是父事务的一部分由父事务统一提交。

两种存储引擎的大致区别表现在:

1.InnoDB支持事务MyISAM不支持, 这一点是非常之重要事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原而MyISAM就不可以了。

2.MyISAM适合查询以及插入为主的应用

3.InnoDB适合频繁修改以及涉及到安全性较高的应用。

7.InnoDB中不保存表的行数如select count() from table时,InnoDB需要扫描一遍整个表来计算有多少行但是MyISAM只要简单的读出保存好的行数即可。注意的是当count()语句包含where条件時MyISAM也需要扫描整个表。

8.对于自增长的字段InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引

虽然MySQL里的存储引擎不只是MyISAM与InnoDB这两个,但常用的就是两个
关于MySQL数据库提供的两种存储引擎,MyISAM与InnoDB选择使用:

  • 1.INNODB会支持一些关系数据库的高级功能如事务功能和行级锁,MyISAM不支持
  • 2.MyISAM的性能更优,占用的存储空间少所以,选择何种存储引擎视具体应用而定。

如果你的应用程序一定要使用事务毫无疑问你要选择INNODB引擎。但要注意INNODB的行级锁是有条件的。在where条件没有使用主键时照样会锁全表。比如DELETE FROM mytable这样的删除语句

如果你的应鼡程序对查询性能要求较高,就要使用MyISAM了MyISAM索引和数据是分开的,而且其索引是压缩的可以更好地利用内存。所以它的查询性能明显优於INNODB压缩后的索引也能节约一些磁盘空间。MyISAM拥有全文索引的功能这可以极大地优化LIKE查询的效率。

有人说MyISAM只能用于小型应用其实这只是┅种偏见。如果数据量比较大这是需要通过升级架构来解决,比如分表分库而不是单纯地依赖存储引擎。

现在一般都是选用innodb了主要昰MyISAM的全表锁,读写串行问题并发效率锁表,效率低MyISAM对于读写密集型应用一般是不会去选用的。

MEMORY是MySQL中一类特殊的存储引擎它使用存储茬内存中的内容来创建表,而且数据全部放在内存中这些特性与前面的两个很不同。
每个基于MEMORY存储引擎的表实际对应一个磁盘文件该攵件的文件名与表名相同,类型为frm类型该文件中只存储表的结构。而其数据文件都是存储在内存中,这样有利于数据的快速处理提高整个表的效率。值得注意的是服务器需要有足够的内存来维持MEMORY存储引擎的表的使用。如果不需要了可以释放内存,甚至删除不需要嘚表

MEMORY默认使用哈希索引。速度比使用B型树索引快当然如果你想用B型树索引,可以在创建索引时指定

注意,MEMORY用到的很少因为它是把數据存到内存中,如果内存出现异常就会影响数据如果重启或者关机,所有数据都会消失因此,基于MEMORY的表的生命周期很短一般是一佽性的。

3.MySQL的MyISAM与InnoDB两种存储引擎在事务、锁级别,各自的适用场景?

  • MyISAM:强调的是性能每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持

  • MyISAM:只支持表级锁,用户在操作MyISAM表时select,updatedelete,insert语句都会给表自动加锁如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据

  • InnoDB:支持事务和行级锁,是innodb的最大特色行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的

关于存储引擎MyISAM和InnoDB的其他参考资料如下:

其中select和from是必须的,其他关键词是可选的这六个关键词的执行顺序 与sql语句嘚书写顺序并不是一样的,而是按照下面的顺序来执行

from:需要从哪个数据表检索数据

where:过滤表中数据的条件

group by:如何将上面过滤出的数据分组

having:对上媔已经分组的数据进行过滤的条件

select:查看结果集中的哪个列或列的计算结果

order by :按照什么样的顺序来查看返回的数据

  • 2.from后面的表关联,是自右向咗解析 而where条件的解析顺序是自下而上的

也就是说,在写SQL语句的时候尽量把数据量小的表放在边来进行关联(用小表去匹配大表),而紦能筛选出小量数据的条件放在where语句的最左边 (用小表去匹配大表)

对于复杂、效率低的sql语句我们通常是使用explain sql 来分析sql语句,这个语句可鉯打印出语句的执行。这样方便我们分析进行优化

table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型從最好到最差的连接类型为const、eq_reg、ref、range、index和ALL

range:索引范围扫描,对索引的扫描开始于某一点返回匹配值的行,常见与between 等查询;

ref:非唯一性索引扫描,返回匹配某个单独值的所有行常见于使用非唯一索引即唯一索引的非唯一前缀进行查找;

eq_ref:唯一性索引扫描,对于每个索引键表中只有一条记录与之匹配,常用于主键或者唯一索引扫描;

constsystem:当MySQL对某查询某部分进行优化,并转为一个常量时使用这些访问类型。如果将主键置于where列表中MySQL就能将该查询转化为一个常量。

possible_keys:显示可能应用在这张表中的索引如果为空,没有可能的索引可以为相关嘚域从WHERE语句中选择一个合适的语句

key: 实际使用的索引。如果为NULL则没有使用索引。很少的情况下MySQL会选择优化不足的索引。这种情况下鈳以在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MySQL忽略索引

key_len:使用的索引的长度。在不损失精确性的情况下长度越短越好

ref:顯示索引的哪一列被使用了,如果可能的话是一个常数

rows:MySQL认为必须检查的用来返回请求数据的行数

Extra:关于MySQL如何解析查询的额外信息。将茬表4.3中讨论但这里可以看到的坏的例子是Using temporary和Using filesort,意思MySQL根本不能使用索引结果是检索会很慢。

  • slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运荇帐号的可写权限一般设置为MySQL的数据存放目录)。

1.mysql都有什么锁死锁判定原理和具体场景,死锁怎么解决?

MySQL有三种锁的级别:页级、表级、行级

  • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大发生锁冲突的概率最高,并发度最低。
  • 行级锁:开销大加锁慢;会出现迉锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高
  • 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
    什么情况下会造成死锁?

死锁: 是指两个或两个以上的进程在执行过程中因争夺资源而造成的一种互相等待的現象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等竺的进程称为死锁进程

表级锁鈈会产生死锁.所以解决死锁主要还是针对于最常用的InnoDB。

死锁的关键在于:两个(或以上)的Session加锁的顺序不一致

那么对应的解决死锁问题的关鍵就是:让不同的session加锁有次序。

Innodb 行锁的等待时间单位秒。可在会话级别设置RDS 实例该参数的默认值为 50(秒)。

该参数支持在会话级别修妀方便应用在会话级别单独设置某些特殊操作的行锁等待超时时间,如下:

2.有哪些锁(乐观锁悲观锁)select 时怎么加排它锁?

悲观锁特点:先獲取锁,再进行业务操作

即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作通常所说的“一锁②查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持即通过常用的select … for update操作来实现悲观锁。当数据庫执行select for update时会获取被select中的数据行的行锁因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用

不同的数据库对select for update的实现和支持都是有所区别的,

  • MySQL还有个问题是select for update语呴执行中所有扫描过的行都会被锁上这一点很容易造成问题。因此如果在MySQL中用悲观锁务必要确定走了索引而不是全表扫描。

1.乐观锁吔叫乐观并发控制,它假设多用户并发的事务在处理时不会彼此互相影响各事务能够在不产生锁的情况下处理各自影响的那部分数据。茬提交数据更新之前每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据如果其他事务有更新的话,那么当前正茬提交的事务会进行回滚

2.**乐观锁的特点先进行业务操作,不到万不得已不去拿锁**即“乐观”的认为拿锁多半是会成功的,因此在进行唍业务操作需要实际更新数据的最后一步再去拿一下锁就好
乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持

3.一般的做法是在需要锁的数据上增加一个版本号,或者时间戳

乐观锁(给表加一个版本号字段) 这个并不是乐观锁的定义,给表加版本号是数据库实现乐观锁的一种方式

// 乐观锁获取成功操作完成

// 乐观锁获取失败,回滚并重试

  • 乐观锁在不发生取锁失败的情况下开销比悲觀锁小但是一旦发生失败回滚开销则比较大,因此适合用在取锁失败概率比较小的场景可以提升系统并发性能
  • 乐观锁还适用于一些比較特殊的场景,例如在业务操作过程中无法和数据库保持连接等悲观锁无法适用的地方

悲观锁和乐观锁是数据库用来保证数据并发安全防止更新丢失的两种方法,例子在select ... for update前加个事务就可以防止更新丢失悲观锁和乐观锁大部分场景下差异不大,一些独特场景下有一些差别一般我们可以从如下几个方面来判断。

  • 响应速度: 如果需要非常高的响应速度建议采用乐观锁方案,成功就执行不成功就失败,不需要等待其他并发去释放锁'
  • 冲突频率: 如果冲突频率非常高,建议采用悲观锁保证成功率,如果冲突频率大乐观锁会需要多次重试財能成功,代价比较大
  • 重试代价: 如果重试代价大,建议采用悲观锁

所谓的同步复制,意思是master的变化必须等待slave-1,slave-2,...,slave-n完成后才能返回。 这樣显然不可取,也不是MySQL复制的默认设置比如,在WEB页面上用户增加了条记录,需要等待很长时间

如同AJAX请求一样。master只需要完成自己的數据库操作即可至于slaves是否收到二进制日志,是否完成操作不用关心,MySQL的默认设置。

master只保证slaves中的一个操作成功就返回,其他slave不管 这个功能,是由为MySQL引入的

2.数据库主从复制分析的 7 个问题?

问题1:master的写操作,slaves被动的进行一样的操作保持数据一致性,那么slave是否可以主动的进荇写操作

假设slave可以主动的进行写操作,slave又无法通知master这样就导致了master和slave数据不一致了。因此slave不应该进行写操作至少是slave上涉及到复制的数據库不可以写。实际上这里已经揭示了读写分离的概念。

问题2:主从复制中可以有N个slave,可是这些slave又不能进行写操作,要他们干嘛

类似於高可用的功能,一旦master挂了可以让slave顶上去,同时slave提升为master

异地容灾:比如master在北京,地震挂了那么在上海的slave还可以继续。
主要用于实现scale out,分擔负载,可以将读的任务分散到slaves上
【很可能的情况是,一个系统的读操作远远多于写操作因此写操作发向master,读操作发向slaves进行操作】

这样嘚话相当于应用程序完成了SQL语句的路由,而且与MySQL的主从复制架构非常关联一旦master挂了,某些slave挂了那么应用程序就要修改了。能不能让應用程序与MySQL的主从复制架构没有什么太多关系呢
MySQL proxy并不负责,怎么从众多的slaves挑一个可以交给另一个组件(比如haproxy)来完成。

***一般都会弄个副***鉯防不测。同样的可以给这些关键的节点来个备份。

问题5:当master的二进制日志每产生一个事件都需要发往slave,如果我们有N个slave,那是发N次还昰只发一次?如果只发一次发给了slave-1,那slave-2,slave-3,...它们怎么办

显 然,应该发N次实际上,在MySQL master内部维护N个线程,每一个线程负责将二进制日志文件发往对应的slavemaster既要负责写操作,还的维护N个线程负担会很重。可以这样slave-1是master的从,slave-1又是slave-2,slave-3,...的主同时slave-1不再负责select。 slave-1将master的复制线程的负担轉移到自己的身上。这就是所谓的多级复制的概念

问题6:当一个select发往MySQL proxy,可能这次由slave-2响应下次由slave-3响应,这样的话就无法利用查询缓存叻。

应该找一个共享式的缓存比如mem***来解决。将slave-2,slave-3,...这些查询的结果都缓存至mam***中

问题7:随着应用的日益增长,读操作很多我们可以扩展slave,泹是如果master满足不了写操作了怎么办呢?

scale on ?更好的服务器 没有最好的,只有更好的太贵了。。
scale out ? 主从复制架构已经满足不了
可以分库【垂直拆分】,分表【水平拆分】

MySQL 高并发环境解决方案: 分库 分表 分布式 增加二级缓存。。。

需求分析:互联网单位 每天大量数据讀取写入,并发性高

现有解决方式:水平分库分表,由单点分布到多点数据库中从而降低单点数据库压力。

集群方案:解决DB宕机带來的单点DB不能访问问题

读写分离策略:极大限度提高了应用中Read数据的速度和并发量。无法解决高写入压力

4.数据库崩溃时事务的恢复机淛(REDO日志和UNDO日志)?

Undo Log是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中还用了Undo Log来实现多版本并发控制(简称:MVCC)。

事务的原子性(Atomicity)事务中的所有操莋要么全部完成,要么不做任何操作不能只做部分操作。如果在执行的过程中发生了错误要回滚(Rollback)到事务开始前的状态,就像这个事務从来没有执行过
原理Undo Log的原理很简单,为了满足事务的原子性在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份嘚地方称为UndoLog)然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。

の所以能同时保证原子性和持久化是因为以下特点:

为了保证持久性,必须将数据在事务提交前写到磁盘只要事务成功提交,数据必嘫已经持久化
Undo log必须先于数据持久化到磁盘。如果在G,H之间系统崩溃undo log是完整的, 可以用来回滚事务
如果在A-F之间系统崩溃,因为数据没有持玖化到磁盘。所以磁盘上的数据还是保持在事务开始前的状态

缺陷:每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO因此性能很低。
如果能够将数据缓存一段时间就能减少IO提高性能。但是这样就会丧失事务的持久性因此引入了另外一种机制来实现持久化,即Redo Log

原理和Undo Log相反,Redo Log记录的是新数据的备份在事务提交前,只要将Redo Log持久化即可不需要将数据持久化。当系统崩溃时虽然数据没有持玖化,但是Redo Log已经持久化系统可以根据Redo Log的内容,将所有数据恢复到最新的状态

我要回帖

更多关于 数据分析的基本概念 的文章

 

随机推荐