-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
199 lines (95 loc) · 114 KB
/
search.xml
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>安装部署-VBlog</title>
<link href="/2024/04/10/init-VBlob/"/>
<url>/2024/04/10/init-VBlob/</url>
<content type="html"><![CDATA[<h1 id="选择Hexo的理由"><a href="#选择Hexo的理由" class="headerlink" title="选择Hexo的理由"></a>选择Hexo的理由</h1><p><strong>Hexo</strong> 是一款基于 Node.js 的静态网站生成器,拥有丰富的插件生态和主题,可以用于快速创建博客和文档网站,并且通过简单的命令就能将生成的网页上传到 GitHub Pages 上。Hexo具有以下特点:</p><ul><li><strong>静态网站生成:</strong> Hexo 生成纯静态 HTML 文件,无需服务器端渲染,从而提高性能。</li><li><strong>Markdown 支持:</strong> 支持 Markdown 语法,允许用户轻松撰写内容。</li><li><strong>主题系统:</strong> 提供广泛的主题选择,用户可以自定义网站的外观和布局。</li><li><strong>插件生态系统:</strong> 拥有丰富的插件,可扩展 Hexo 的功能,添加各种特性,如社交分享、搜索功能等。</li><li><strong>命令行界面:</strong> 通过命令行界面管理网站,提供简洁高效的工作流程。</li></ul><h2 id="页面展示-首页"><a href="#页面展示-首页" class="headerlink" title="页面展示 - 首页"></a>页面展示 - 首页</h2><p><img src="/2024/04/10/init-VBlob/image-20240410135730844.png" alt="image-20240410135730844"></p><h3 id="页面展示-归档"><a href="#页面展示-归档" class="headerlink" title="页面展示-归档"></a>页面展示-归档</h3><p><img src="/2024/04/10/init-VBlob/image-20240410144016108.png" alt="image-20240410144016108"></p><h3 id="页面展示-分类-标签"><a href="#页面展示-分类-标签" class="headerlink" title="页面展示-分类/标签"></a>页面展示-分类/标签</h3><p><img src="/2024/04/10/init-VBlob/image-20240410144052030.png" alt="image-20240410144052030"></p><p><img src="/2024/04/10/init-VBlob/image-20240410144103768.png" alt="image-20240410144103768"></p><h3 id="页面展示-关于"><a href="#页面展示-关于" class="headerlink" title="页面展示-关于"></a>页面展示-关于</h3><p><img src="/2024/04/10/init-VBlob/image-20240410144222930.png" alt="image-20240410144222930"></p><h3 id="页面展示-详情"><a href="#页面展示-详情" class="headerlink" title="页面展示-详情"></a>页面展示-详情</h3><p><img src="/2024/04/10/init-VBlob/image-20240410144932245.png" alt="image-20240410144932245"></p><h3 id="页面展示-RSS"><a href="#页面展示-RSS" class="headerlink" title="页面展示-RSS"></a>页面展示-RSS</h3><p>该链接可以直接由Fluent Reader等软件进行订阅</p><p><img src="/2024/04/10/init-VBlob/image-20240410144303194.png" alt="image-20240410144303194"></p><h3 id="页面展示-搜索"><a href="#页面展示-搜索" class="headerlink" title="页面展示-搜索"></a>页面展示-搜索</h3><p><img src="/2024/04/10/init-VBlob/image-20240410144434134.png" alt="image-20240410144434134"></p><h1 id="Hexo安装"><a href="#Hexo安装" class="headerlink" title="Hexo安装"></a>Hexo安装</h1><h2 id="安装基础框架"><a href="#安装基础框架" class="headerlink" title="安装基础框架"></a>安装基础框架</h2><h3 id="安装-Hexo"><a href="#安装-Hexo" class="headerlink" title="安装 Hexo"></a>安装 Hexo</h3><p>(前提是安装过Nodejs和Git,此处省略)</p><pre><code class="shell">$ npm install hexo-cli -g</code></pre><h3 id="非Windows用户安装"><a href="#非Windows用户安装" class="headerlink" title="非Windows用户安装"></a>非Windows用户安装</h3><pre><code class="shell">$ brew install hexo</code></pre><h3 id="初始化一个项目"><a href="#初始化一个项目" class="headerlink" title="初始化一个项目"></a>初始化一个项目</h3><pre><code class="shell">$ hexo init blog$ cd blog</code></pre><p>此时项目结构如下:</p><pre><code>├── _config.yml ├── package.json├── scaffolds├── source| ├── _drafts| └── _posts└── themes</code></pre><ul><li><code>_config.yml</code>: 网站配置信息</li><li>package.json:应用程序版本信息</li><li>scaffolds:Hexo 会根据 scaffold 来创建文件</li><li>source:资源文件夹是存放用户资源的地方。除 <code>_posts</code> 文件夹之外,开头命名为 <code>_</code> (下划线)的文件 / 文件夹和隐藏的文件将会被忽略。Markdown 和 HTML 文件会被解析并放到 <code>public</code> 文件夹,而其他文件会被拷贝过去。</li><li>themes:主题文件夹。Hexo 会根据主题来生成静态页面。</li></ul><h3 id="启动服务"><a href="#启动服务" class="headerlink" title="启动服务"></a>启动服务</h3><p>默认端口4000</p><pre><code class="shell">$ hexo server</code></pre><h2 id="安装主题"><a href="#安装主题" class="headerlink" title="安装主题"></a>安装主题</h2><p>主题可以在<a href="https://hexo.io/themes/">Themes | Hexo</a>网站找,找到心仪的主题后可以将其代码拉下来并放在<code>themes</code>文件夹下</p><p>然后根据主题教程进行配置。本博客的主题:<a href="https://github.com/litreily/snark-hexo">snark</a></p><p>同时记得将<strong>主目录</strong>下的 <code>_config.yml</code> 文件中的 <code>theme</code>修改为主题名称</p><h3 id="安装搜索插件"><a href="#安装搜索插件" class="headerlink" title="安装搜索插件"></a>安装搜索插件</h3><p>需要在<strong>主目录</strong>下安装 hexo-generator-search 这款插件。(指令在主目录输入,不是主题所在目录)</p><pre><code>npm install hexo-generator-search --save</code></pre><p>然后修改博客根目录下的 <code>_config.yml </code><br>其中中<code>search.xml</code>会在生成代码时候自动创建</p><pre><code class="yml">search: path: search.xml</code></pre><h3 id="安装RSS插件"><a href="#安装RSS插件" class="headerlink" title="安装RSS插件"></a>安装RSS插件</h3><p>需要安装 hexo-generator-feed 插件来生成。</p><pre><code>npm install hexo-generator-feed --save</code></pre><p>同样也需要修改主目录下的 _config.yml</p><pre><code class="yml">feed: type: atom path: atom.xml limit: 20 hub: content: true content_limit: 140 content_limit_delim: ' ' order_by: -date</code></pre><h3 id="自定义代码高亮"><a href="#自定义代码高亮" class="headerlink" title="自定义代码高亮"></a>自定义代码高亮</h3><p>要使用自定义代码高亮,可以先访问<a href="https://highlightjs.org/download/">该网站</a> 并选择自己需要高亮的语言以获取最佳的体验。下载下来的压缩包中找到 highlight.pack.js 文件,将其重命名为 highlight.min.js 后替换放入 /source/js/ 文件夹下,然后关闭自带的 highlight。</p><pre><code class="yml">highlight: enable: false</code></pre><p>如果需要其他主题高亮,需要修改 _config.yml 中的配置。</p><pre><code class="yml">syntax: enable: true global: true theme: xcode</code></pre><h2 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h2><ol><li><p>blog 仓库与远端仓库绑定</p><pre><code class="shell">git remote remove origingit remote add origin 你的仓库地址</code></pre></li><li><p>安装部署插件</p><pre><code>npm install hexo-deployer-git --save</code></pre></li><li><p>生成代码</p><pre><code>hexo g</code></pre></li><li><p>部署到远程(可能需要输入GitHub账号密码)</p><p>修改部署配置文件</p><pre><code class="yml">url: http://marigweizhi.github.ioroot: /deploy: type: 'git' repo: https://github.com/MarigWeizhi/marigweizhi.github.io.git branch: master</code></pre><p>开始部署</p><pre><code>hexo d</code></pre></li><li><p>GitHub配置</p><pre><code>仓库名称必须为:用户名.github.io1. 进入仓库设置 -> 仓库名称设置为 用户名.github.io2. Pages -> Branch 选择 提交的代码分支,点保存,等待1分钟自动部署静态页面到 用户名.github.io</code></pre></li></ol><h2 id="遇到的问题"><a href="#遇到的问题" class="headerlink" title="遇到的问题"></a>遇到的问题</h2><h3 id="图片显示异常"><a href="#图片显示异常" class="headerlink" title="图片显示异常"></a>图片显示异常</h3><p>安装相关插件</p><pre><code class="shell">npm install https://github.com/CodeFalling/hexo-asset-image --save# 最好不要用下面的指令,最后生成的路径会有问题npm install hexo-asset-image --save</code></pre><p>修改配置</p><pre><code class="yml">post_asset_folder: true</code></pre><p>将图片存放在.md文件同级的同名文件夹下,并引用</p><p>引用方式如下图所示</p><p><img src="/2024/04/10/init-VBlob/image-20240410160419016.png" alt="image-20240410160419016"></p><p>修改完成,重新启动即可</p><pre><code class="shell">hexo cleanhexo ghexo s</code></pre><p>ps: 尽量不要有中文路径,本地没问题,远程也有可能出问题</p><h3 id="前端报错,资源文件路径错误"><a href="#前端报错,资源文件路径错误" class="headerlink" title="前端报错,资源文件路径错误"></a>前端报错,资源文件路径错误</h3><pre><code class="xml"><script type="text/javascript" src="/marigweizhi.github.io/plugins/highlight/highlight.min.js"></script><script> hljs.initHighlightingOnLoad();</script></code></pre><p>检查发现是配置文件的root配置错了,修改成<code>/</code>后,重新生成代码<code>hexo g</code> 重新部署<code>hexo d</code> 修复</p><pre><code class="xml"><script type="text/javascript" src="/plugins/highlight/highlight.min.js"></script><script> hljs.initHighlightingOnLoad();</script></code></pre><h3 id="文章多标签"><a href="#文章多标签" class="headerlink" title="文章多标签"></a>文章多标签</h3><p>使用数组表示即可</p><pre><code>tags: ['bug','406']</code></pre><h3 id="语法警告"><a href="#语法警告" class="headerlink" title="语法警告"></a>语法警告</h3><pre><code>Deprecation Warning: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.Recommendation: math.div($mobile-head-height, 2) or calc($mobile-head-height / 2)</code></pre><p>找到代码所在位置 将<code>$mobile-head-height / 2</code> 改为 <code>calc($mobile-head-height / 2)</code>即可</p><h1 id="博客更新流程"><a href="#博客更新流程" class="headerlink" title="博客更新流程"></a>博客更新流程</h1><ol><li><p>创建新文章,设置分类标签,并编辑内容</p><pre><code>hexo new "My New Post"</code></pre></li><li><p>生成代码</p><pre><code>hexo g</code></pre></li><li><p>启动服务,本地检查内容格式</p><pre><code>hexo server</code></pre></li><li><p>部署到Github</p><pre><code>hexo d</code></pre></li></ol><h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><p><a href="https://hexo.io/zh-cn/docs/">官方文档 | Hexo</a></p>]]></content>
<categories>
<category> web </category>
</categories>
<tags>
<tag> blog </tag>
<tag> app </tag>
<tag> config </tag>
</tags>
</entry>
<entry>
<title>Hello World</title>
<link href="/2024/04/08/hello-world/"/>
<url>/2024/04/08/hello-world/</url>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><pre><code class="bash">$ hexo new "My New Post"</code></pre><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><pre><code class="bash">$ hexo server</code></pre><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><pre><code class="bash">$ hexo generate</code></pre><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><pre><code class="bash">$ hexo deploy</code></pre><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]></content>
</entry>
<entry>
<title>数据库笔记6-事务处理</title>
<link href="/2022/10/26/databse-transaction/"/>
<url>/2022/10/26/databse-transaction/</url>
<content type="html"><![CDATA[<h1 id="事务"><a href="#事务" class="headerlink" title="事务"></a>事务</h1><blockquote><p>事务是数据库数据恢复和并发控制的基本单位。</p></blockquote><h2 id="事务的ACID属性"><a href="#事务的ACID属性" class="headerlink" title="事务的ACID属性"></a>事务的ACID属性</h2><h2 id="原子性-Atomicity"><a href="#原子性-Atomicity" class="headerlink" title="原子性(Atomicity)"></a>原子性(Atomicity)</h2><blockquote><p>保证事务是一个独立的逻辑单位,事务中的诸多操作要么全做,要么全不做。事务对于数据库来说,要么彻底完成数据的增删改,要么对数据库未做任何操作。</p></blockquote><h2 id="一致性-Consistency"><a href="#一致性-Consistency" class="headerlink" title="一致性(Consistency)"></a>一致性(Consistency)</h2><blockquote><p>事务的执行结果必须是使数据库从一个一致性状态到另一个一致性状态。</p></blockquote><h2 id="隔离性-Isolation"><a href="#隔离性-Isolation" class="headerlink" title="隔离性(Isolation)"></a>隔离性(Isolation)</h2><blockquote><p>一个事务的执行不会被另一个事务干扰。DBMS可以通过加锁在并发执行的多事务间提供不同级别的分离。</p></blockquote><h2 id="持续性-Durability"><a href="#持续性-Durability" class="headerlink" title="持续性(Durability)"></a>持续性(Durability)</h2><blockquote><p>一个事务一旦提交,它对数据库中的数据改变是永久性的。</p></blockquote><p>事务被破坏的两种情况:</p><ul><li>多个事务并行运行,并且不同事务的操作交叉执行</li><li>事务运行过程被强制停止</li></ul><h2 id="故障类型"><a href="#故障类型" class="headerlink" title="故障类型"></a>故障类型</h2><ul><li>事务内部的错误,如数据库数据部不满足业务逻辑导致的错误(只剩100块,扣200块),这类错误无法执行<code>commit</code>操作,因此数据库操作只执行了一部分,需要通过<code>UNDO</code>操作恢复。</li><li>系统故障,如CPU、操作系统、DBMS故障、断电等故障导致系统停止运转。此时系统正在执行的事务被影响,对于已经<code>commit</code>的事务,但仍在数据库缓冲区中的内容也会丢失。系统需要重新启动,对故障发生前<code>commit</code>过的事务执行<code>REDO</code>操作。</li><li>介质故障,系统故障为软故障,而介质故障为硬故障,即磁盘、磁头、瞬时强磁场干扰等,几率小破坏性更大。</li><li>计算机病毒,通过非法程序破坏数据库,或恶意篡改数据库数据。</li></ul><h1 id="事务在程序中的使用方法"><a href="#事务在程序中的使用方法" class="headerlink" title="事务在程序中的使用方法"></a>事务在程序中的使用方法</h1><h2 id="登记日志文件"><a href="#登记日志文件" class="headerlink" title="登记日志文件"></a>登记日志文件</h2><blockquote><p>日志文件是用来记录事务对数据库的更新操作的文件(增删改) </p></blockquote><p><em><strong>日志内容:</strong></em> </p><ul><li>事务开始标记</li><li>事务所有更新操作(事务标识、操作类型、操作对象、更新前值,更新后值)</li><li>事务结束标记</li></ul><p><em><strong>日志要求:</strong></em> </p><ul><li>登记时间严格按并发事务执行时间的顺序</li><li>必须先写日志文件后写数据库<br>如果日志文写入了,数据未写入,在恢复时只会多做一个无效的UNDO操作。<br>如果先写数据,若数据写入,日志未写入,数据库则无法根据日志恢复。</li></ul><h2 id="恢复"><a href="#恢复" class="headerlink" title="恢复"></a>恢复</h2><h3 id="数据转储"><a href="#数据转储" class="headerlink" title="数据转储"></a>数据转储</h3><blockquote><p>数据库管理员可定期将整个数据库复制到磁盘或其他存储介质中。</p></blockquote><ul><li>当数据库需要恢复时,可拿<code>后备副本</code>恢复到数据库备份时的状态。</li><li>数据转储费时费力,可以考虑海量动态转储、海量静态转储、增量动态转储、增量静态转储等多种方式。</li><li>动态转储是数据库转储前的内容+转储期间的日志</li></ul><h3 id="事务故障的恢复"><a href="#事务故障的恢复" class="headerlink" title="事务故障的恢复"></a>事务故障的恢复</h3><ol><li>反向扫描日志文件,查找该事务的更新操作</li><li>对日志记录进行逆操作,插入变删除、删除变插入,修改为前值</li><li>直到事务的开始标记</li></ol><h3 id="系统故障的恢复"><a href="#系统故障的恢复" class="headerlink" title="系统故障的恢复"></a>系统故障的恢复</h3><ol><li>正向从头扫描日志文件到故障发生处,所有有<code>commit</code>记录的事务添加到<code>REDO-LIST</code>,没有<code>commit</code>记录的添加到<code>UNDO-LIST</code></li><li>对撤销队列中的事务执行<code>UNDO</code>操作</li><li>对重做队列中的事务执行<code>REDO</code>操作</li></ol><h3 id="介质故障的恢复"><a href="#介质故障的恢复" class="headerlink" title="介质故障的恢复"></a>介质故障的恢复</h3><ol><li>装入最新一次的数据库后备副本。(如果是动态转储的副本需要附加转储过程的日志文件结合系统故障恢复步骤恢复)</li><li>装入相应日志文件副本,从备份点到故障发生点所有已经提交的事务执行<code>REDO</code>操作(因为是新的磁盘,无需UNDO)</li></ol><h3 id="检查点"><a href="#检查点" class="headerlink" title="检查点"></a>检查点</h3><ul><li>从系统故障恢复步骤来看,从头扫描日志文件,是费时费力的,而且若数据库在故障发生前,事务commit后结果已经写入数据库了,则该事务无需执行REDO操作。 </li><li>因此系统可以准备一个<code>重新开始文件</code>,里面可以专门定时记录<code>检查点</code>并利用检查点,在数据库恢复时快速找到真正需要重做的事务。</li></ul><h4 id="检查点内容"><a href="#检查点内容" class="headerlink" title="检查点内容"></a>检查点内容</h4><ul><li>某一刻正在运行的所有事务清单</li><li>这些事务在日志文件中,最近一个日志记录地址</li></ul><h3 id="带检查点的恢复"><a href="#带检查点的恢复" class="headerlink" title="带检查点的恢复"></a>带检查点的恢复</h3><ol><li>根据重新开始文件,找到最近一个检查点,并索引到相应日志位置</li><li>将检查点这一刻正在运行的所有事务<code>ACTIVE-LIST</code>暂时加入到<code>UNDO-LIST</code></li><li>从检查点开始到故障点,扫描日志文件,若遇到事务开始标记,将其加入到<code>UNDO-LIST</code>,若遇到事务提交标记(此时该事务一定在UNDO-LIST中),则从<code>UNDO-LIST</code>中移除,转移到<code>REDO-LIST</code>中。</li><li>对<code>UNDO-LIST</code>中的事务做<code>UNDO</code>操作,对<code>REDO-LIST</code>中的事务做<code>REDO</code>操作。</li></ol><h2 id="并发控制"><a href="#并发控制" class="headerlink" title="并发控制"></a>并发控制</h2><blockquote><p>并发控制可以更好的利用CPU、I/O、通信资源。数据库系统通过事务的并发操作,实现数据库共享资源的特点。</p></blockquote><ul><li>数据库系统可以通过不同的并发控制策略以解决这些问题(封锁、时间戳、乐观控制法、多版本并发控制(MVCC))</li><li>并发操作,很容易破坏事务的隔离性和一致性,并产生以下经典问题。</li></ul><h3 id="丢失修改"><a href="#丢失修改" class="headerlink" title="丢失修改"></a>丢失修改</h3><blockquote><p>T1 T2读入同一个数据并修改,T1先保存修改,T2后保存修改,并将T1的修改结果覆盖掉了,导致T1丢失修改。</p></blockquote><h3 id="不可重复读"><a href="#不可重复读" class="headerlink" title="不可重复读"></a>不可重复读</h3><blockquote><p>T1 T2读取同一个数据,T2进行修改并保存修改,T1再次读取数据,结果与第一次不一致。</p></blockquote><h3 id="读”脏”数据"><a href="#读”脏”数据" class="headerlink" title="读”脏”数据"></a>读”脏”数据</h3><blockquote><p>T1修改一个数据并写入磁盘,T2在T1写入后读取同一数据,T2读取后T1事务发生异常导致T1回滚,使得T2读到的数据为脏数据。</p></blockquote><h2 id="封锁"><a href="#封锁" class="headerlink" title="封锁"></a>封锁</h2><h4 id="排它锁(写锁、X锁)"><a href="#排它锁(写锁、X锁)" class="headerlink" title="排它锁(写锁、X锁)"></a>排它锁(写锁、X锁)</h4><p>事务T1给对象O加上排他锁后,其他事务不能对O加任何的锁,直到T1释放锁,以实现保护数据不被其他事务影响。(但若T2事务的策略不打算给O加锁的话,尽管T1加了X锁,T2仍可以读O)</p><h4 id="共享锁(读锁、S锁)"><a href="#共享锁(读锁、S锁)" class="headerlink" title="共享锁(读锁、S锁)"></a>共享锁(读锁、S锁)</h4><p>事务T1给对象O加了共享锁后,其他事务不能给该事务加排它锁,只能继续加共享锁。</p><blockquote><p>数据库通过使用封锁功能中的X锁和S锁可以实现并发控制。而不同的加锁策略可以实现不同级别的封锁协议,以满足不同的功能。 </p></blockquote><h3 id="一级封锁协议"><a href="#一级封锁协议" class="headerlink" title="一级封锁协议"></a>一级封锁协议</h3><blockquote><p>事务如果要执行修改操作,则需要在修改前,给修改对象加上X锁,直到事务结束。 </p></blockquote><p>解决了丢失修改的问题<br>未解决不可重复和读”脏”数据的问题</p><h3 id="二级封锁协议"><a href="#二级封锁协议" class="headerlink" title="二级封锁协议"></a>二级封锁协议</h3><blockquote><p>在一级封锁协议的基础上,如果事务要读取数据则需先给目标加S锁,读取结束后释放锁。</p></blockquote><p>解决了丢失修改和读”脏”数据的问题<br>未解决不可重复读的问题</p><h3 id="三级封锁协议"><a href="#三级封锁协议" class="headerlink" title="三级封锁协议"></a>三级封锁协议</h3><blockquote><p>在一级封锁协议的基础上,如果事务要读取数据则需先给目标加S锁,事务结束后释放锁。</p></blockquote><p>解决了丢失修改、不可重复读和读”脏”数据的问题 </p><h2 id="死锁活锁"><a href="#死锁活锁" class="headerlink" title="死锁活锁"></a>死锁活锁</h2><p><strong>活锁</strong>:是某一个事务在申请锁资源时,由于其他事务一直插队,导致这个事务一直处于等待状态。<br><strong>死锁</strong>:是两个事务执行时各自锁上一个对象,后又申请封锁对方的资源,导致两个事务互相等待。</p><p><strong>活锁解决</strong>:先来后到<br><strong>死锁解决</strong>:</p><ul><li>一次性将所需资源全部上锁</li><li>事务超时判定死锁</li><li>等待图法,找到死锁环,选一个代价最小的事务终止,解除死锁,后重新执行这个事务。</li></ul><h1 id="串行化调度"><a href="#串行化调度" class="headerlink" title="串行化调度"></a>串行化调度</h1><blockquote><p>若多个事务严格按前后循序执行,T1执行完,T2开始,则这些事务属于<code>串行化调度</code>。 </p></blockquote><ul><li>虽然T1和T2的执行顺序可能导致结果不同,但都认为串行化调度的结果是正确的。</li><li>如果存在一个并发的调度,其运行结果属于某个串行化调度,则称这个并发的调度是<code>可串行化</code>的,并且定义只有一个调度是<code>可串行化</code>调度,才认为这个调度是正确的。</li></ul><h2 id="冲突可串行化"><a href="#冲突可串行化" class="headerlink" title="冲突可串行化"></a>冲突可串行化</h2><h3 id="冲突"><a href="#冲突" class="headerlink" title="冲突"></a>冲突</h3><blockquote><p>不同事务对同一个数据的<code>读写</code>操作和<code>写写</code>操作认为是两对冲突操作。<br>对同一数据的<code>读读</code>操作不为冲突操作,同时对不同数据的操作也不为冲突操作。 </p></blockquote><p><code>读写</code>冲突例子:Ri(x) 和 Wj(x) :事务i读取x和事务j写入x<br><code>写写</code>冲突例子:Wi(x) 和 Wj(x) :事务i写入x和事务j写入x </p><h3 id="交换条件"><a href="#交换条件" class="headerlink" title="交换条件"></a>交换条件</h3><ul><li>冲突操作不能交换</li><li>同一事务内的操作不能交换</li></ul><p>一个调度在满足交换条件的情况下,若能转变成串行化调度,则认为这个调度是<code>冲突可串行化的</code></p><ul><li>若调度是冲突可串行化的,那一定是可串行化的调度</li><li>若调度是可串行化的,则不一定是冲突可串行化的</li></ul><p>例1:r1(A)w1(A)r2(A)<code>w2(A)r1(B)w1(B)</code>r2(B)w2(B)<br>高亮处第一次交换:r1(A)w1(A)<code>r2(A)r1(B)w1(B)</code>w2(A)r2(B)w2(B)<br>高亮处第二次交换:r1(A)w1(A)r1(B)w1(B)r2(A)w2(A)r2(B)w2(B)<br>交换完毕:事务1的操作全在事务2的前面,因此是可串行化的 </p><h1 id="两段锁-TwoPhase-Locking"><a href="#两段锁-TwoPhase-Locking" class="headerlink" title="两段锁(TwoPhase Locking)"></a>两段锁(TwoPhase Locking)</h1><blockquote><p>两阶段锁,简称2PL。两阶段分别为<code>扩展阶段</code>和<code>收缩阶段</code>,扩展阶段只能给数据上锁,收缩阶段只能释放锁,进入收缩阶段后不能回到扩展阶段。</p></blockquote><ul><li>若并发的所有事务满足两段锁协议,则这些事务的任何并发调度策略都是可串行化的。 </li><li>可串行化不一定满足两段锁协议</li><li></li></ul><h1 id="封锁的粒度-granularity"><a href="#封锁的粒度-granularity" class="headerlink" title="封锁的粒度(granularity)"></a>封锁的粒度(granularity)</h1><blockquote><p>封锁对象的大小称为封锁粒度,封锁粒度与系统的并发度和并发控制开销密切相关。封锁对象越大,并发度越小,开销小,封锁对象小,并发度高,开销也大。 </p></blockquote><h2 id="多粒度封锁"><a href="#多粒度封锁" class="headerlink" title="多粒度封锁"></a>多粒度封锁</h2><ul><li><code>多粒度树</code>的根节点是整个数据库表示最大的粒度,往下粒度减小,比如数据库、数据分区、数据文件、数据记录。 </li><li><code>多粒度封锁协议</code>允许多粒度树中每个结点被独立地加锁。对一个结点加锁意味着这个结点的所有子结点也被加了同类型的锁。</li><li><code>显式封锁</code>指直接加了锁的结点</li><li><code>隐式封锁</code>指由于上级结点加了锁,导致该结点被锁</li><li>加新锁,需要检查上级结点和下级结点是否有冲突的锁,导致效率低下,因此引入<code>意向锁</code>(intention lock),这样加锁后就不用逐个检查下一结点的显示封锁。</li><li>给一个结点加意向锁,表示该结点的下层结点正在被加锁,给任意结点加锁前,先给其上层结点加相应意向锁:<code>IS(意向共享锁)</code>、<code>IX(意向排它锁)</code>、<code>SIX(共享意向排他锁)</code></li><li>加锁过程自上而下,释放锁自下而上。</li></ul><p>各个锁的相容性:</p><table><thead><tr><th>T1/T2</th><th>S</th><th>X</th><th>IS</th><th>IX</th><th>SIX</th><th>-</th></tr></thead><tbody><tr><td>S</td><td>Y</td><td>N</td><td>Y</td><td>N</td><td>N</td><td>Y</td></tr><tr><td>X</td><td>N</td><td>N</td><td>N</td><td>N</td><td>N</td><td>Y</td></tr><tr><td>IS</td><td>Y</td><td>N</td><td><strong>Y</strong></td><td><strong>Y</strong></td><td><strong>Y</strong></td><td>Y</td></tr><tr><td>IX</td><td>N</td><td>N</td><td><strong>Y</strong></td><td><strong>Y</strong></td><td><strong>N</strong></td><td>Y</td></tr><tr><td>SIX</td><td>N</td><td>N</td><td><strong>Y</strong></td><td><strong>N</strong></td><td><strong>N</strong></td><td>Y</td></tr><tr><td>-</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td></tr></tbody></table><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><table><thead><tr><th>事务技术</th><th>效果</th></tr></thead><tbody><tr><td>恢复技术</td><td>保证原子性和持续性</td></tr><tr><td>并发控制</td><td>保证一致性和隔离性</td></tr></tbody></table><table><thead><tr><th>转储方式</th><th>动态转储状态</th><th>静态转储状态</th></tr></thead><tbody><tr><td>海量转储</td><td>动态海量转储</td><td>静态海量转储</td></tr><tr><td>增量转储</td><td>动态增量转储</td><td>静态海量转储</td></tr></tbody></table><table><thead><tr><th>协议</th><th>一级封锁协议</th><th>二级封锁协议</th><th>三级封锁协议</th></tr></thead><tbody><tr><td>事务结束释放X锁</td><td>√</td><td>√</td><td>√</td></tr><tr><td>读取结束释放S锁</td><td>-</td><td>√</td><td>×</td></tr><tr><td>事务结束释放S锁</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></tbody></table>]]></content>
<categories>
<category> database </category>
</categories>
<tags>
<tag> database </tag>
</tags>
</entry>
<entry>
<title>数据库笔记5-数据库基本原理</title>
<link href="/2022/10/16/database-principles/"/>
<url>/2022/10/16/database-principles/</url>
<content type="html"><![CDATA[<h1 id="数据的存储方式"><a href="#数据的存储方式" class="headerlink" title="数据的存储方式"></a>数据的存储方式</h1><h3 id="聚簇-clustering"><a href="#聚簇-clustering" class="headerlink" title="聚簇(clustering)"></a>聚簇(clustering)</h3><blockquote><p>为提高某个属性(组)的查询速度,将这些属性上具有相同值的元组存在连续的物理块中称为聚簇。该属性(组)称为<code>聚簇码</code>(cluster key) </p></blockquote><h4 id="聚簇的优点"><a href="#聚簇的优点" class="headerlink" title="聚簇的优点"></a>聚簇的优点</h4><ul><li>在数据库系统中,I/O操作的时间开销很大,而聚簇大大降低了I/O操作</li><li>聚簇也适用于多个常用于连接的关系,即把多个连接关系的元组按连接属性值聚簇存放,相当于<code>预连接</code>。</li><li>一个数据库可以有多个聚簇,一个关系只能加入一个聚簇。</li></ul><h4 id="聚簇的缺点"><a href="#聚簇的缺点" class="headerlink" title="聚簇的缺点"></a>聚簇的缺点</h4><ul><li>聚簇建立维护开销很大,需要与优点权衡</li><li>对已有关系建立聚簇,会移动数据的物理地址,即原索引全部失效,需要重新建立索引</li><li>聚簇码值修改会导致数据物理地址移动</li></ul><h4 id="聚簇的选择要求"><a href="#聚簇的选择要求" class="headerlink" title="聚簇的选择要求"></a>聚簇的选择要求</h4><ul><li>经常进行连接操作的关系</li><li>关系中的一组属性经常出现在相等比较中</li><li>关系的个或一组属性上的值重复率很高。即聚簇码值平均元组数不能太少。</li><li>SQL语句经常出现<code>ORDER BY</code>、<code>GROUP BY</code>、<code>UNION</code>、<code>DISTINCT</code>等子句。</li><li>不经常进行全表扫描</li><li>连接操作多于更新操作</li><li>一个表只能加入一个聚簇,如果有一个表符合多个,则选择最优的</li></ul><h1 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h1><p>索引法(B+树、Hash)</p><h3 id="B-树索引法"><a href="#B-树索引法" class="headerlink" title="B+树索引法"></a>B+树索引法</h3><p>一般条件:</p><ol><li>一个(组)属性经常在查询条件中出现,考虑在该属性上建立(组合)索引</li><li>一个属性经常作为最大值和最小值等聚集函数的参数,考虑建立索引</li><li>一个(组)属性经常在连接操作的连接条件中出现,考虑建立索引</li></ol><p><em><strong>注意:</strong></em><br>若一个关系更新频率很高,则要花费大量时间更新索引,因此不适合建立太多索引</p><h3 id="Hash索引法"><a href="#Hash索引法" class="headerlink" title="Hash索引法"></a>Hash索引法</h3><p>一般条件:</p><ol><li>一个关系的大小可预知,且不变。</li><li>关系的大小动态改变,但数据库管理系统提供了动态hash存储方法。</li></ol><h1 id="查询的执行方式"><a href="#查询的执行方式" class="headerlink" title="查询的执行方式"></a>查询的执行方式</h1><p>数据库查询四个步骤:查询分析、查询检查、查询优化、查询执行</p><ul><li>查询分析<br>对查询语句进行扫描、词法、语法分析,没有错误则进行下一步。</li><li>查询检查<br>对合法的查询语句进行语义检查,根据数据字典检查各对象是否存在和有效和权限检查,如果是视图操作,则需转换成对基本表的操作。</li><li>查询优化<br>选择一个高效的查询策略,一般分为代数优化、物理优化。代数优化是修改代数表达式的操作和组合实现优化;物理优化是指存储路径和底层操作算法,物理优化可以基于规则、代价、语义。</li><li>查询执行<br>根据优化器得到的查询策略,通过代码生成器生成查询计划并进行查询。</li></ul><h2 id="选择操作实现"><a href="#选择操作实现" class="headerlink" title="选择操作实现"></a>选择操作实现</h2><ul><li>选择操作只涉及一张表,一般用简单全表扫描或索引扫描。</li><li>若选择率低,索引扫描效率更高。</li><li>若选择率高,全表扫描效率高,因为B+树索引的扫描操作,对于每个检索码,从根结点到叶子结点,每个结点都要执行一次I/O操作。</li></ul><h3 id="1)简单全表扫描法"><a href="#1)简单全表扫描法" class="headerlink" title="1)简单全表扫描法"></a>1)简单全表扫描法</h3><p>设可用内存M</p><ol><li>按照物理次序读M的数据到内存</li><li>检查内存每个元组t,满足则输出</li><li>若表没读完,则重复1-2操作</li></ol><h3 id="2)索引扫描法"><a href="#2)索引扫描法" class="headerlink" title="2)索引扫描法"></a>2)索引扫描法</h3><ul><li>若选择条件的数学有索引(B+树、Hash),则可以通过索引先找到满足条件的元组指针,再通过指针在基本表中找到元组。</li><li>若干选择条件包含多个带索引的属性,有以下两种方法:<ol><li>各属性分别利用索引找到满足条件的指针组,最后将各组指针取交集。</li><li>选某个属性利用索引找到满足条件的指针组,遍历这个指针组对应的元组,检查是否满足其他属性的条件,满足则输出。</li></ol></li></ul><h2 id="连接操作实现"><a href="#连接操作实现" class="headerlink" title="连接操作实现"></a>连接操作实现</h2><p>连接操作是查询处理最常用也最耗时的操作之一。常用等值连接算法思想:</p><h3 id="1-嵌套循环算法"><a href="#1-嵌套循环算法" class="headerlink" title="1) 嵌套循环算法"></a>1) 嵌套循环算法</h3><ul><li>最简单可行通用的算法,可以处理等值与非等值的连接</li><li>以一张表为外循环,另一张表作为内循环,根据连接条件判断是否连接</li><li>实际实现时是按照数据库读入内存,而不是按照元组I/O</li></ul><h3 id="2-排序-合并算法"><a href="#2-排序-合并算法" class="headerlink" title="2) 排序-合并算法"></a>2) 排序-合并算法</h3><ul><li>将参与连接的表根据连接条件进行排序</li><li>取出一张表的第一个连接属性,并扫描找到另一张表连接属性相同值,然后开始连接。(因为排了序,后面都是连续可连接的)</li><li>开始连接后,当遇到第一个不可连接的元组时,第一个对象连接结束。</li><li>重复上述过程,直到连接结束。</li></ul><p>特点: </p><ul><li>两个表都只遍历了一遍</li><li>一般来说,对于大表,先排序再连接,效率也比嵌套循环好</li></ul><h3 id="3-索引连接算法"><a href="#3-索引连接算法" class="headerlink" title="3) 索引连接算法"></a>3) 索引连接算法</h3><p>设SC表上已有Sno索引</p><ul><li>对每一个Student元组,根据Student.Sno值,利用SC的Sno索引,快速找到SC.Sno</li><li>将Student元组和SC元组连接起来</li></ul><h3 id="4-hash-join算法"><a href="#4-hash-join算法" class="headerlink" title="4) hash join算法"></a>4) hash join算法</h3><ul><li>划分阶段:也称创建阶段,连接属性作为hash码,将较小的表散列到hash表中。</li><li>试探阶段:也称连接阶段,将另一张表用同一个hash函数进行散列,并将来自大表的元组和hash表中来自小表的元组相匹配的元组连接起来。</li><li>前提:较小的表可完全放入内存中,不满足前提则需要其他优化后的算法</li></ul><h1 id="查询优化"><a href="#查询优化" class="headerlink" title="查询优化"></a>查询优化</h1><h2 id="查询优化概述"><a href="#查询优化概述" class="headerlink" title="查询优化概述"></a>查询优化概述</h2><p>集中式数据库中,查询执行开销主要包括:磁盘存取块数(I/O代价)、处理机时间(CPU代价)、查询的内存开销。<br>在分布式数据库中还要加上通信代价。<br>即<code>总代价=I/O代价+CPU代价+内存代价+通信代价</code><br>其中,I/O代价比内存操作相比要高几个数量级,因此计算代价时一般用查询处理读写的块数作为衡量单位。</p><h2 id="查询优化的优点"><a href="#查询优化的优点" class="headerlink" title="查询优化的优点"></a>查询优化的优点</h2><ul><li>用户无需考虑最好的表达查询以获得较高的查询</li><li>系统优化可以比用户程序的优化做的更好,因为:<ol><li>优化器可以从数据字典中获取许多统计信息。</li><li>若物理统计信息变了,优化器可以重新优化,即无需重写程序。</li><li>优化器可以考虑到数百种查询计划,而程序员一般只能考虑到有限的几种。</li><li>优化器使用了很多复杂的优化技术,而这些技术不是所有人都能掌握的,即使用了优化器,相当于普通程序员也能使用到这些技术。</li></ol></li></ul><h2 id="举个栗子"><a href="#举个栗子" class="headerlink" title="举个栗子"></a>举个栗子</h2><pre><code class="sql">select student.sname from student,sc where student.sno = sc.sno and sc.cno='2'</code></pre><p>以上SQL语句可以等价于以下三种关系代数表达式:</p><ul><li><code>Q1=πSname(σStudent.Sno=SC.Cno='2'(Student × SC))</code></li><li><code>Q2=πSname(σSC.Cno='2'(Student ⋈ SC))</code></li><li><code>Q3=πSname(Student ⋈ (σSC.Cno='2'(SC)))</code></li></ul><p>假设学生记录1000个,选课记录10000个,2号课选修记录50个</p><h3 id="情况1"><a href="#情况1" class="headerlink" title="情况1"></a>情况1</h3><h4 id="1-连接:"><a href="#1-连接:" class="headerlink" title="1) 连接:"></a>1) 连接:</h4><ul><li>先将Student表尽可能存在内存中,留出一块放SC表的元组,然后将SC中的元组与Student的元组连接,连接后的元组写入中间文件中</li><li>再从SC中读入一块和内存中的Student元组连接,直到SC表处理完。</li><li>这时再一次读入剩下的Student元组,也留一块放SC表元组,重复操作,直到Student处理完。</li></ul><p>简单理解:Studen只读一遍,分多批读,每一批Student要遍历所有SC。</p><p>设一个块能装10个Student元组或100个SC元组,在内存中放五块Student元组和1块SC元组,则读取总数为:<br><code>1000/10 + 1000/(10*5) * 10000/100 = 100+20*100=2100块</code><br>其中读Student100块,读SC表20遍,每遍100块,则总计要读2100块。</p><p>连接后的元组数:1000*10000=1e7,设一个块存10个元组,则写出1e6个块。</p><h4 id="2-选择:"><a href="#2-选择:" class="headerlink" title="2) 选择:"></a>2) 选择:</h4><p>假设内存操作时间忽略不计,读取第一步的中间文件1e6块,满足条件的50个元组均可放在内存。</p><h4 id="3-投影:"><a href="#3-投影:" class="headerlink" title="3) 投影:"></a>3) 投影:</h4><p>将第二部的结果在Sname上投影,得到结果。</p><p>总读写数据块:<code>2100 + 1e6 + 1e6</code></p><h3 id="情况2"><a href="#情况2" class="headerlink" title="情况2"></a>情况2</h3><ul><li>自然连接读取策略不变,与情况1一致为2100块,但连接结果只有1e4个元组,写出数据库1e3 </li><li>读取数据块1e3做选择操作</li><li>投影输出,最终读写数据块 <code>2100 + 1e3 + 1e3</code><br> 代价为情况1的 1/488</li></ul><h3 id="情况3"><a href="#情况3" class="headerlink" title="情况3"></a>情况3</h3><ul><li>先遍历一次SC,读取100块,将满足条件的50个元组筛选出来,不用使用中间文件</li><li>读取Student表一遍,100块,并与SC连接。</li><li>将结果投影输出</li><li>总代价为 <code>100+100</code><br>第三种情况是第一种的万分之一,是第二种的20分之一</li></ul><h3 id="情况4"><a href="#情况4" class="headerlink" title="情况4"></a>情况4</h3><p>若SC在Cno上有索引,StudentSno上有索引,SC找到符合条件的50个元组,只需通过读取索引块(大约3-4块),再通过Student上的sno索引,也能更快速找到50个满足条件的student元组,并连接输出结果。</p><h2 id="代数优化"><a href="#代数优化" class="headerlink" title="代数优化"></a>代数优化</h2><h3 id="关系代数表达式等价变化规则"><a href="#关系代数表达式等价变化规则" class="headerlink" title="关系代数表达式等价变化规则"></a>关系代数表达式等价变化规则</h3><ol><li>连接、笛卡尔积的交换律</li><li>连接、笛卡尔积的结合律<br>(E1 × E2) × E3 = E1 × (E2 × E3)<br>(E1 ⋈ E2) ⋈ E3 = E1 ⋈ (E2 ⋈ E3)</li><li>投影的串接定律<br>在投影的基础上再一次投影等价于一次性全部投影</li><li>选择的串接定律</li><li>选择与投影的交换律</li><li>选择与笛卡尔积的交换律</li><li>选择与并的分配律</li><li>选择与差的分配律</li><li>选择与自然连接的分配律</li><li>投影与笛卡尔积的分配律</li><li>投影与并的分配律</li></ol><h3 id="查询树的启发式优化:"><a href="#查询树的启发式优化:" class="headerlink" title="查询树的启发式优化:"></a>查询树的启发式优化:</h3><ol><li>选择运算优先做(对比情况2和情况3)</li><li>投影运算和选择运算同时进行,对同一个表的操作避免重复扫描。</li><li>把投影前或后的双目运算结合起来,没有必要为了去掉某些字段而扫描一遍表。(例如情况3,没有必要先将Student的Sno和Sname投影出来后再与SC连接)</li><li>把某些选择同它之前要执行的笛卡尔积结合成一个连接运算(对比情况1和情况2)</li><li>找出公共表达式,若读取公共查询结果代价小于重新计算代价可以,避免重复计算</li></ol><p>查询树优化示例:</p><pre><code class="sql">select Student.Sname from Student,SC where Student.Sno = SC.Sno and SC.Cno = '2';</code></pre><p><em><strong>查询树图</strong></em> </p><p><img src="/2022/10/16/database-principles/searchTree1.png" alt="searchTree1"></p><p><em><strong>关系代数语法树</strong></em> </p><p><img src="/2022/10/16/database-principles/algebraTree.jpg" alt="algebraTree"></p><p><em><strong>优化后的查询树</strong></em> </p><p><img src="/2022/10/16/database-principles/searchTree2-1712736033810-11.jpg" alt="searchTree2"></p><h2 id="物理优化"><a href="#物理优化" class="headerlink" title="物理优化"></a>物理优化</h2><p>物理优化方法一般有: </p><ul><li><ol><li>基于规则的启发式优化</li></ol></li><li><ol start="2"><li>基于代价估算的优化</li></ol></li><li><ol start="3"><li>两者结合的算法</li></ol></li></ul><h3 id="基于启发式规则的存储路径选择优化"><a href="#基于启发式规则的存储路径选择优化" class="headerlink" title="基于启发式规则的存储路径选择优化"></a>基于启发式规则的存储路径选择优化</h3><h4 id="选择操作的启发式规则"><a href="#选择操作的启发式规则" class="headerlink" title="选择操作的启发式规则"></a>选择操作的启发式规则</h4><ul><li>对于小表,使用全表顺序扫描,即使选择列上有索引</li><li>对于大表,启发式规则:</li></ul><ol><li>选择条件为<code>主码=值</code>,其选择结果唯一,可选择主码索引。</li><li>选择条件为<code>非主属性=值</code>,选择列上有索引,估算目标元组比例小于10%,可以使用索引扫描,否则全表扫描。 </li><li>选择条件为非等值查询,选择列上有索引,估算目标元组比例小于10%,可以使用索引扫描,否则全表扫描。</li><li>对于多属性<code>AND</code>选择条件,若多属性上有组合索引优先使用组合索引,如果只有部分属性有索引,则考虑:<ol><li>用不同索引取出相应的指针组,并取交集(所有属性都有各自的索引)</li><li>用一个索引取出一个指针组,然后遍历其他属性(遍历时有索引用索引)</li></ol></li><li>对于<code>OR</code>选择条件,一般使用全表顺序扫描。</li></ol><h4 id="连接操作的启发式规则"><a href="#连接操作的启发式规则" class="headerlink" title="连接操作的启发式规则"></a>连接操作的启发式规则</h4><ol><li>如果2个表都已经按照连接属性排序,则选用<code>排序-合并算法</code></li><li>如果一个表在连接属性上有索引,则选择<code>索引连接算法</code></li><li>1-2方法不使用,可以考虑选较小的表选用<code>hash join算法</code></li><li>如果1-3不适用,则考虑<code>嵌套循环算法</code>,并选择占用块较小的表作为外循环。</li></ol><h3 id="基于代价估算的优化"><a href="#基于代价估算的优化" class="headerlink" title="基于代价估算的优化"></a>基于代价估算的优化</h3><ul><li>基于启发式的算法是定性的,比较粗糙,实现简单代价较小,适合解释执行的系统。</li><li>若在编译执行的系统,由于可以一次编译,多次执行,因此可以考虑加入一些精细复杂的基于代价的优化。</li></ul><p>可考虑的统计信息: </p><ol><li>对于基本表,元组总数<code>N</code>、元组长度<code>l</code>、占用块数<code>B</code>、占用的溢出块数<code>BO</code></li><li>对于基本表的列,该列不同值的个数<code>m</code>、该列最大值、最小值、是否有索引、何种索引(B+树、Hash、聚簇),根据这些数据可以算出谓词条件的选择率<code>f</code>,如果值分布均匀则<code>f=1/m</code>,否则需要算出每个值的选择率。</li><li>对于索引,如B+树索引,该索引的层数<code>L</code>、不同索引值的个数、索引的选择基数<code>S</code>(有S个元组具有某个索引值)、索引的叶节点数<code>Y</code></li></ol><h4 id="代价估算示例"><a href="#代价估算示例" class="headerlink" title="代价估算示例"></a>代价估算示例</h4><ol><li><p>全表扫描算法估算<br>基本表大小<code>B块</code>,全表扫描代价<code>B</code>,等值扫描,平均代价为<code>B/2</code></p></li><li><p>索引连接算法估算<br>等值条件,代价<code>L+1</code>,L为索引层数,1为目标所在那一块</p></li><li><p>嵌套循环算法估算<br>代价为<code>Br+BrBs(K-1)</code><br>如果要把结果写回磁盘则为<code>Br+BrBs(K-1)+(Frs*Nr*Ns)/Mrs</code><br>Br、Bs分别为R表和S表占用的块数B<br>K为内存缓存区块数(其中K-1块给外表)<br>Frs为连接选择率<br>Mrs是存放连接结果的块因子,表示每块中可以存放结果元组数</p></li></ol><p>具体算法参考前文的<code>栗子</code></p><ol start="4"><li>排序-合并算法估算<br>如果已经排好序代价为<code>Br+Bs+(Frs*Nr*Ns)/Mrs</code><br>如果未排序则需要加上<code>2*B+(2*B*log2B)</code></li></ol><h3 id="基于语义的物理优化"><a href="#基于语义的物理优化" class="headerlink" title="基于语义的物理优化"></a>基于语义的物理优化</h3><p>上述主要描述了基于规则和基于代价的物理优化方法,基于语义的方式仅举个栗子:<br><code>select * from Student where Student.age >= 200</code><br>数据库系统发现,查询条件中年龄最大值小于200,因此无需读取基本表,直接返回空值。</p>]]></content>
<categories>
<category> database </category>
</categories>
<tags>
<tag> database </tag>
</tags>
</entry>
<entry>
<title>数据库笔记4-数据库设计</title>
<link href="/2022/10/15/databse-design/"/>
<url>/2022/10/15/databse-design/</url>
<content type="html"><![CDATA[<h1 id="数据库模式"><a href="#数据库模式" class="headerlink" title="数据库模式"></a>数据库模式</h1><ul><li>数据库系统的三级模式结构是指数据库系统是由外模式、模式、内模式三级构成; </li><li>数据与程序之间的独立性,使得数据的定义和描述可以从应用中分离出去。</li></ul><h2 id="模式"><a href="#模式" class="headerlink" title="模式"></a>模式</h2><blockquote><p>模式也称逻辑模式,是数据库中<code>全体数据的逻辑结构</code>和特征的描述,是所有用户的公共数据视图。</p></blockquote><ul><li>定义模式时不仅要定义数据的<code>逻辑结构</code>,还要定义<code>数据之间的联系</code>,定义数据有关的<code>安全性、完整性要求</code>。</li></ul><h2 id="外模式"><a href="#外模式" class="headerlink" title="外模式"></a>外模式</h2><blockquote><p>也称<code>子模式</code>或<code>用户模式</code>,它是数据库用户能够看见和使用的<code>局部数据的逻辑结构</code>和特征的描述,是数据库用户的数据视图,是与某一应用有关的数据的逻辑表示。 </p></blockquote><ul><li>一个数据库可以有多个外模式; </li><li>同一外模式可以为某一用户的多个应用使用; </li><li>一个应用程序只能使用一个外模式;</li></ul><h2 id="内模式"><a href="#内模式" class="headerlink" title="内模式"></a>内模式</h2><blockquote><p>也称<code>存储模式</code>,它是<code>数据物理结构</code>和存储方式的描述,是数据在数据库内部的表示方式。 </p></blockquote><ul><li>一个数据库只有一个内模式</li></ul><h2 id="外模式-模式映象"><a href="#外模式-模式映象" class="headerlink" title="外模式/模式映象"></a>外模式/模式映象</h2><ul><li>每一个外模式,都有一个外模式/模式映像,这些映像通常包含在外模式的描述中; </li><li>模式改变时,只需改变外模式/模式映像,使得外模式保持不变,进而保证应用程序不用改变; </li><li>保证了数据与程序的逻辑独立性,简称数据的逻辑独立性;</li></ul><h2 id="模式-内模式映象"><a href="#模式-内模式映象" class="headerlink" title="模式/内模式映象"></a>模式/内模式映象</h2><ul><li>内模式唯一,因此模式/内模式映像唯一,定义了数据全局逻辑结构与存储结构的对应关系,通常包含在模式的描述中; </li><li>内模式改变时,只需改变模式/内模式映像,使得模式保持不变,进而保证应用程序不用改变; </li><li>保证了数据与程序的物理独立性,简称数据的物理独立性;</li></ul><h1 id="范式"><a href="#范式" class="headerlink" title="范式"></a>范式</h1><p><code>主属性</code>:属于某个候选码的属性。<br><code>非主属性</code>:不属于任何候选码的属性。 </p><h2 id="1NF"><a href="#1NF" class="headerlink" title="1NF"></a>1NF</h2><blockquote><p>如果一个关系模式R的所有属性都是不可分的基本数据项则R属于第一范式</p></blockquote><p>第一范式是对关系模式的最起码的要求,不满足则不能成为关系数据库。</p><h2 id="2NF"><a href="#2NF" class="headerlink" title="2NF"></a>2NF</h2><blockquote><p>若R属于第一范式,且每个非主属性都完全函数依赖于码则R属于第二范式,即每一行被码唯一标识。</p></blockquote><h2 id="3NF"><a href="#3NF" class="headerlink" title="3NF"></a>3NF</h2><blockquote><p>若R每个非主属性都不传递依赖于R的码则属于第三范式。即第三范式要求一个数据库表中不能包含其他表中已包含的非码信息。</p></blockquote><h2 id="BCNF"><a href="#BCNF" class="headerlink" title="BCNF"></a>BCNF</h2><blockquote><p>关系模式R<U,F>属于第一范式,若X→Y 且Y→X时X必含有码,即每个属性都不传递依赖于R的码,则R属于BC范式。等价于每一个决定因素都包含码,即消除任何属性对码的部分和传递函数依赖。</p></blockquote><p>结论:</p><ol><li>所有非主属性对每一个码都是完全函数依赖。</li><li>所有主属性对每一个不包含它的码也是完全函数依赖。</li><li>没有任何属性完全函数依赖于非码的任何一组属性。</li><li>属于BCNF一定属于3NF,反之则不一定。</li></ol><p>简单理解:若A能推出B,且B不在A的内部,则A必包含码,如能找到反例则不属于BCNF。<br>简称:每个决定因素都含有码</p><ul><li>R属于BC范式是R属于第三范式的充分不必要条件;</li><li>若R属于第三范式,且R只有一个候选码,则R属于BC范式是R属于第三范式的充要条件。</li></ul><h2 id="多值依赖"><a href="#多值依赖" class="headerlink" title="多值依赖"></a>多值依赖</h2><blockquote><p>R(U)是属性集U上的关系模式,XYZ是U的子集,并且Z=U-X-Y。关心模式R(U)中多值依赖X→→Y成立,当且仅当对R(U)的任意关系r,给定的一对(x,z)值,有一组Y的值,这组值仅仅决定于x的值而与z的值无关。</p></blockquote><p>若X→→Y,而Z为空,则X→→Y为平凡的多值依赖。</p><ul><li>增广律:如果X→→Y,V包含于W包含于U,则WX→→VY。</li><li>传递律:如果X→→Y,Y→→Z,则X→→Z-Y</li><li>补余律:如果X→→Y,则X→→U-X-Y</li></ul><p><a href="https://blog.csdn.net/Shishishi888/article/details/90144652">多值依赖扩展参考博客</a></p><h2 id="4NF"><a href="#4NF" class="headerlink" title="4NF"></a>4NF</h2><blockquote><p>4NF,关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。如果属于第四范式,则必属于BC范式。</p></blockquote><ul><li>任意二元关系一定是4NF</li></ul><p><em><strong>总结</strong></em></p><table><thead><tr><th>规范化</th><th>步骤</th></tr></thead><tbody><tr><td>1NF到2NF</td><td>消除非主属性对码的部分函数依赖</td></tr><tr><td>2NF到3NF</td><td>消除非主属性对码的传递函数依赖</td></tr><tr><td>3NF到BCNF</td><td>消除主属性对码的部分和传递函数依赖</td></tr><tr><td>BCNF到4NF</td><td>消除非平凡且非函数依赖的多值依赖</td></tr></tbody></table><h2 id="模式分解"><a href="#模式分解" class="headerlink" title="模式分解"></a>模式分解</h2><ul><li>分解具有无损连接性</li><li>分解要保持函数依赖</li><li>分解既要d保持函数依赖,又要具有无损连接性</li></ul><p>以上三个定义是实行分解的三个不同准则,不同的分解准则,模式所能达到的分离程度不同,各种范式就是对分离程度的测度。</p><h3 id="无损连接判断:"><a href="#无损连接判断:" class="headerlink" title="无损连接判断:"></a>无损连接判断:</h3><p>无损连接定理<br>关系模式R(U,F)的一个分解,ρ={R1<U1,F1>,R2<U2,F2>}具有无损连接的充分必要条件是:<br>U1∩U2→U1-U2 €F+ 或U1∩U2→U2 -U1€F+ </p><p><a href="https://blog.csdn.net/qq_34246965/article/details/115943652">数据库模式分解是否为无损连接和是否保持函数依赖的判断方法</a></p><h1 id="数据库设计步骤"><a href="#数据库设计步骤" class="headerlink" title="数据库设计步骤"></a>数据库设计步骤</h1><ol><li>需求分析</li><li>概念结构设计</li><li>逻辑结构设计</li><li>物理结构设计</li><li>数据库实施</li><li>数据库运行维护</li></ol><h2 id="需求分析"><a href="#需求分析" class="headerlink" title="需求分析"></a>需求分析</h2><blockquote><p>对应系统的整个应用情况作全面的详细的调查,确定用户的目标和需求,并把要求写成用户和数据库设计者都能够接受的文档。 </p></blockquote><p>输入:<code>信息需求</code>、<code>处理需求</code>、<code>安全性和完整性需求</code><br>输出:需求说明书 </p><ul><li>数据字典:是对系统中数据的详尽描述,提供对数据库数据描述的集中管理。包含数据项、数据结构、数据流、数据存储和加工过程。</li></ul><h2 id="概念结构设计"><a href="#概念结构设计" class="headerlink" title="概念结构设计"></a>概念结构设计</h2><blockquote><p>反应企业组织信息需求的数据库概念结构。独立于数据库逻辑结构,独立于DBMS,不依赖于计算机系统。</p></blockquote><h3 id="ER图"><a href="#ER图" class="headerlink" title="ER图"></a>ER图</h3><blockquote><p>描述现实世界关系概念模型的有效方法,完成对系统中数据部分设计。 </p></blockquote><p>ER图三要素:</p><ul><li>实体:实体可以时具体的人、事、物,也可以是抽象的概念或联系。用矩形表示。</li><li>属性:实体所具有的某一特征,用椭圆形表示,并用无向边将其与相应的实体连接起来。<em><strong>属性不可再分,不可与其他实体有联系。</strong></em></li><li>联系:实体内部或实体间的关联,用菱形表示,用无向边连接相应实体,并在无向边旁边表明联系的类型(1:1,1:n,n:m)。</li></ul><h4 id="E-R图扩展"><a href="#E-R图扩展" class="headerlink" title="E-R图扩展"></a>E-R图扩展</h4><h5 id="IAS联系"><a href="#IAS联系" class="headerlink" title="IAS联系"></a>IAS联系</h5><ul><li>父类实体与子类实体之间的联系称为<code>ISA联系</code>,用三角形表示。例如:研究生 is a 学生。</li><li>分类属性:三角形旁边可以标明<code>分类属性</code>,分类属性的值表示该父实体型被分派到的子实体型中。</li><li>不相交约束与可重叠约束:若父类实体不能同时属于多个子类中的实体集,则称为<code>不相交约束</code>,否则称为<code>可重叠约束</code>,其中不相交约束在三角形内画一个X。</li><li>完备性约束:若父类实体必须为某一个子类实体则称为<code>完全特化</code>用父类子类用双线连接,否则为<code>部分特化</code>用单线连接。</li></ul><h5 id="基数约束"><a href="#基数约束" class="headerlink" title="基数约束"></a>基数约束</h5><blockquote><p>是1:1、1:n、n:m的细化,用<code>min..max</code>表示。 </p></blockquote><ul><li>0≤min≤max,例如0..1,1..3,1..* (*表示无穷大)。</li><li>当min=1时,约束称为<code>强制参与约束</code>,即实体型每个实体都要参与;min=0则为<code>非强制参与约束</code>,可以不在联系中。</li></ul><p>例1:班级与学生,一个学生必须加入一个班级且只能加入一个班级,一个班级可以容纳30到40名学生。因此在学生一端的联系上标 30..40 ,在班级的一端的联系上标 1..1。</p><h5 id="独占联系"><a href="#独占联系" class="headerlink" title="独占联系"></a>独占联系</h5><ul><li>依赖其他实体存在的实体称为<code>弱实体</code>用双矩形表示,反之则为<code>强实体</code>,强实体与弱实体之间的联系称为<code>独占联系</code>(Part-of)用双菱形表示。</li><li>弱实体一般没有作为码的属性。</li></ul><p>例1:一次贷款可以有多次还款,显然”还款”实体依赖于”贷款”实体存在。<br>例2:楼房包含多个房间,房间有房间号,但是房间号不能区别在哪个楼房,因此房间依赖楼房存在。</p><p>大型项目一般采取自底向上的方法,先设计子系统的分E-R图,然后进行合并成最终的E-R图。</p><h4 id="E-R图的冲突"><a href="#E-R图的冲突" class="headerlink" title="E-R图的冲突"></a>E-R图的冲突</h4><p>合并过程一般会出现三类冲突:<code>属性冲突</code>、<code>命名冲突</code>、<code>结构冲突</code>。</p><ul><li><em><strong>属性冲突</strong></em></li></ul><ol><li>属性域冲突:例如数据类型、取值范围</li><li>属性单位冲突:例如市斤、公斤</li></ol><ul><li><em><strong>命名冲突</strong></em></li></ul><ol><li>同名异义</li><li>异名同义</li></ol><ul><li><em><strong>结构冲突</strong></em></li></ul><ol><li>同一对象在不同应用中具有不同的抽象<br>例如:职工在局部为实体,在别处为属性。一般将统一对象变成同一抽象(都为实体或都为属性)</li><li>同一实体在不同子E-R图中的属性个数、排列方式不一致<br>取同一实体的不同部分属性取并集,并统一排列方式即可。</li><li>实体间的联系在不同的E-R图中为不同类型<br>例如:产品和零件有构成关系,产品、零件和供应商有供应关系,两个子图合并时因为”构成”和”供应”两个联系不能相包含,因此将其综合起来,两个关系同时存在。</li></ol><h4 id="消除E-R图冗余"><a href="#消除E-R图冗余" class="headerlink" title="消除E-R图冗余"></a>消除E-R图冗余</h4><p>在合并之后,消除冗余的数据和实体间冗余的联系。冗余的数据是可由基本数据导出的数据。冗余联系是指可由其他联系导出的联系。</p><h2 id="逻辑结构设计"><a href="#逻辑结构设计" class="headerlink" title="逻辑结构设计"></a>逻辑结构设计</h2><blockquote><p>把概念结构中的ER图转换成具体DBMS所支持的数据模式相符合的逻辑结构。(包括数据库模式、外模式) </p></blockquote><p>步骤: </p><ol><li>E-R图向关系模式的转换</li><li>数据模型的优化<br>不是规范化越高的的关系越优,适当的冗余可以提高查询效率。</li><li>设计用户子模式<br>使用符合用户习惯的别名、针对不同级别的用户定义视图、简化用户多系统的使用。</li></ol><h2 id="物理结构设计"><a href="#物理结构设计" class="headerlink" title="物理结构设计"></a>物理结构设计</h2><blockquote><p>对给定的逻辑数据模型选取一个合适的物理结构。主要指物理设备上的存储结构和存取方法。 </p></blockquote><p><em><strong>数据库存储结构:</strong></em><br>一般基于<code>存取时间</code>、<code>存储空间利用率</code>、<code>维护代价</code>三方面权衡。<br>存放位置:</p><ul><li>稳定部分和易变部分分开存放</li><li>数据大表、数据和索引、日志文件和数据库对象存在多个不同的磁盘阵列,并行存取,提高效率</li></ul><p><em><strong>关系模式存取方法的选择:</strong></em><br>索引法(B+树、Hash)、聚簇(clustering)</p><h3 id="B-树索引法"><a href="#B-树索引法" class="headerlink" title="B+树索引法"></a>B+树索引法</h3><p>一般条件:</p><ol><li>一个(组)属性经常在查询条件中出现,考虑在该属性上建立(组合)索引</li><li>一个属性经常作为最大值和最小值等聚集函数的参数,考虑建立索引</li><li>一个(组)属性经常在连接操作的连接条件中出现,考虑建立索引</li></ol><p><em><strong>注意:</strong></em><br>若一个关系更新频率很高,则要花费大量时间更新索引,因此不适合建立太多索引</p><h3 id="Hash索引法"><a href="#Hash索引法" class="headerlink" title="Hash索引法"></a>Hash索引法</h3><p>一般条件:</p><ol><li>一个关系的大小可预知,且不变。</li><li>关系的大小动态改变,但数据库管理系统提供了动态hash存储方法。</li></ol><h3 id="聚簇"><a href="#聚簇" class="headerlink" title="聚簇"></a>聚簇</h3><blockquote><p>为提高某个属性(组)的查询速度,将这些属性上具有相同值的元组存在连续的物理块中称为聚簇。该属性(组)称为<code>聚簇码</code>(cluster key) </p></blockquote><h4 id="聚簇的优点"><a href="#聚簇的优点" class="headerlink" title="聚簇的优点"></a>聚簇的优点</h4><ul><li>在数据库系统中,I/O操作的时间开销很大,而聚簇大大降低了I/O操作</li><li>聚簇也适用于多个常用于连接的关系,即把多个连接关系的元组按连接属性值聚簇存放,相当于<code>预连接</code>。</li><li>一个数据库可以有多个聚簇,一个关系只能加入一个聚簇。</li></ul><h4 id="聚簇的缺点"><a href="#聚簇的缺点" class="headerlink" title="聚簇的缺点"></a>聚簇的缺点</h4><ul><li>聚簇建立维护开销很大,需要与优点权衡</li><li>对已有关系建立聚簇,会移动数据的物理地址,即原索引全部失效,需要重新建立索引</li><li>聚簇码值修改会导致数据物理地址移动</li></ul><h4 id="聚簇的选择要求"><a href="#聚簇的选择要求" class="headerlink" title="聚簇的选择要求"></a>聚簇的选择要求</h4><ul><li>经常进行连接操作的关系</li><li>关系中的一组属性经常出现在相等比较中</li><li>关系的个或一组属性上的值重复率很高。即聚簇码值平均元组数不能太少。</li><li>SQL语句经常出现<code>ORDER BY</code>、<code>GROUP BY</code>、<code>UNION</code>、<code>DISTINCT</code>等子句。</li><li>不经常进行全表扫描</li><li>连接操作多于更新操作</li><li>一个表只能加入一个聚簇,如果有一个表符合多个,则选择最优的</li></ul><h1 id="约束的使用"><a href="#约束的使用" class="headerlink" title="约束的使用"></a>约束的使用</h1><h2 id="实体完整性"><a href="#实体完整性" class="headerlink" title="实体完整性"></a>实体完整性</h2><blockquote><p>关系模型中的实体完整性在create table 中用<code>primary key</code>定义(对单属性构成的码可以定义为列级约束条件,也可以定义为表级约束条件,而对于多个属性构成的码只有一种说明方法,即定义为表级约束条件)。</p></blockquote><p>检查与违约处理:</p><ul><li>检查主码是否唯一,如果不唯一则拒绝插入或修改。</li><li>检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改。</li></ul><h2 id="参照整性"><a href="#参照整性" class="headerlink" title="参照整性"></a>参照整性</h2><blockquote><p>关系模型的参照完整性在create table中使用foreign key短语定义哪些列为外码,用reference短语指明这些外码参照哪些表的主码。</p></blockquote><p>参照表与参照表的违约处理:</p><table><thead><tr><th>被参照表</th><th>参照表</th><th>违约处理</th></tr></thead><tbody><tr><td>可能破坏参照完整性</td><td>插入元组</td><td>拒绝</td></tr><tr><td>可能破坏参照完整性</td><td>修改外码值</td><td>拒绝</td></tr><tr><td>删除元组</td><td>可能破坏参照完整性</td><td>拒绝/级联删除/设置为空</td></tr><tr><td>修改主码</td><td>可能破坏参照完整性</td><td>拒绝/级联删除/设置为空</td></tr></tbody></table><h2 id="用户定义完整性"><a href="#用户定义完整性" class="headerlink" title="用户定义完整性"></a>用户定义完整性</h2><blockquote><p>用户定义完整性就是针对某一具体应用的数据必须满足的语义要求。 </p></blockquote><ol><li>属性上的约束条件 <ol><li>列值非空(<code>NOT NULL</code>)</li><li>列值唯一(<code>UNIQUE</code>)</li><li>列值是否满足条件表达式(<code>CHECK</code>)</li></ol></li><li>元组上的约束条件<br>在create table语句中可以使用check定义元组上的约束条件。例如<code>check (sex = '女' or name not like 'Ms.%')</code>,即男性姓名不以Ms.开头</li></ol><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><table><thead><tr><th>完整性类型</th><th>约束类型</th><th>说明</th></tr></thead><tbody><tr><td>实体完整性</td><td>PRIMARY KEY</td><td>唯一标识每一行,保证用户不输入重复的数据,且创建一个索引来提高性能,不允许空值</td></tr><tr><td>实体完整性</td><td>UNIQUE</td><td>防止非主键关键字的重复,并保证创建一个索引来提高性能,允许空值(最多一个)</td></tr><tr><td>用户定义完整性</td><td>DEFAULT</td><td>指定在INSERT语句中没有明确提供一个值时,为该列提供的值</td></tr><tr><td>用户定义完整性</td><td>CHECK</td><td>指定在一个列中可接受的数据值</td></tr><tr><td>参照完整性</td><td>FOREIGN KEY</td><td>定义一个列或几个列的组合,他们的值匹配同一个表或另一个表中的关键字</td></tr></tbody></table><h1 id="例题"><a href="#例题" class="headerlink" title="例题"></a>例题</h1><h3 id="1-关系模式R-商店编号、商品编号、数量、部门编号、负责人-,规定,每个商店的每种商品只在一个部门销售;每个商店的每个部门只有一个负责人;每个商店的每个商品只有一个数量;求函数依赖关系和分解成3NF模式集;"><a href="#1-关系模式R-商店编号、商品编号、数量、部门编号、负责人-,规定,每个商店的每种商品只在一个部门销售;每个商店的每个部门只有一个负责人;每个商店的每个商品只有一个数量;求函数依赖关系和分解成3NF模式集;" class="headerlink" title="1. 关系模式R(商店编号、商品编号、数量、部门编号、负责人),规定,每个商店的每种商品只在一个部门销售;每个商店的每个部门只有一个负责人;每个商店的每个商品只有一个数量;求函数依赖关系和分解成3NF模式集;"></a>1. 关系模式R(商店编号、商品编号、数量、部门编号、负责人),规定,每个商店的每种商品只在一个部门销售;每个商店的每个部门只有一个负责人;每个商店的每个商品只有一个数量;求函数依赖关系和分解成3NF模式集;</h3><blockquote><p>依赖关系:<br>(商店编号,商品编号) -> 数量;<br>(商店编号,商品编号) -> 部门编号;<br>(商店编号,部门编号) -> 负责人;<br>分解:<br>R1(商店编号,商品编号,部门编号,数量)<br>R2(商店编号,部门编号,负责人) </p></blockquote><h3 id="2-试述数据库设计过程中形成的数据库模式"><a href="#2-试述数据库设计过程中形成的数据库模式" class="headerlink" title="2. 试述数据库设计过程中形成的数据库模式"></a>2. 试述数据库设计过程中形成的数据库模式</h3><blockquote><ul><li>在概念结构设计阶段,独立于DBMS绘制E-R图,形成概念模式</li><li>在逻辑结构设计阶段,E-R图转成数据库支持的数据模型、创建视图,形成外模式</li><li>是物理结构设计阶段,规划存取策略、建立索引,形成内模式</li></ul></blockquote>]]></content>
<categories>
<category> database </category>
</categories>
<tags>
<tag> database </tag>
</tags>
</entry>
<entry>
<title>数据库笔记3-关系模型</title>
<link href="/2022/10/15/relationship-model/"/>
<url>/2022/10/15/relationship-model/</url>
<content type="html"><![CDATA[<h1 id="关系模型"><a href="#关系模型" class="headerlink" title="关系模型"></a>关系模型</h1><blockquote><p>关系模型由:关系数据结构、关系操作集合和关系完整性约束三部分组成。 </p></blockquote><h3 id="关系模式"><a href="#关系模式" class="headerlink" title="关系模式"></a>关系模式</h3><blockquote><p>对关系的描述,R(D,U,Dom,F),R 为关系名,U为属性集合,D为属性组U中属性的域,Dom为属性向域的映像集合,F为属性间数据的依赖关系的集合。相当于关系数据库的型。</p></blockquote><h3 id="关系"><a href="#关系" class="headerlink" title="关系"></a>关系</h3><blockquote><p>关系模式在某一时刻的状态或内容,相当于关系数据库的值。</p></blockquote><h4 id="关系数据库"><a href="#关系数据库" class="headerlink" title="关系数据库"></a>关系数据库</h4><blockquote><p>有值和型之分,型也称关系数据库模式,是对关系数据库的描述,包括若干域的定义和这些域上定义的若干关系模式。值为这些关系模式在某一时刻对应的关系的集合,通常成称为关系数据库。</p></blockquote><table><thead><tr><th>关系模式</th><th>关系</th></tr></thead><tbody><tr><td>对关系的描述</td><td>关系模式在某一时刻的状态或内容</td></tr><tr><td>静态的、稳定的</td><td>动态的、随时间不断变化的</td></tr></tbody></table><h1 id="关系代数"><a href="#关系代数" class="headerlink" title="关系代数"></a>关系代数</h1><blockquote><p>传统关系代数:并、差、交、笛卡尔积<br>专门的关系运算符:选择、投影、连接、除<br>其中 并、差、笛卡尔积、选择、投影为五种基本关系代数运算,其他三种:交、连接、除可以由基本运算来表达,不增加语言能力,但能简化表达。 </p></blockquote><h2 id="并(union)"><a href="#并(union)" class="headerlink" title="并(union)"></a>并(union)</h2><blockquote><p>关系R并关系S得关系T,T中的元组属于R或S </p></blockquote><h2 id="差(except)"><a href="#差(except)" class="headerlink" title="差(except)"></a>差(except)</h2><blockquote><p>关系R与关系S的差,结果为关系T,T中的元组属于R并且不属于S </p></blockquote><h2 id="交(intersection)"><a href="#交(intersection)" class="headerlink" title="交(intersection)"></a>交(intersection)</h2><blockquote><p>关系R与关系S的交集,结果为关系T,T中的元组同时属于R和S </p></blockquote><h2 id="笛卡尔积(cartesian-product)"><a href="#笛卡尔积(cartesian-product)" class="headerlink" title="笛卡尔积(cartesian product)"></a>笛卡尔积(cartesian product)</h2><blockquote><p>此处指广义笛卡尔积,因为此处元素是元组。<br>设R有n列k1个元组,S有m列k2个元组,RxS=T。则T中有(n+m)列,(k1*k2)个元组,且元组的前n列为R的元组,后m列为S的元组。 </p></blockquote><h2 id="选择(selection)"><a href="#选择(selection)" class="headerlink" title="选择(selection)"></a>选择(selection)</h2><blockquote><p>又称为限制(restriction),<code>选择行</code>,关系R在选择条件B下进行选择操作得到关系T,则T中的元组均满足条件B,R个属性个数不变。</p></blockquote><h2 id="投影(projection)"><a href="#投影(projection)" class="headerlink" title="投影(projection)"></a>投影(projection)</h2><blockquote><p><code>选择列</code>,关系R中选取若干属性组成新的关系,并去除重复元组。</p></blockquote><h2 id="连接(join)"><a href="#连接(join)" class="headerlink" title="连接(join)"></a>连接(join)</h2><blockquote><p>关系R和关系S,在基于条件B的情况下进行连接操作得到关系T。等价于关系(RxS)在条件B下进行选择操作。</p></blockquote><ul><li>连接条件的比较运算符为<code>=</code>称为等值连接,它是从(RxS)中选择出指定属性值相同的元组。</li><li>自然连接是一种特殊的等值连接,其比较分量必须是同名属性组,并且结果将重复的属性列去掉。</li><li>自然连接过程中,因为比较分量不一致的元组被舍弃,该元组称为悬浮元组(dangling tuple)</li><li></li></ul><h2 id="除运算(division)"><a href="#除运算(division)" class="headerlink" title="除运算(division)"></a>除运算(division)</h2><blockquote><p>设关系R除以关系S的结果为关系T,则<code>T包含所有在R中且不在S中的属性和值,且T的元组与S的元组的所有组合属于R</code></p></blockquote><h3 id="象集(images-set)"><a href="#象集(images-set)" class="headerlink" title="象集(images set)"></a>象集(images set)</h3><blockquote><p>设关系R(X,Y),s是X中的一个值,则s在R中的象集定义为:R中属性组X上,值为s的所有元组在Y分量上的集合。</p></blockquote><h3 id="用象集定义除运算"><a href="#用象集定义除运算" class="headerlink" title="用象集定义除运算"></a>用象集定义除运算</h3><blockquote><p>设关系 R(X,Y)和 S(Y,Z),其中R的Y属性和S的Y属性可以有不同属性名,但是必须出自相同域集。<br>R除以S得到关系P,P是R中满足以下条件的元组在X属性上的投影:元组在X上的分量值x的<code>象集Yx包含S在Y上投影的集合</code>。</p></blockquote><ul><li><p><em><strong>例1:是查询至少选择1号和3号课程的学生号码Sno。</strong></em></p><blockquote><p>首先建立一个临时关系K,K中一个属性(Cno),两个元组(1,3)<br>则问题的答案为:从关系SC中对Sno和Cno投影,然后除以关系K<br>原理:SC在Sno和Cno的投影,然后逐一求出各个Sno的象集,并依次检查这些象集是否包含K。</p></blockquote></li><li><p><em><strong>例2</strong></em><br><em><strong>R</strong></em></p></li></ul><table><thead><tr><th>A</th><th>B</th><th>C</th></tr></thead><tbody><tr><td>a1</td><td>b1</td><td>c2</td></tr><tr><td>a2</td><td>b3</td><td>c7</td></tr><tr><td>a3</td><td>b4</td><td>c6</td></tr><tr><td>a1</td><td>b2</td><td>c3</td></tr><tr><td>a4</td><td>b6</td><td>c6</td></tr><tr><td>a2</td><td>b2</td><td>c3</td></tr><tr><td>a1</td><td>b2</td><td>c1</td></tr></tbody></table><p><em><strong>S</strong></em></p><table><thead><tr><th>B</th><th>C</th><th>D</th></tr></thead><tbody><tr><td>b1</td><td>c2</td><td>d1</td></tr><tr><td>b2</td><td>c1</td><td>d1</td></tr><tr><td>b2</td><td>c3</td><td>d2</td></tr></tbody></table><p><em><strong>R除以S</strong></em></p><table><thead><tr><th>A</th></tr></thead><tbody><tr><td>a1</td></tr></tbody></table><ul><li>A表中a1的象集为{(b1,c2),(b2,c3),(b2,c1)} </li><li>S表在B、C分量投影的集合为{(b1,c2),(b2,c3),(b2,c1)} </li><li>a1的象集包含了S表在B、C分量投影的集合,因此a1满足条件。a2、a3、a4象集不满足条件,因此结果只有a1</li></ul><h1 id="关系演算"><a href="#关系演算" class="headerlink" title="关系演算"></a>关系演算</h1><p><a href="https://www.cnblogs.com/wkfvawl/p/11031826.html">关系演算参考博客</a></p><h1 id="查询语言"><a href="#查询语言" class="headerlink" title="查询语言"></a>查询语言</h1><h1 id="SQL(DDL、DML)"><a href="#SQL(DDL、DML)" class="headerlink" title="SQL(DDL、DML)"></a>SQL(DDL、DML)</h1><h3 id="SQL特点"><a href="#SQL特点" class="headerlink" title="SQL特点:"></a>SQL特点:</h3><ol><li><p>综合统一 </p><blockquote><p>SQL集数据定义语言、数据操纵语言、数据控制语言的功能于一体,语言风格统一,可以独立完成数据库生命周期中的全部活动。</p></blockquote></li><li><p>高度非过程化 </p><blockquote><p>只要提出”做什么”,无需指定”怎么做”,存储路径的选择和SQL的操作过程由系统自动完成,提高数据独立性,减轻用户负担。</p></blockquote></li><li><p>面向集合的操作方式</p><blockquote><p>操作对象、查找结果、插入、删除、更新的对象都可以是元组的集合。</p></blockquote></li><li><p>以同一种语法结构提供多种使用方式 </p><blockquote><p>支持嵌入其他高级语言</p></blockquote></li><li><p>语言简洁、易学易用 </p><blockquote><p>接近英语口语,语言简洁。</p></blockquote></li></ol><h2 id="DDL(-Data-Definition-Language)"><a href="#DDL(-Data-Definition-Language)" class="headerlink" title="DDL((Data Definition Language)"></a>DDL((Data Definition Language)</h2><blockquote><p>数据定义语言是用来定义数据库外模式、模式、内模式的语言</p></blockquote><h3 id="模式"><a href="#模式" class="headerlink" title="模式"></a>模式</h3><ul><li>创建<br>create schema <模式名> authorization <用户名>[<表定义字句>|<视图定义字句>|<授权定义字句>]</li><li>删除<br>drop schema <模式名> <cascade|restrict><br>cascade: 级联,删除模式的同时将该模式中的所有数据库对象全部删除<br>restrict:限制,没有任何下属的对象时才能执行</li></ul><h3 id="表"><a href="#表" class="headerlink" title="表"></a>表</h3><ul><li>创建<br>create table <表名><br>(<列名> <数据类型> [<列级完整性约束条件>],<br><列名> <数据类型> [<列级完整性约束条件>],<br>…<br>[<表级完整性约束条件>]<br>)</li></ul><h4 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h4><table><thead><tr><th>数据类型</th><th>含义</th></tr></thead><tbody><tr><td>char(n)</td><td>定长字符串</td></tr><tr><td>varchar(n)</td><td>变长字符串</td></tr><tr><td>int</td><td>整数(4B)</td></tr><tr><td>smallint</td><td>短整数(2B)</td></tr><tr><td>bigint</td><td>大整数(8B)</td></tr><tr><td>clob</td><td>字符串大对象</td></tr><tr><td>blob</td><td>二进制大对象</td></tr><tr><td>numeric(p,d)</td><td>定点数,p位数,小数点后又d位数</td></tr><tr><td>real</td><td>取决用户机器精度的单精度浮点数</td></tr><tr><td>double recision</td><td>取决于机器精度的双精度浮点数</td></tr><tr><td>float(n)</td><td>可选精度浮点数</td></tr><tr><td>date</td><td>日期,YYYY-MM-DD</td></tr><tr><td>time</td><td>某一日的时间 HH:MM:SS</td></tr><tr><td>timestamp</td><td>时间戳</td></tr><tr><td>interval</td><td>时间间隔</td></tr></tbody></table><ul><li><p>创建模式后创建表<br>create table “模式A”.student (…)</p></li><li><p>创建模式时创建表<br>create schema “模式A” authorization user1 crate table student(…)</p></li><li><p>设置所属模式,创建表自动分配<br>show search_path;// 查看搜索路径<br>set search_path to “模式A”,public;</p></li><li><p>修改表<br>alter table <表名><br>[add [column] <新列名> <数据类型> [完整性约束]]<br>[add <表级完整性约束>]<br>[drop [column] <列名> [cascade|restrict]]<br>[drop constraint <完整性约束名> [cascade|restrict]]<br>[alter column <列名> <数据类型>] // 修改数据类型</p></li><li><p>删除表<br>drop table table <表名> [cascade|restrict]</p></li></ul><h3 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h3><ul><li><p>创建索引<br>create [unique] [cluster] index <索引名> on <表名>(<列名>[<次序>][,<列名>[<次序>]]…)<br>一个索引可以建立在一个表的一个列或多个列上,排列次序:默认asc升序,desc降序<br>unique:表明此索引的每一个索引值只对应唯一的数据记录<br>cluster:聚簇索引 </p></li><li><p>为SC表建立以学号升序,课程号降序的唯一索引<br>create unique index scno on sc(sno asc,cno desc)</p></li><li><p>修改索引<br>alter index <旧索引名> rename to <新索引名></p></li><li><p>删除索引<br>drop index <索引名></p></li></ul><h3 id="数据字典"><a href="#数据字典" class="headerlink" title="数据字典"></a>数据字典</h3><blockquote><p>关系数据库的系统表,记录了所有定义信息:<br>关系模式、视图、索引、完整性约束、用户权限、统计信息等。<br>在执行DDL时,本质是在操作数据字典。<br>进行查询优化和处理时,数据字典的内容是重要依据。 </p></blockquote><h2 id="DML(Data-Manipulation-Language)"><a href="#DML(Data-Manipulation-Language)" class="headerlink" title="DML(Data Manipulation Language)"></a>DML(Data Manipulation Language)</h2><blockquote><p>数据操纵语言是用来对数据库进行查询插入删除和修改的语言。</p></blockquote><h3 id="查找"><a href="#查找" class="headerlink" title="查找"></a>查找</h3><p>select [all/distinct] <目标列表达式>,<目标列表达式>…<br>from <表名>,[select 子句] [as 别名]…<br>where <条件表达式><br>group by <列名> [having <条件表达式>]<br>order by <列名> [asc/desc] </p><p><em><strong>where 条件表达式常用的查询条件</strong></em></p><table><thead><tr><th>查询条件</th><th>谓词</th></tr></thead><tbody><tr><td>比较</td><td>=,>,<,>=,<=,!=,<>,!>,!<;Not + 其他比较运算符</td></tr><tr><td>确定范围</td><td>between and,not between end</td></tr><tr><td>确定集合</td><td>in,not in</td></tr><tr><td>字符匹配</td><td>like,not like</td></tr><tr><td>空值</td><td>IS NULL,IS NOT NULL</td></tr><tr><td>多重条件</td><td>and,or,not</td></tr></tbody></table><p><em><strong>集合查询</strong></em></p><ul><li>union(并)</li><li>intersect(交)</li><li>except(差)</li></ul><h4 id="经典案例"><a href="#经典案例" class="headerlink" title="经典案例"></a>经典案例</h4><ul><li>查询选了所有课程的学生姓名</li></ul><pre><code class="sql">-- 查询这样的学生,条件是每个课程这个学生都选了-- 关系演算RANGE Course CXRANGE SC SCXGET W(Student.Sname): 全部 CX 存在 SCX(SCX.Sno=Student.Sno ∧ SCX.Cno=CX.Cno)-- 由于SQL没有全称量词 for all,因此可以转成等价的存在量词`for all A == not exists not A`-- 即转换成以下等价逻辑-- 查询这样的学生,条件是不存在这样的课程这个学生未选-- 关系演算RANGE Course CXRANGE SC SCXGET W(Student.Sname): 不存在 CX 不存在 SCX(SCX.Sno=Student.Sno ∧ SCX.Cno=CX.Cno)-- SQLselect sname from student where not exists( select * from course where not exists( select * from sc where sc.sno=student.sno and course.cno = sc.cno))-- 另一个思路-- 查询这样的学生,条件是该学生选课数等于总课数select sname from studentwhere sno in ( select sno from sc group by cno having count(sno) = (select count(*) from course))-- 关系代数π sname ((π cno,sno(sc) ÷ π cno(course)) ⋈ student)</code></pre><ul><li>查询至少选修了学生201215122选修的全部课程的学生号码</li></ul><pre><code class="sql">-- 查询这样的学生,条件是对于全部课程,若学生201215122选了,则该学生也选了-- 关系演算RANGE Course CXRANGE SC SCXRANGE SC SCYGET W(Student.sno): 任意CX(存在 SCX(SCX.sno = '201215122' ∧ SCX.cno = CX.cno ) => 存在 SCY(Student.sno = SCY.sno ∧ SCY.cno = CX.cno))-- 通过逻辑蕴含的等价形式`p => q` == `not p V q`,转换上述逻辑。-- 查询这样的学生,条件是对于全部课程,学生201215122没选或者该学生选了RANGE Course CXRANGE SC SCXRANGE SC SCYGET W(Student.sno): 任意CX(不存在 SCX(SCX.sno = '201215122' ∧ SCX.cno = CX.cno ) V 存在 SCY(Student.sno = SCY.sno ∧ SCY.cno = CX.cno))-- 再将全称量词转换为存在量词-- 查询这样的学生,条件是不存在这样的课程,学生201215122选了并且该学生没选RANGE Course CXRANGE SC SCXRANGE SC SCYGET W(Student.sno): 不存在 CX(存在 SCX(SCX.sno = '201215122' ∧ SCX.cno = CX.cno ) ∧ 不存在 SCY(Student.sno = SCY.sno ∧ SCY.cno = CX.cno))-- 翻译成SQL-- 最外层循环遍历学生x-- 不存在这样的课,y中存在,x没选select distinct sno from sc scxwhere not exists( -- 不存在这样的课 -- 201215122所选的课程scy.cno select * from sc scy where scy.sno = '201215122' and not exists(select * from sc scz -- scy.cno中x没修,这里的z相当于x where scx.sno = scz.sno and scy.cno = scz.cno));-- 关系代数π sno,cno(sc) ÷ π cno(σ sno=201215122 (student ⋈ sc))</code></pre><p><em><strong>完整栗子</strong></em></p><pre><code class="sql">use study;drop table if EXISTS sc ;drop table if EXISTS student ;drop table if EXISTS course ;create table if not EXISTS student(sno int PRIMARY key,sname VARCHAR(20));create table if not EXISTS course (cno int PRIMARY key,cname VARCHAR(20));create table if not EXISTS sc(sno int,cno int,score int,PRIMARY key (sno,cno),FOREIGN KEY(sno) REFERENCES student(sno),FOREIGN KEY(cno) REFERENCES course(cno));INSERT INTO `course`(`cno`, `cname`) VALUES (1, 'java');INSERT INTO `course`(`cno`, `cname`) VALUES (2, 'c++');INSERT INTO `course`(`cno`, `cname`) VALUES (3, 'go');INSERT INTO `course`(`cno`, `cname`) VALUES (4, 'php');INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (1, 1, 100);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (1, 2, 88);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (2, 1, 90);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (2, 3, 88);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (3, 1, 22);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (3, 2, 89);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (3, 3, 56);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (3, 4, 55);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (4, 1, 99);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (4, 2, 99);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (4, 3, 66);INSERT INTO `sc`(`sno`, `cno`, `score`) VALUES (4, 4, 99);INSERT INTO `student`(`sno`, `sname`) VALUES (1, '张三');INSERT INTO `student`(`sno`, `sname`) VALUES (2, '李四');INSERT INTO `student`(`sno`, `sname`) VALUES (3, '王五');INSERT INTO `student`(`sno`, `sname`) VALUES (4, '周六');select distinct sno from sc scxwhere not exists( select * from sc scy where scy.sno = '1' and not exists(select * from sc scz where scx.sno = scz.sno and scy.cno = scz.cno));-- 上述例子的子查询select * from sc scy where scy.sno = '1' and not exists(select * from sc scz where '4' = scz.sno and scy.cno = scz.cno)select sname from student xwhere not exists( select * from course y where not exists(select * from sc z where x.sno = z.sno and z.cno = y.cno))</code></pre><h3 id="数据更新"><a href="#数据更新" class="headerlink" title="数据更新"></a>数据更新</h3><h4 id="1-插入元组"><a href="#1-插入元组" class="headerlink" title="1.插入元组"></a>1.插入元组</h4><pre><code class="sql">insert [into] <表名>[(属性1,属性2...)]values(<常量1>,<常量2>...)</code></pre><blockquote><p>into子句中属性的顺序可以自定义,也可以不写,默认为表定义的顺序,values提供的值必须与into中一致</p></blockquote><h4 id="2-修改数据"><a href="#2-修改数据" class="headerlink" title="2.修改数据"></a>2.修改数据</h4><pre><code class="sql">update <表名>set <列名1>=<表达式1>,<列名2>=<表达式2>...where <条件></code></pre><h4 id="3-删除数据"><a href="#3-删除数据" class="headerlink" title="3.删除数据"></a>3.删除数据</h4><pre><code class="sql">deletefrom <表名>where <条件></code></pre><h3 id="视图"><a href="#视图" class="headerlink" title="视图"></a>视图</h3><pre><code class="sql">create view is_student as (select ...) [with check option]</code></pre><p>with check option: 表示进行删除、插入、修改操作时候,会检查新的元组是否满足视图的where条件</p><ul><li>视图消解:用户对视图的查询,数据库系统基于查询语句和视图的定义语句合并,形成新的完整的查询语句</li><li>一般行列子集视图可更新</li><li>若设视图设涉及多表、distinct、group、聚集函数等不允许更新</li></ul><h4 id="视图的作用"><a href="#视图的作用" class="headerlink" title="视图的作用"></a>视图的作用</h4><ul><li>简化用户操作</li><li>可以从不同角度看同一数据</li><li>对重构数据库提供一定程度的逻辑独立性</li><li>视图可以对机密数据提供安全保护</li><li>适当利用视图可以更清晰地表达</li></ul><h2 id="授权"><a href="#授权" class="headerlink" title="授权"></a>授权</h2><p>用户权限两要素:数据库对象、操作类型 </p><table><thead><tr><th>对象类型</th><th>对象</th><th>操作类型</th></tr></thead><tbody><tr><td>数据库模式</td><td>模式</td><td>create schema</td></tr><tr><td>数据库模式</td><td>基本表</td><td>create table, alter table</td></tr><tr><td>数据库模式</td><td>视图</td><td>create view</td></tr><tr><td>数据库模式</td><td>索引</td><td>create index</td></tr><tr><td>数据</td><td>基本表和视图</td><td>select,insert,update,delete,references,all privileges</td></tr><tr><td>数据</td><td>属性列</td><td>select,insert,update,references,all privileges</td></tr></tbody></table><h3 id="grant语句"><a href="#grant语句" class="headerlink" title="grant语句"></a>grant语句</h3><p>grant <权限>[,<权限>]…<br>on <对象类型> <对象名>[,<对象类型> <对象名>]…<br>to <用户>[,<用户>]…<br>[with grant option];</p><p>如果指定了<code>with grant option</code>则获得该权限的用户可以把这种权限授予给其他用户。 </p><ul><li><em>把学生表的查询权限给U1</em></li></ul><pre><code class="sql">grant selecton table studentto u1;</code></pre><ul><li><em>把学生表的全部权限给U2,并运行u2授予给其他人</em></li></ul><pre><code class="sql">grant all privilegeson table studentto u2with grant option;</code></pre><h3 id="revoke语句"><a href="#revoke语句" class="headerlink" title="revoke语句"></a>revoke语句</h3><p>revoke <权限>[,<权限>]…<br>on <对象类型> <对象名>[,<对象类型> <对象名>]…<br>from <用户>[,<用户>]… [cascade|restrict] </p><ul><li><em>把u4修改学生学号的权限收回</em></li></ul><pre><code class="sql">revoke update(sno)on table studentfrom u4;</code></pre><ul><li><em>收回所有用户对SC的查询权限</em></li></ul><pre><code class="sql">revoke selecton table scfrom public;</code></pre><h3 id="角色"><a href="#角色" class="headerlink" title="角色"></a>角色</h3><ul><li><p>创建<br>create role <角色名> </p></li><li><p>授权<br>grant 权限 on 对象类型 对象名 to 角色名 </p></li><li><p>角色1和角色2的权限授予给角色3<br>grant 角色1 角色2 to 角色3 [with admin option]<br><code>with admin option</code>则允许角色3继续授予该权限给其他角色 </p></li><li><p>收回<br>revoke 权限 on 对象类型 对象名<br>from 角色名</p></li></ul><h1 id="例题"><a href="#例题" class="headerlink" title="例题"></a>例题</h1><h3 id="关系模型的三个组成部分"><a href="#关系模型的三个组成部分" class="headerlink" title="关系模型的三个组成部分"></a>关系模型的三个组成部分</h3><blockquote><p>关系数据结构、关系数据操作、关系完整性约束</p></blockquote><h3 id="简述关系数据库语言的特点和分类"><a href="#简述关系数据库语言的特点和分类" class="headerlink" title="简述关系数据库语言的特点和分类"></a>简述关系数据库语言的特点和分类</h3><blockquote><ul><li>关系代数语言</li><li>关系演算语言:元组关系演算语言ALPHA、域关系演算语言QBE(Query By Example)</li><li>SQL:具有关系代数和关系演算语言的双重特点</li></ul><p>共同特点是:语言具有完备的表达能力,是非过程化的集合操作语言,功能强,能嵌入高级语言中</p></blockquote>]]></content>
<categories>
<category> database </category>
</categories>
<tags>
<tag> database </tag>
</tags>
</entry>
<entry>
<title>数据库笔记2-数据模型</title>
<link href="/2022/10/13/data-model/"/>
<url>/2022/10/13/data-model/</url>
<content type="html"><![CDATA[<h1 id="数据模型"><a href="#数据模型" class="headerlink" title="数据模型"></a>数据模型</h1><blockquote><p>是对现实世界数据特征的抽象,是用来描述数据、组织数据、对数据进行操作的;</p></blockquote><p>数据模型分有概念模型和物理模型、逻辑模型:</p><h2 id="概念模型"><a href="#概念模型" class="headerlink" title="概念模型"></a>概念模型</h2><blockquote><p>也称信息模型,按照用户的观念对数据建模,是现实世界到信息世界的第一层抽象,用于数据库设计。</p></blockquote><h3 id="相关术语"><a href="#相关术语" class="headerlink" title="相关术语"></a>相关术语</h3><ul><li>实体<br>客观存在并且可以相互区分的事物</li><li>实体型<br>具有相同特征的实体,用实体名及其属性名集合来抽象和刻画统一类实体</li><li>实体集<br>同一类型的实体集合</li><li>实体与实体间的关系<br>实体之间的关系用菱形表示,中间写上联系名,并与相关实体连接起来,并在无向边上标注(1:1,1:n,n:m)</li></ul><h2 id="数据模型三要素"><a href="#数据模型三要素" class="headerlink" title="数据模型三要素"></a>数据模型三要素</h2><ul><li>数据结构<br>描述数据库组成对象以及<em><strong>对象之间的联系</strong></em> </li><li>数据操作<br>数据操作是指数据库中的各类对象的<em><strong>实例允许操作的集合</strong></em>,包括操作及有关的操作规则。</li><li>完整性约束<br>一组完整性规则,限制数据库状态以及状态的变化,保证数据<em><strong>正确性、有效性、相容性</strong></em>。</li></ul><h1 id="层次模型-hierarchical-model"><a href="#层次模型-hierarchical-model" class="headerlink" title="层次模型 hierarchical model"></a>层次模型 hierarchical model</h1><h2 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h2><blockquote><ul><li>有且仅有一个结点没有双亲结点,这个结点为根节点</li><li>根以外的其他结点有且仅有一个双亲结点</li></ul></blockquote><p>层次模型用树形结构来表示各类实体以及实体之间的联系。 </p><p>层次模型与网状模型统称为格式化模型 </p><h2 id="典型代表"><a href="#典型代表" class="headerlink" title="典型代表"></a>典型代表</h2><p>IBM公司旗下的IMS(Information Management System)</p><h3 id="层次模型优点"><a href="#层次模型优点" class="headerlink" title="层次模型优点"></a>层次模型优点</h3><p>结构简单清晰,查询效率高,提供了良好的完整性支持;</p><h3 id="层次模型缺点"><a href="#层次模型缺点" class="headerlink" title="层次模型缺点"></a>层次模型缺点</h3><p>对非层次的联系,如一个结点有多个双亲,表示起来复杂,对插入删除操作限制多;<br>查询子女结点必须通过双亲结点;<br>由于结构严密,层次命令趋于程序化; </p><h1 id="网状模型-network-model"><a href="#网状模型-network-model" class="headerlink" title="网状模型 network model"></a>网状模型 network model</h1><h2 id="定义-1"><a href="#定义-1" class="headerlink" title="定义"></a>定义</h2><blockquote><ul><li>允许一个以上的结点无双亲;</li><li>一个结点可以有多个双亲结点;</li></ul></blockquote><p>网状模型中要为每个联系命名,并指出与该联系有关的双亲记录和子女记录。 </p><h2 id="典型代表-1"><a href="#典型代表-1" class="headerlink" title="典型代表"></a>典型代表</h2><p>DBTG(Data Base Task Group),也称CODASYL系统(Conference On Data System Language)<br>简化版DBTG :<br>CullinetSoftware 公司的 IDMS<br>Univac 公司的 DMS100<br>Honeywell 公司的 IDS/2<br>HP公司的 IMAGE</p><h3 id="网状模型优点"><a href="#网状模型优点" class="headerlink" title="网状模型优点"></a>网状模型优点</h3><p>能更直接地描述现实世界,并指出与该联系有关的双亲记录和子女记录。</p><h3 id="网状模型缺点"><a href="#网状模型缺点" class="headerlink" title="网状模型缺点"></a>网状模型缺点</h3><p>结构复杂,不利于最终用户掌握;DDL、DML复杂,并要嵌入某一种高级语言中,用户不易使用;</p><h1 id="关系模型-relational-model"><a href="#关系模型-relational-model" class="headerlink" title="关系模型 relational model"></a>关系模型 relational model</h1><blockquote><p>从用户观点看,关系模型由一组关系组成。每个关系的数据结构是一张规范的二维表。</p></blockquote><h2 id="关系模型的一些术语"><a href="#关系模型的一些术语" class="headerlink" title="关系模型的一些术语"></a>关系模型的一些术语</h2><ul><li>关系:一张二维表。</li><li>元组:表中的一行数据。</li><li>属性:二维表中的一列。</li><li>码:用于区分元组的关键字。</li><li>域:数据项的取值范围。</li><li>分量:元组中的一个属性。</li><li>关系模式:描述关系的内容:关系名(属性1、属性2、属性3)</li></ul><p>关系的每一个分量必须是不可再分的。</p><h3 id="关系模型缺点"><a href="#关系模型缺点" class="headerlink" title="关系模型缺点"></a>关系模型缺点</h3><p>由于存储路径对用户透明,查询效率不如格式化模型。</p><h3 id="关系模型优点"><a href="#关系模型优点" class="headerlink" title="关系模型优点"></a>关系模型优点</h3><ul><li>建立在严格的数学概念模型的基础上; </li><li>结构单一,数据结构简单、清晰、用户易懂易用;</li><li>存储路径对用户透明,具有更高的数据独立性、更好的安全保密性,简化了程序员的工作和数据库开发建立工作;</li></ul>]]></content>
<categories>
<category> database </category>
</categories>
<tags>
<tag> database </tag>
</tags>
</entry>
<entry>
<title>数据库笔记1-基本概念</title>
<link href="/2022/09/30/databse-concept/"/>
<url>/2022/09/30/databse-concept/</url>
<content type="html"><![CDATA[<h1 id="结构化数据"><a href="#结构化数据" class="headerlink" title="结构化数据"></a>结构化数据</h1><blockquote><p>数据库系统实现<code>整体数据结构化</code>,这是数据库的主要特征之一,也是<code>数据库系统与文件系统的本质区别</code>;</p></blockquote><ul><li>结构化的数据一般是指可以使用关系型数据库表示和存储,可以用<code>二维表</code>来逻辑表达实现的数据。 </li><li>对于结构化数据来讲通常是<code>先有结构再有数据</code>,而对于半结构化数据来说则是先有数据再有结构。</li></ul><h2 id="半结构化数据"><a href="#半结构化数据" class="headerlink" title="半结构化数据"></a>半结构化数据</h2><blockquote><p>半结构化数据是结构化数据的一种形式,它并不符合关系型数据库或其他数据表的形式关联起来的数据模型结构,但包含相关标记,用来分隔语义元素以及对记录和字段进行分层,数据的结构和内容混在一起,没有明显的区分,因此,它也被称为自描述的结构,简单的说半结构化数据就是<code>介于完全结构化数据和完全无结构的数据之间</code>的数据。例如:<code>HTML文档,JSON,XML</code>和一些NoSQL数据库等就属于半结构化数据。</p></blockquote><h2 id="非结构化数据"><a href="#非结构化数据" class="headerlink" title="非结构化数据"></a>非结构化数据</h2><blockquote><p>非结构化数据顾名思义,就是<code>没有固定结构</code>的数据。包括所有格式的办公文档、<code>图片、视频、音频</code>等等都属于非结构化数据。对于这类数据,我们一般直接整体进行存储,而且一般存储为<code>二进制</code>的数据格式。</p></blockquote><h1 id="数据库系统"><a href="#数据库系统" class="headerlink" title="数据库系统"></a>数据库系统</h1><blockquote><p>在计算机系统引入数据库后的系统,一般由数据库、数据库管理系统(及开发工具)、应用系统、数据库管理员构成。 </p></blockquote><h2 id="数据库"><a href="#数据库" class="headerlink" title="数据库"></a>数据库</h2><blockquote><p>数据库是长期存储在计算机内,<code>有组织、可共享</code>的大量数据的集合。数据库中的数据是按照某种数据模型进行组织、描述和存放在外存储器上,且可被多个用户同时使用。因此,数据库具有较小的冗余度、较高的<code>数据独立性和易扩展性</code>。</p></blockquote><h3 id="数据库特点"><a href="#数据库特点" class="headerlink" title="数据库特点"></a>数据库特点</h3><p><code>永久储存</code> <code>有组织</code> <code>可共享</code></p><h2 id="数据库管理系统"><a href="#数据库管理系统" class="headerlink" title="数据库管理系统"></a>数据库管理系统</h2><blockquote><p>数据库管理系统(DBMS)是操纵和管理数据库的一组软件,它是数据库系统(DBS)的重要组成部分。不同的数据库系统都配有各自的DBMS,而不同的DBMS各支持一种数据库模型,虽然他们的功能强弱不同,但大多数DBMS的构成相同、功能相似。</p></blockquote><h3 id="主要功能"><a href="#主要功能" class="headerlink" title="主要功能"></a>主要功能</h3><ol><li>数据<code>定义</code>功能</li><li>数据组织、存储、管理</li><li>数组<code>操纵</code>功能</li><li>数据的<code>事物管理</code>和运行管理</li><li>数据库的建立和<code>维护</code>功能</li><li>其他(软件通信、不同系统间的数据转换、异构数据库的互访)</li></ol><h2 id="DBA"><a href="#DBA" class="headerlink" title="DBA"></a>DBA</h2><blockquote><p>数据库管理员,负责全面管理和控制数据库系统,具体职责包括:</p></blockquote><ul><li>决定数据库中的信息内容和<code>结构</code>;</li><li>决定数据库的存储结构和<code>存储</code>策略;</li><li>定义数据的安全性要求和完整性<code>约束条件</code>;</li><li>监督和控制数据库的使用和<code>运行</code>;</li><li>数据库的<code>改进</code>和重组;</li></ul><h2 id="数据管理技术的产生和发展"><a href="#数据管理技术的产生和发展" class="headerlink" title="数据管理技术的产生和发展"></a>数据管理技术的产生和发展</h2><p>对数据进行分类、组织、编码、存储、检索和维护,是数据处理的中心问题。<br>数据库发展:人工管理、文件系统、数据库系统</p><h2 id="数据库系统特点"><a href="#数据库系统特点" class="headerlink" title="数据库系统特点"></a>数据库系统特点</h2><p>相较于文件系统,特点有:</p><ol><li>数据结构化<br>数据库系统整体<code>数据结构化</code>,是与文件系统的<em><strong>本质区别</strong></em>。</li><li>数据<code>共享性高</code>,冗余度低、易扩展<br><em><strong>数据共享</strong></em>可大大减少数据冗余,节约存储空间,还能避免数据之间的不相容性与不一致性。</li><li>数据<code>独立性高</code></li></ol><ul><li>数据逻辑独立性<br> 由外模式到模式的映射保证; </li><li>数据物理独立性<br> 由内模式到模式的映射保证;</li></ul><ol start="4"><li>数据由DBMS统一管理<br>多个用户可以同时存储数据库,因此DBMS必须保证:<ol><li>数据的安全性保护</li><li>数据的完整性检查</li><li>并发控制</li><li>数据库恢复</li></ol></li></ol><p>与文件系统的联系:都是计算机系统中的<code>数据管理软件</code></p><h2 id="相关问题"><a href="#相关问题" class="headerlink" title="相关问题"></a>相关问题</h2><h3 id="1-举出适合文件系统的例子,举出适合数据库系统的例子"><a href="#1-举出适合文件系统的例子,举出适合数据库系统的例子" class="headerlink" title="1.举出适合文件系统的例子,举出适合数据库系统的例子"></a>1.举出适合文件系统的例子,举出适合数据库系统的例子</h3><blockquote><p>文件系统:数据的备份、应用软件的临时存储<br>数据库系统:部门信息、学校学生信息</p></blockquote><h3 id="2-试述数据库管理员、系统分析人员、数据库设计人员、应用程序员的职责"><a href="#2-试述数据库管理员、系统分析人员、数据库设计人员、应用程序员的职责" class="headerlink" title="2.试述数据库管理员、系统分析人员、数据库设计人员、应用程序员的职责"></a>2.试述数据库管理员、系统分析人员、数据库设计人员、应用程序员的职责</h3><blockquote><blockquote><p><em><strong>数据管理员</strong></em><br>负责<code>全面管理和控制</code>数据库系统: </p><ol><li>决定数据库中的信息内容和<code>结构</code>;</li><li>决定数据库的存储结构和<code>存储</code>策略;</li><li>定义数据的安全性要求和完整性<code>约束</code>条件;</li><li>监督和控制数据库的使用和<code>运行</code>;</li><li><code>改进</code>和重组数据库系统;</li></ol></blockquote><blockquote><p><em><strong>系统分析人员</strong></em><br>负责应用系统的<code>需求分析和规范说明</code>,系统分析员要和用户及DBA相结合,确定系统的硬件,软件配置,并参与数据库系统的概要设计。 </p></blockquote><blockquote><p><em><strong>数据库设计人员</strong></em><br>负责数据中<code>数据的确定、数据库各级模式的设计</code>。数据库设计人员必须参加用户需求调查和系统分析,然后进行数据库设计。很多时候由数据库管理员担任。 </p></blockquote><blockquote><p><em><strong>应用程序员</strong></em><br>负责设计和编写应用系统的程序模块,并进行调试和安装。 </p></blockquote></blockquote><h3 id="3-试举出三个层次模型的和三个网状模型的例子"><a href="#3-试举出三个层次模型的和三个网状模型的例子" class="headerlink" title="3.试举出三个层次模型的和三个网状模型的例子"></a>3.试举出三个层次模型的和三个网状模型的例子</h3><blockquote><p><em><strong>层次模型</strong></em> </p><ol><li>教员学生层次数据库模型<br><img src="/2022/09/30/databse-concept/levelModel1.jpg" alt="levelModel1"></li><li>行政机构层次数据库模型<br><img src="/2022/09/30/databse-concept/levelModel2.jpg" alt="levelModel2"></li><li>行政区域层次数据库模型<br><img src="/2022/09/30/databse-concept/levelModel3.jpg" alt="levelModel3"></li></ol></blockquote><blockquote><p><em><strong>网状模型</strong></em></p><ol><li>学生从属网状模型<br><img src="/2022/09/30/databse-concept/netModel1.jpg" alt="netModel1"></li><li>学生选课网状模型<br><img src="/2022/09/30/databse-concept/netModel2.jpg" alt="netModel2"></li><li>城市航班网状模型<br><img src="/2022/09/30/databse-concept/netModel3.jpg" alt="netModel3"></li></ol></blockquote>]]></content>
<categories>
<category> database </category>
</categories>
<tags>
<tag> database </tag>
</tags>
</entry>
</search>