-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
84 lines (46 loc) · 45.2 KB
/
atom.xml
File metadata and controls
84 lines (46 loc) · 45.2 KB
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Lee's Blog</title>
<subtitle>Study Notes</subtitle>
<link href="http://leee9.cn/atom.xml" rel="self"/>
<link href="http://leee9.cn/"/>
<updated>2021-12-22T21:18:42.766Z</updated>
<id>http://leee9.cn/</id>
<author>
<name>Lee</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>数据库系统概论 1.绪论</title>
<link href="http://leee9.cn/2021/12/23/1.%E7%BB%AA%E8%AE%BA/"/>
<id>http://leee9.cn/2021/12/23/1.%E7%BB%AA%E8%AE%BA/</id>
<published>2021-12-22T21:08:44.500Z</published>
<updated>2021-12-22T21:18:42.766Z</updated>
<content type="html"><![CDATA[<p>第一章的概念非常多,很多概念都反复出现,需要捋清楚其中的逻辑关系,比如1.2.3中数据模型的基本组成的数据结构,数据操纵与完整性约束,在后面三个具体的数据模型中都分别具体地进行说明。第一章整个是对一些概念的入门和综述内容,比如关系模型在第二章关系数据库中也会给出更详细的介绍。</p><span id="more"></span><h2 id="1-1-数据库系统概述"><a href="#1-1-数据库系统概述" class="headerlink" title="1.1 数据库系统概述"></a>1.1 数据库系统概述</h2><h3 id="1-1-1-数据库的4个基本概念"><a href="#1-1-1-数据库的4个基本概念" class="headerlink" title="1.1.1 数据库的4个基本概念"></a>1.1.1 数据库的4个基本概念</h3><ol><li><p>数据(Data)</p><ul><li>数据与其语义是不可分的</li></ul></li><li><p>数据库(Database)</p><ul><li>数据库的定义<ul><li>数据库是<strong>长期存储</strong>在计算机内、<strong>有组织</strong>的、<strong>可共享</strong>的<strong>大量</strong>数据的集合</li></ul></li><li>数据库的基本特征<ul><li>数据按照一定的<strong>数据模型</strong>组织、描述和储存</li><li>可为各种用户<strong>共享、冗余度较小、易扩展</strong></li><li><strong>数据独立性较高</strong></li></ul></li></ul></li><li><p>数据库管理系统(DBMS)</p><ul><li>DBMS是位于用户与操作系统之间的一层<strong>数据管理软件</strong>,是基础软件,也是一个<strong>大型复杂的软件系统</strong>,可以科学地<strong>组织</strong>和<strong>存储</strong>数据、高效地<strong>获取和维护</strong>数据</li><li>数据定义功能<ul><li>DDL数据定义语言定义数据库中的数据对象</li></ul></li><li>数据组织、存储和管理<ul><li>分类组织、存储和管理各类数据</li><li>确定组织数据的文件结构和存取方式</li><li>实现数据之间的联系</li><li>提供多种存取方式提高存取效率</li></ul></li><li>数据操纵功能<ul><li>DML数据操纵语言实现对数据库的基本操作:查询、插入、删除和修改</li></ul></li><li>数据库的事务管理和运行管理<ul><li>数据库在建立、运行和维护时由数据库管理系统<strong>统一管理和控制</strong>,保证事务正常运行</li><li>保证数据的安全性、完整性、多用户并发使用</li><li>发生故障后系统恢复</li></ul></li><li>数据库的建立和维护功能<ul><li>数据库初始数据的装载和转换</li><li>数据库转储、恢复功能</li><li>数据库的重组织</li><li>性能监视、分析等</li></ul></li><li>其他功能<ul><li>数据库管理系统和网络中其他软件系统的通信</li><li>数据库管理系统之间的数据转换</li><li>异构数据库之间的互访和互操作</li></ul></li></ul></li><li><p>数据库系统(DBS)</p><ul><li><p>DBS是指在计算机系统种引入数据库后的系统构成,不引起混淆的情况下常常简称为数据库</p></li><li><p>数据库系统的构成</p><ul><li><p>数据库</p></li><li><p>数据库管理系统(及其应用开发工具)</p></li><li><p>应用程序</p></li><li><p>数据库管理员(DBA)</p></li></ul></li></ul></li></ol><h3 id="1-1-2-数据库管理技术的产生和发展"><a href="#1-1-2-数据库管理技术的产生和发展" class="headerlink" title="1.1.2 数据库管理技术的产生和发展"></a>1.1.2 数据库管理技术的产生和发展</h3><ul><li><p>数据管理:对数据进行<strong>分类、组织、编码、存储、检索和维护</strong>。数据管理时数据处理的中心问题</p></li><li><p>数据管理技术的发展过程</p><table><thead><tr><th></th><th>人工管理阶段</th><th>文件系统阶段</th><th>数据库系统阶段</th></tr></thead><tbody><tr><td>数据的管理者</td><td>用户(程序员),数据不保存</td><td>文件系统,数据可长期保存</td><td>数据库管理系统</td></tr><tr><td>数据面向的对象</td><td>某一应用程序</td><td>某一应用</td><td>现实世界,企业等</td></tr><tr><td>数据的共享程度</td><td>无共享,冗余度极大</td><td>共享性差,冗余度大</td><td>共线性高,冗余度小</td></tr><tr><td>数据的独立性</td><td>不独立</td><td>独立性差</td><td>具有较高的物理独立性和一定的逻辑独立性</td></tr><tr><td>数据的结构化</td><td>无结构</td><td>记录内由结构,整体无结构</td><td>整体结构化,由数据模型描述</td></tr><tr><td>数据控制能力</td><td>应用程序自己控制</td><td>应用程序自己控制</td><td>由DBMS提供数据安全性、完整性、并发控制和恢复能力</td></tr></tbody></table></li></ul><h3 id="1-1-3-数据库系统的特点"><a href="#1-1-3-数据库系统的特点" class="headerlink" title="1.1.3 数据库系统的特点"></a>1.1.3 数据库系统的特点</h3><ul><li>数据结构化<ul><li>不仅数据内部结构化,整体也是结构化,数据之间有联系</li><li>数据记录可以变长</li><li>数据的最小存取单位是数据项</li><li><strong>数据用数据模型描述</strong>,无需应用程序定义</li></ul></li><li>数据的共享性高,冗余度低且易扩充</li><li>数据的独立性高<ul><li><strong>物理独立性</strong>:用户的应用程序与数据库中的数据的物理存储是相互独立的,当数据的物理存储改变了,应用程序不用变</li><li><strong>逻辑独立性</strong>:用户的应用程序域数据库的逻辑结构是相互独立的。数据的逻辑结构改变了,应用程序不用改变</li><li>数据独立性由DBMS的二级映像功能来保证</li></ul></li><li>数据由数据库管理系统统一管理和控制<ol><li>数据的安全性(Security)维护</li><li>数据的完整性(Integrity)检查</li><li>并发控制(Concurrency Control)</li><li>数据库回复(Recovery)</li></ol></li></ul><h2 id="1-2-数据模型"><a href="#1-2-数据模型" class="headerlink" title="1.2 数据模型"></a>1.2 数据模型</h2><p><strong>数据模型是对现实世界数据特征的抽象</strong>,即现实世界的模拟,数据模型是数据库系统的<strong>核心和基础</strong></p><h3 id="1-2-1-两类数据模型"><a href="#1-2-1-两类数据模型" class="headerlink" title="1.2.1 两类数据模型"></a>1.2.1 两类数据模型</h3><p>数据模型分为两个不同层次</p><ol><li><strong>概念模型</strong>,也称信息模型,按照<strong>用户的观点</strong>对数据和信息建模,用于数据库设计</li><li>逻辑模型和物理模型<ul><li><strong>逻辑模型</strong>主要包括:网状模型、层次模型、关系模型、面向对象数据模型、对象关系数据模型、半结构化数据模型等。按照<strong>计算机系统的观点</strong>对数据建模,用于DBMS实现</li><li><strong>物理模型</strong>是对数据最底层的抽象,描述数据在系统内(磁盘上)的<strong>表示方法和存取方法</strong></li></ul></li></ol><h3 id="1-2-2-概念模型"><a href="#1-2-2-概念模型" class="headerlink" title="1.2.2 概念模型"></a>1.2.2 概念模型</h3><ul><li><p>信息世界中的基本概念</p><ol><li><p>实体(Entity)–客观存在并且可以互相区别的事物称为实体</p></li><li><p>属性(Attribute)–实体所具有的某一特征称为属性,一个实体可以用若干个属性来刻画</p></li><li><p>码(Key)–唯一标识实体的<strong>属性集</strong>称为码</p></li><li><p>实体型(Entity Type)–用实体名及其属性名集合来抽象和刻画同类实体称为实体型</p></li><li><p>实体集(Entity Set)–同一类型实体的集合称为实体集</p></li><li><p>联系(Relationship)–现实世界中事物内部以及事物之间的联系在信息世界中反映为实体(型)内部的联系和实体(型)之间的联系</p><ul><li>实体内部的联系:即组成实体的各个属性之间的联系</li><li>实体之间的联系:通常指不同实体集之间的联系,有一对一,一对多,多对多等多种类型</li><li>实体-联系方法(Entity-Relationship Approach),E-R方法/E-R模型,用E-R图来描述现实世界的概念模型</li></ul></li></ol></li></ul><h3 id="1-2-3-数据模型的基本组成"><a href="#1-2-3-数据模型的基本组成" class="headerlink" title="1.2.3 数据模型的基本组成"></a>1.2.3 数据模型的基本组成</h3><p>数据模型是严格定义了一组概念的集合,精确地描述了系统的静态特性-数据结构、动态特性-数据操作和完整性约束条件(Integrity Constraints)</p><ol><li>数据结构<ul><li><strong>数据结构的类型来命名数据模型</strong>,比如层次结构-层次模型、网状结构-网状模型、关系结构-关系模型</li><li>描述数据库的组成对象–对象的类型、内容和性质以及对象之间的联系</li></ul></li><li>数据操作<ul><li>对数据库中各个对象的实例允许执行的操作的集合,包括操作以及有关的操作规则</li><li>数据操作的类型:查询、更新(增、删、改)</li><li>实现操作的语言</li></ul></li><li>数据的完整性约束条件<ul><li>一组完整性规则的集合<ul><li>完整性规则:给定的数据模型中数据及其联系所具有的制约和依存规则</li><li>用以限定符合数据模型的数据库状态以及状态的变化,以确保数据的正确、有效和相容</li></ul></li><li>反映和规定必须遵守的<strong>基本的通用的</strong>完整性约束条件</li><li>下面具体的数据模型中会给出具体的完整性约束条件</li></ul></li></ol><h3 id="1-2-4-常用的数据模型"><a href="#1-2-4-常用的数据模型" class="headerlink" title="1.2.4 常用的数据模型"></a>1.2.4 常用的数据模型</h3><ul><li>层次模型(Hierarchical Model)–格式化模型</li><li>网状模型(Network Model)–格式化模型<ul><li>结构化模型中数据结构的单位:基本层次联系</li><li>双亲结点–子女结点一对多(包括一对一)的联系</li></ul></li><li>关系模型(Relational Model)</li><li>面向对象数据模型(Object Oriented Data Model)–对象模型</li><li>对象关系数据模型(Object Relational Data Model)–对象模型</li><li>半结构化数据模型(Semistructure Data Model)</li><li>其他还有非结构化数据模型、图模型等</li></ul><h3 id="1-2-5-层次模型"><a href="#1-2-5-层次模型" class="headerlink" title="1.2.5 层次模型"></a>1.2.5 层次模型</h3><p><strong>定义</strong>:满足以下两个条件的基本层次联系</p><ul><li>有且只有一个节点没有双亲结点,称为根结点</li><li>根以外的其他节点有且只有一个双亲结点</li></ul><ol><li>数据结构:层次模型用<strong>树形结构</strong>来表示各类实体以及实体之间的联系<ul><li>实体型:用记录类型描述,每个结点表示一个记录类型(实体)</li><li>属性:用字段描述,每个记录可以包含若干个字段</li><li>联系:用结点之间的连线表示记录类型(实体)之间的一对多的父子联系</li><li>特点<ul><li>只能处理一对多(包括一对一)的实体联系</li><li>任何记录值只有按其路径查看</li><li>没有子女记录值能脱离双亲的记录值而存在</li></ul></li></ul></li><li>数据操纵和完整性约束<ul><li>数据操纵,即查询、插入、删除、更新</li><li><strong>完整性约束条件</strong><ul><li>没有相应的双亲结点就不能插入子女结点值</li><li>删除双亲结点值,相应的子结点点值同时被删除</li><li>更新操作时,要更新所有相应记录,以保证数据的一致性</li></ul></li></ul></li><li>优缺点<ul><li>优点<ul><li>数据结构清晰简单</li><li>查询效率高,性能优于关系模型,不低于网状模型</li><li>提供了良好的完整性支持</li></ul></li><li>缺点<ul><li>结点间多对多联系表示不方便</li><li>插入和删除操作限制多,应用程序编写比较复杂</li><li>查询子女结点必须通过双亲结点</li><li>命令(语言)趋于程序化,即描述性差</li></ul></li></ul></li></ol><h3 id="1-2-6-网状模型"><a href="#1-2-6-网状模型" class="headerlink" title="1.2.6 网状模型"></a>1.2.6 网状模型</h3><ul><li>允许一个以上的结点无双亲</li><li>一个结点可以有多于一个双亲</li></ul><ol><li>数据结构:网状数据库采用网状结构来表示各类实体以及实体间的联系,表示方法与层次数据模型相同,特点如下<ul><li>允许两个结点之间有多种联系</li><li>要为每个联系命名,并指出与该联系有关的双亲记录和子女记录</li><li>多对多联系在网状模型中的表示<ul><li><strong>间接</strong>表示,将多对多联系<strong>分解成一对多联系</strong></li></ul></li></ul></li><li>数据操纵与完整性约束<ul><li>导航式的查询语言和增删改操作语言<ul><li>允许插入尚未确定双亲结点值的子女结点值</li><li>允许只删除双亲结点值</li></ul></li><li>完整性约束条件不严格<ul><li>支持码</li><li>保证一个联系中双亲记录与子女记录之间是一对多联系</li><li>可以定义双亲记录和子女记录之间的某些约束条件</li></ul></li></ul></li><li>优缺点<ul><li>优点<ul><li>能够更为直接描述现实世界,如一个结点可以有多个双亲</li><li>具有良好的性能,存取效率较高</li></ul></li><li>缺点<ul><li>结构比较复杂,而且随着应用环境的扩大,数据库的结构越来越复杂,不利于最终用户掌握</li><li>DDL,DML语言复杂,用户不容易使用</li><li>记录直接是通过存取路径实现的,应用程序必须选择存取路径,加重了程序员的负担</li></ul></li></ul></li></ol><h3 id="1-2-7-关系模型"><a href="#1-2-7-关系模型" class="headerlink" title="1.2.7 关系模型"></a>1.2.7 关系模型</h3><p>在<strong>用户观点</strong>下,关系模型中数据的逻辑结构是一张二维表</p><ol><li><p>关系模型的数据结构</p><ul><li>关系(Relation)–每个关系对应一张表</li><li>元组(Tuple)–表的一行为一个元组</li><li>属性(Attribute)–表的一列为一个属性,起个名字为属性名</li><li>主码(Key)–能够唯一确定一个元组的属性组</li><li>域(Domain)–具有相同数据类型的值的集合。属性的取值范围来自某个域</li><li>分量–元组中的一个属性值</li><li>关系模式–对关系的描述<ul><li>关系名(属性1, 属性2,…,属性n)</li></ul></li><li>关系必须是<strong>规范化</strong>的,满足一定的规范条件,比如,不允许表中还有表,即每个属性都是原子不可分的(第一范式)</li></ul></li><li><p>数据操纵和完整性</p><ul><li>数据操作是集合操作,操作对象和操作结果都是关系<ul><li>存取路径对用户隐蔽,用户不必说明怎么找,只需指出找什么,提高了数据的独立性,提高了用户生产率</li></ul></li><li>完整性<ul><li>实体完整性</li><li>参照完整性</li><li>用户定义的完整性</li></ul></li></ul></li><li><p>优缺点</p><ul><li><p>优点</p><ul><li>建立在严格的数学概念的基础上</li><li>概念单一<ul><li>实体和各类联系都用关系来表示</li><li>对数据的检索结果也是关系</li></ul></li><li>关系模型的存取路径对用户隐蔽<ul><li>具有更好的数据独立性,更好的安全保密性</li><li>简化了程序员的工作和数据库开发建立的工作</li></ul></li></ul></li><li><p>缺点</p><ul><li><p><strong>查询效率</strong>往往不如格式化数据类型</p></li><li><p>为了提高性能必须对查询请求优化,增加了开发DBMS的难度</p></li></ul></li></ul></li></ol><h2 id="1-3-数据库系统的结构"><a href="#1-3-数据库系统的结构" class="headerlink" title="1.3 数据库系统的结构"></a>1.3 数据库系统的结构</h2><p>从数据库应用开发人员角度看</p><ul><li>数据库系统采用三级模式结构,是数据库系统内部的系统结构</li></ul><p>从数据库最终用户角度看</p><ul><li>单用户结构、主从式结构、分布式结构、客户-服务器、浏览器-应用服务器/数据库服务器等</li></ul><h3 id="1-3-1-数据库系统模式的概念"><a href="#1-3-1-数据库系统模式的概念" class="headerlink" title="1.3.1 数据库系统模式的概念"></a>1.3.1 数据库系统模式的概念</h3><ul><li>模式(Schema)<ul><li>是对数据库逻辑结构和特征的描述</li><li>是型的表述,不涉及具体值</li><li>模式是相对稳定的</li></ul></li><li>实例(Instance)<ul><li>数据库某一时刻的状态–模式的一个具体值</li><li>同一个模式可以有很多实例</li><li>实例随数据库中的数据更新而变动</li></ul></li></ul><h3 id="1-3-2-数据库系统的三级模式结构"><a href="#1-3-2-数据库系统的三级模式结构" class="headerlink" title="1.3.2 数据库系统的三级模式结构"></a>1.3.2 数据库系统的三级模式结构</h3><ol><li>模式(Schema)–逻辑模式<ul><li>数据库<strong>全体数据的</strong>逻辑结构和特征的描述,所有用户的公共数据视图</li><li>模式是数据库系统模式结构的中心,与物理存储细节与硬件环境都无关</li></ul></li><li>外模式(External Schema)–子模式/用户模式<ul><li>用户使用的<strong>局部数据</strong>的逻辑结构和特征的描述,数据视图,与某一应用有关的数据的逻辑表示</li><li>外模式通常是模式的子集,一个模式可以有多个外模式,反映不同用户的应用需求、看待数据的方式以及对数据保密的要求</li><li>模式中的某一数据在不同的外模式中,结构、类型、长度、保密级别都可以不同</li></ul></li><li>内模式(Internal Schema)–存储模式<ul><li>数据<strong>物理结构和存储方式</strong>的描述</li><li>数据在数据库内部的表示方式,如记录的存储方式(顺序、堆等),索引的组织方式(B+树, Bitmap,Hash)等等其他组织方式</li><li><strong>一个数据库只有一个内模式</strong></li></ul></li></ol><h3 id="1-3-3-数据库的二级映像功能与数据独立性"><a href="#1-3-3-数据库的二级映像功能与数据独立性" class="headerlink" title="1.3.3 数据库的二级映像功能与数据独立性"></a>1.3.3 数据库的二级映像功能与数据独立性</h3><p>三级模式是对数据的三个级别抽象,DBMS内部提供二级映像:外模式/模式映像,模式/内模式映像,是三个抽象层次之间的联系和转换</p><ol><li>外模式/模式映像<ul><li>每个外模式都对应一个外模式/模式映像,通常包含在各个外模式的描述中</li><li>保证数据的<strong>逻辑独立性</strong><ul><li><strong>当模式改变时,DBA对外模式/模式映像作相应改变,使外模式保存不变</strong></li><li>应用程序根据外模式编写,应用程序不用修改,保证了数据与程序的逻辑独立性</li></ul></li></ul></li><li>模式/内模式映像<ul><li>定义了数据全局逻辑结构和存储结构直接的对应关系</li><li>保证数据的<strong>物理独立性</strong><ul><li><strong>当数据库的存储结构改变时(如选用另一种存储结构),DBA修改模式/内模式映像,使模式保持不变</strong></li><li>模式不变,则应用程序不变,保证了数据和程序的物理独立性</li></ul></li></ul></li><li>二级映像功能和数据独立性<ul><li>保证应用程序的稳定性</li><li>从程序为中心–发展为以数据为中心</li><li>数据的存取由DBMS管理</li></ul></li></ol><h2 id="1-4-数据库系统的组成"><a href="#1-4-数据库系统的组成" class="headerlink" title="1.4 数据库系统的组成"></a>1.4 数据库系统的组成</h2><p>数据库、数据库管理系统(及其开发工具)、应用程序、数据库管理员</p><h3 id="1-硬件平台及数据库"><a href="#1-硬件平台及数据库" class="headerlink" title="1. 硬件平台及数据库"></a>1. 硬件平台及数据库</h3><ul><li>数据库系统对硬件资源的要求<ul><li>足够大的内存</li><li>足够大的磁盘或磁盘阵列等外部设备</li><li>较高的通道能力,提高数据传送率</li></ul></li></ul><h3 id="2-软件"><a href="#2-软件" class="headerlink" title="2. 软件"></a>2. 软件</h3><ul><li>数据库管理系统</li><li>支持DBMS运行的操作系统</li><li>与数据库接口的高级语言及其编译系统</li><li>以DBMS为核心的应用开发工具</li><li>为特定应用环境开发的数据库应用系统</li></ul><h3 id="3-人员"><a href="#3-人员" class="headerlink" title="3. 人员"></a>3. 人员</h3><p>不同人员涉及不同的数据抽象级别,具有不同的数据视图</p><ol><li>数据库管理员(DBA)<ul><li>参与确定数据库中的内容和信息结构</li><li>参与存储结构和存取策略的设计</li><li>参与确定数据安全性要求和完整性约束条件</li><li>监控数据库的使用和运行<ul><li>周期性转储-数据文件、日志文件</li><li>系统故障回复</li><li>介质故障回复</li><li>监视审计文件</li></ul></li><li>数据库的改进和重组<ul><li>性能监控和调优</li><li>定期对数据库进行重组织,以提高系统的性能</li><li>需求增加和改变时,数据库需要重构造</li></ul></li></ul></li><li>系统分析员、数据库设计人员<ul><li>系统分析员<ul><li>负责应用系统的需求分析和规范说明</li><li>与用户及数据库管理员结合确定系统的硬软件配置</li><li>参与数据库系统的概要设计</li></ul></li><li>数据库设计人员<ul><li>参与用户需求调查和系统分析</li><li>确定数据库中的数据</li><li>设计数据库的各级模式</li></ul></li></ul></li><li>应用程序员<ul><li>设计和编写应用系统的程序模块</li><li>进行调试和安装</li></ul></li><li>用户<ul><li>通过应用系统的接口使用数据库</li><li>复杂用户直接使用数据库语言访问数据库,甚至能够基于数据库管理系统的应用程序接口编制自己的应用程序</li></ul></li></ol>]]></content>
<summary type="html"><p>第一章的概念非常多,很多概念都反复出现,需要捋清楚其中的逻辑关系,比如1.2.3中数据模型的基本组成的数据结构,数据操纵与完整性约束,在后面三个具体的数据模型中都分别具体地进行说明。第一章整个是对一些概念的入门和综述内容,比如关系模型在第二章关系数据库中也会给出更详细的介绍。</p></summary>
<category term="数据库" scheme="http://leee9.cn/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="study notes" scheme="http://leee9.cn/tags/study-notes/"/>
</entry>
<entry>
<title>Start a Blog</title>
<link href="http://leee9.cn/2021/12/20/NEXT%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE/"/>
<id>http://leee9.cn/2021/12/20/NEXT%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE/</id>
<published>2021-12-19T17:53:59.000Z</published>
<updated>2021-12-19T18:22:46.593Z</updated>
<content type="html"><![CDATA[<p><a href="https://www.nesxc.com/post/hexo.html">hexo开始教程</a></p><p><a href="https://siriusq.top/Next%E4%B8%BB%E9%A2%98%E7%BE%8E%E5%8C%96?tdsourcetag=s_pctim_aiomsg">超级全的NEXT主题设置</a></p>]]></content>
<summary type="html"><p><a href="https://www.nesxc.com/post/hexo.html">hexo开始教程</a></p>
<p><a href="https://siriusq.top/Next%E4%B8%BB%E9%A2%98%E7%BE%8E%E5%8C%96?</summary>
<category term="guide" scheme="http://leee9.cn/tags/guide/"/>
</entry>
<entry>
<title>装饰器 decorator</title>
<link href="http://leee9.cn/2021/12/18/Python%20%E8%A3%85%E9%A5%B0%E5%99%A8decorator/"/>
<id>http://leee9.cn/2021/12/18/Python%20%E8%A3%85%E9%A5%B0%E5%99%A8decorator/</id>
<published>2021-12-17T16:00:00.000Z</published>
<updated>2021-12-19T15:08:33.001Z</updated>
<content type="html"><![CDATA[<p>装饰器</p><ul><li><p>不改变函数代码,且保持函数调用方法不变,增加新的功能(或给类增加属性和方法)</p></li><li><p>核心思想:用一个函数(或者类)去装饰一个旧函数(或者类),造出一个新函数(或者新类)</p></li><li><p>语法规则:在原有的函数上加@符,装饰器会把下面的函数或方法当作参数传递到装饰器中</p></li><li><p>应用场景:引入日志,函数执行时间统计,执行函数前的准备工作,执行函数后的处理工作,权限校验,缓存等</p></li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@outer</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line"> <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><h3 id="1-装饰器原型与定义"><a href="#1-装饰器原型与定义" class="headerlink" title="1.装饰器原型与定义"></a>1.装饰器原型与定义</h3><p>利用闭包,把函数当作参数传递,并且在函数内去调用传递进来的函数,并返回一个函数</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 定义外函数,接收一个函数作为参数</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">outer</span>(<span class="params">f</span>):</span></span><br><span class="line"><span class="comment"># 定义内函数,并且在内函数中调用了外函数的参数</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">inner</span>():</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">"我是外函数中的内函数1"</span>)</span><br><span class="line">f()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">"我是外函数中的内函数2"</span>)</span><br><span class="line"><span class="keyword">return</span> inner</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 定义普通函数</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">old</span>:</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"我是普通函数"</span>)</span><br><span class="line"><span class="comment"># old()直接调用 </span></span><br><span class="line">old = outer(old)<span class="comment"># outer函数返回了inner函数</span></span><br><span class="line">old() <span class="comment"># 此时再调用old等同于调用了inner函数</span></span><br></pre></td></tr></table></figure><p>装饰器用法</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 改为装饰器用法</span></span><br><span class="line"><span class="meta">@outer</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">old</span>():</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">"我是一个普通函数"</span>)</span><br><span class="line">old()</span><br></pre></td></tr></table></figure><h3 id="2-统计函数执行时间"><a href="#2-统计函数执行时间" class="headerlink" title="2.统计函数执行时间"></a>2.统计函数执行时间</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">inport time</span><br><span class="line"><span class="comment"># 定义一个统计函数执行时间的装饰器</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">runtime</span>(<span class="params">f</span>):</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner</span>():</span></span><br><span class="line"> start = time.pref_counter()</span><br><span class="line"> f()</span><br><span class="line"> end = time.perf_counter()-start</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'函数执行时间为:<span class="subst">{end}</span>'</span>)</span><br><span class="line"><span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="meta">@runtime</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):</span><br><span class="line"> <span class="built_in">print</span>(i,end=<span class="string">''</span>)</span><br><span class="line"> time.sleep(<span class="number">1</span>)</span><br><span class="line">func()</span><br></pre></td></tr></table></figure><h3 id="3-装饰器的嵌套"><a href="#3-装饰器的嵌套" class="headerlink" title="3.装饰器的嵌套"></a>3.装饰器的嵌套</h3><ul><li>普通装饰器</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">outer</span>(<span class="params">f</span>):</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"内函数1"</span>)</span><br><span class="line"> f()</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"内函数2"</span>)</span><br><span class="line"><span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="meta">@outer</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"普通函数"</span>)</span><br><span class="line">func()</span><br></pre></td></tr></table></figure><ul><li>再定义一个装饰器</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 装饰器1</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">outer</span>(<span class="params">f</span>):</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"内函数1"</span>)</span><br><span class="line"> f()</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"内函数2"</span>)</span><br><span class="line"><span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="comment"># 装饰器2</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">kuozhan</span>(<span class="params">f</span>):</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">kzinner</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"扩展1"</span>)</span><br><span class="line"> f()</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"扩展2"</span>)</span><br><span class="line"> <span class="keyword">return</span> kzinner</span><br><span class="line"></span><br><span class="line"><span class="meta">@kuozhan</span></span><br><span class="line"><span class="meta">@outer</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"普通函数"</span>)</span><br><span class="line"></span><br><span class="line">func()</span><br></pre></td></tr></table></figure><h3 id="4-装饰带有参数的函数"><a href="#4-装饰带有参数的函数" class="headerlink" title="4.装饰带有参数的函数"></a>4.装饰带有参数的函数</h3><p>在inner函数中添加参数即可</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">outer</span>(<span class="params">f</span>):</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner</span>(<span class="params">arg</span>):</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"内函数1"</span>)</span><br><span class="line"> f(arg)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"内函数2"</span>)</span><br><span class="line"><span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="meta">@outer</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">arg</span>):</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f"普通函数<span class="subst">{arg}</span>"</span>)</span><br><span class="line">func()</span><br></pre></td></tr></table></figure><p>装饰带有<strong>多参数</strong>的函数也是一样的道理</p><h3 id="5-带有参数的装饰器"><a href="#5-带有参数的装饰器" class="headerlink" title="5.带有参数的装饰器"></a>5.带有参数的装饰器</h3><p>用于流程控制</p><p>给当前的装饰器套一个壳,用于接收装饰器的参数</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">kuozhan</span>(<span class="params">var</span>) </span></span><br><span class="line"><span class="function"> <span class="title">def</span> <span class="title">outer</span>(<span class="params">f</span>):</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner1</span>:</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"inner1"</span>)</span><br><span class="line"> f()</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner2</span>():</span> </span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"inner2"</span>)</span><br><span class="line"> f()</span><br><span class="line"> <span class="keyword">if</span> var == <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">return</span> inner1</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> inner2</span><br><span class="line"><span class="keyword">return</span> outer</span><br><span class="line"></span><br><span class="line"><span class="comment"># 本来是outer的参数,用壳接收参数</span></span><br><span class="line"><span class="meta">@kuozhan(<span class="params"><span class="number">1</span></span>)</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"普通函数"</span>)</span><br><span class="line">func()</span><br></pre></td></tr></table></figure><h3 id="6-类装饰器装饰函数"><a href="#6-类装饰器装饰函数" class="headerlink" title="6.类装饰器装饰函数"></a>6.类装饰器装饰函数</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Outer</span>():</span></span><br><span class="line"> <span class="comment"># 魔术方法,当把该类的对象当函数调用时,自动触发</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__call__</span>(<span class="params">self, f</span>):</span></span><br><span class="line"> self.f = f</span><br><span class="line"> <span class="keyword">return</span> self.inner</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 在定义的需要返回的新方法中,进行装饰和处理</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner</span>(<span class="params">self, arg</span>):</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'1'</span>)</span><br><span class="line"> self.f(arg)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'2'</span>)</span><br><span class="line"> </span><br><span class="line"><span class="meta">@Outer() </span><span class="comment"># 实例化对象obj @obj ==> obj(func) ==> 执行__call__(func)方法 ==> 返回inner()调用</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>(<span class="params">arg</span>):</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"普通函数"</span>,arg)</span><br><span class="line">func(<span class="string">'a'</span>)</span><br></pre></td></tr></table></figure><h3 id="7-用类方法装饰函数"><a href="#7-用类方法装饰函数" class="headerlink" title="7.用类方法装饰函数"></a>7.用类方法装饰函数</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Outer</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">newinner</span>(<span class="params">f</span>):</span></span><br><span class="line"> Outer.f = f <span class="comment"># 把传递进来的函数定义为类方法</span></span><br><span class="line"> <span class="keyword">return</span> Outer.inner <span class="comment"># 返回一个新的类方法</span></span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">inner</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'1'</span>)</span><br><span class="line"> Outer.f()</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'2'</span>)</span><br><span class="line"> </span><br><span class="line"><span class="meta">@Outer.newinner </span><span class="comment"># Outer.newinner(func) ==> Outer.inner</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">func</span>():</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'1'</span>)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">1.装饰器的原型与定义;2.统计函数执行时间;3.装饰器的嵌套;4.装饰带有参数的函数;5.带有参数的装饰器;6.类装饰器装饰函数;7.用类方法装饰函数。</summary>
<category term="python" scheme="http://leee9.cn/categories/python/"/>
<category term="python" scheme="http://leee9.cn/tags/python/"/>
</entry>
</feed>