Jekyll2023-08-11T11:35:40+00:00https://www.ingernotes.cn/feed.xmlInger Notes:blush: inger notes about cs, writing, etc.系统架构设计师备考 - 系统工程与信息系统基础2023-08-06T00:00:00+00:002023-08-06T00:00:00+00:00https://www.ingernotes.cn/sa-1<h2 id="系统工程与信息系统基础">系统工程与信息系统基础</h2>
<h3 id="系统工程">系统工程</h3>
<p>背景:诞生于二战期间</p>
<p>概念:</p>
<ol>
<li>一种组织管理技术;</li>
<li>从整体出发、系统观念出发,以求 <strong>整体最优</strong>;</li>
<li>现代的科学决策方法</li>
</ol>
<p>方法:</p>
<ol>
<li><strong>霍尔三位结构</strong>
<ol>
<li>逻辑维:明确问题、确定目标、系统综合、系统分析、优化、系统决策、实施计划</li>
<li>时间维:规划、拟案、研制、生产、安装、运行、更新</li>
<li>知识维</li>
</ol>
</li>
<li>切克兰德</li>
<li>并行工程</li>
<li>综合集成法:钱学森命名,“简单系统”、“巨系统”;</li>
<li>WSR</li>
</ol>
<p>系统工程生命周期阶段:探索性研究、概念、开发、生产、使用、保障、退役;</p>
<p>系统工程生命周期方法:计划驱动、渐进迭代式、精益开发、敏捷开发;</p>
<h3 id="信息系统">信息系统</h3>
<p>信息系统生命周期:</p>
<ol>
<li>产生/立项:初步想法、需求分析</li>
<li>开发:总体规划、分析、设计、实施、验收</li>
<li>运行:通过验收、移交之后</li>
<li>消亡:更新改造、功能扩展、报废重建</li>
</ol>
<p><strong>信息系统建设原则</strong>(论文写作的支撑):</p>
<ul>
<li><strong>高层管理人员介入</strong>原则,如:CIO 介入【解决阻力问题】、一把手工程;</li>
<li><strong>用户参与</strong>开发原则,用户确定范围、核心用户全程参与、用户深度参与;</li>
<li><strong>自顶向下规划</strong>原则,以此减少信息不一致的现象;</li>
<li><strong>工程化</strong>原则,引入软件工程;</li>
<li>其他原则:创新性原则、整体性原则、发展性原则、经济型原则等;</li>
</ul>
<p>信息系统开发方法:</p>
<p>原型法【需求阶段】</p>
<p>针对需求不明确,按功能分为:水平原型(界面)、垂直原型(复杂算法);</p>
<p>按最终结果分:</p>
<ul>
<li>抛弃式原型:得到需求后,抛弃原型,全新开发;</li>
<li>演化式原型:原型逐步演化为最终系统;</li>
</ul>
<p>开发方法【开发阶段】</p>
<ul>
<li>结构化法:早期,自顶向下,逐步分解求精,应变能力差,如:瀑布模型;</li>
<li><strong>面向对象</strong>方法:<strong>自底向上</strong>,阶段界限不明,更好应变、复用;</li>
<li><strong>面向服务</strong>的方法:粗粒度、松耦合,标准化和构件化,多个服务协作形成业务流程;</li>
</ul>
<p>其他信息系统开发方法:</p>
<ul>
<li><strong>形式化</strong>方法:<strong>数学模型化</strong>,所有东西均可证明/验证,而不是测试;如:净室软件工程,芯片设计软件、航天设计软件,需要数学模型和物理模型作支撑。</li>
<li>统一过程方法(UP)</li>
<li>敏捷方法</li>
<li>基于架构的开发方法(ABSD)</li>
</ul>
<p>信息系统分类:</p>
<ul>
<li>业务处理系统 TPS: 早期最初级的信息系统,主要功能为数据输入、数据处理、数据库维护、文件报表产生等。</li>
<li>管理信息系统 MIS:高度集成化的人机信息系统,在 TPS 基础上引进大量管理方法对企业整体信息进行处理,并利用信息进行预测、控制、计划、辅助企业全面管理的信息系统。如,图书管理系统、学生管理系统等;</li>
<li>决策支持系统 DSS:由<strong>语言系统</strong>、<strong>知识系统</strong>和<strong>问题处理</strong>系统组成,用于辅助决策、支持决策。</li>
<li>专家系统 ES:知识 + 推理,人工智能的一个重要分支,可处理不确定的知识,使用于特定的领域。知识库存储求解实际问题的领域知识,推理机实质是规则解释器。</li>
<li>办公自动化系统 OAS:由计算机设备、办公设备、数据通信及网路设备、软件系统组成。</li>
<li>企业资源计划 ERP:打通供应链,集成,整合。</li>
</ul>ingerchao系统工程与信息系统基础系统架构设计师备考 - 软件架构设计2023-08-06T00:00:00+00:002023-08-06T00:00:00+00:00https://www.ingernotes.cn/sa-2<h3 id="软件架构的概念">软件架构的概念</h3>
<p>架构的本质:</p>
<ol>
<li>为软件系统提供了一个结构、行为和属性的高级抽象;</li>
<li>是特定应用领域的惯用模式,架构定义一个词汇表和一组约束;</li>
</ol>
<p>架构的作用:</p>
<ol>
<li>是项目干系人进行交流的手段;</li>
<li>可传递和可复用的模型,通过研究软件架构可能预测软件的质量;</li>
<li>使推理和控制的更改更加简单,有助于循序渐进的原型设计,可以作为培训的基础。</li>
</ol>
<p>软件架构 = 软件体系结构,架构设计就是需求分配,即将满足需求的职责分配到组件上。</p>
<h3 id="41-视图">4+1 视图</h3>
<p>架构发展历程:</p>
<ol>
<li>无架构阶段:汇编语言;</li>
<li>萌芽阶段:程序结构设计;</li>
<li>初级阶段:统一建模语言 UML;</li>
<li>高级阶段:4+1 视图;</li>
</ol>
<p>何为视角与视图?从不同的视角来检查,所以会有不同的视图。</p>
<p>架构的 4 + 1 视图中,1表示场景,4分别指的是逻辑视图、开发视图、进程视图(过程视图)、物理视图。逻辑视图指最终用户的功能需求,开发视图指编程人员的软件开发,进程视图为系统集成人员关心的性能、可扩充性、吞吐量等,物理视图指系统工程人员负责的系统拓扑、安装、通信等。</p>
<p><img src="./../assets/images/ruankao/sa-41.png" alt="image-20230806223150711" /></p>
<p><img src="./../assets/images/ruankao/uml-41.png" alt="image-20230806223301358" /></p>
<h3 id="软件架构风格">软件架构风格</h3>
<p>重点五大架构风格,其中每种风格又分为多种子风格。</p>
<ul>
<li>数据流风格:以数据处理为导向
<ul>
<li>批处理</li>
<li>管道-过滤器</li>
</ul>
</li>
<li>调用/返回风格
<ul>
<li>主程序/子程序</li>
<li>面向对象</li>
<li>层次结构</li>
</ul>
</li>
<li>独立构件风格:强调每个构件尽可能独立,避免紧耦合
<ul>
<li>进程通信</li>
<li>事件驱动系统(隐式调用)</li>
</ul>
</li>
<li>虚拟机风格:构造虚拟机去完成内容的解读
<ul>
<li>解释器</li>
<li>规则系统</li>
</ul>
</li>
<li>仓库风格
<ul>
<li>数据库系统</li>
<li>黑板系统</li>
<li>超文本系统</li>
</ul>
</li>
</ul>
<p>在应用过程中,往往是多种架构风格同时使用。在写论文时,不可以只用一种架构风格。了解每种架构风格,应用时扬长避短,综合应用。</p>
<h4 id="数据流风格">数据流风格</h4>
<p>分步处理数据,数据驱动,前一步的处理结果是后一步的输入内容。</p>
<p>优点:</p>
<ol>
<li>数据和处理过程独立,松耦合,复合高内聚、低耦合;</li>
<li>具有良好的重用性 / 可维护性;</li>
<li>可扩展性,适配标准接口;</li>
<li>隐蔽性良好;</li>
<li>支持并行</li>
</ol>
<p>缺点:</p>
<ol>
<li>交互性较差:数据输入后一步步进行处理,不需要人工干预,所以对人操作的支持性较差;</li>
<li>复杂性较高;</li>
<li>性能较差:每个过滤器都需要解析与合成数据;</li>
</ol>
<p>典型实例:传统编译器、网络报文处理等。</p>
<p>子风格:</p>
<ul>
<li>批处理:<strong>大量整体数据</strong>批量处理、无需用户交互;</li>
<li>管道-过滤器:<strong>流式数据</strong>、弱用户交互;</li>
</ul>
<h4 id="调用返回风格">调用/返回风格</h4>
<p><img src="./../assets/images/ruankao/invoke-return.png" alt="image-20230807143746790" /></p>
<ul>
<li>主程序/子程序:面向过程</li>
<li>面向对象:对象的方法调用</li>
<li>层次结构:层与层之间的方法调用;各个层次的组建形成不同功能级别的虚拟机;多层相互协同工作,而且实现透明。例如 ISO 七层模型。</li>
</ul>
<p>优点:</p>
<ol>
<li>良好的重用性,只要接口不变可用在其他处;</li>
<li>可维护性好</li>
<li>可扩展性好,支持递增设计;</li>
</ol>
<p>缺点:</p>
<ol>
<li>并不是每个系统都方便分层;</li>
<li>很难确定合适的、正确的层次抽象方法;层次多影响效率,层次少可能导致逻辑结构不清楚、内容混杂;</li>
<li>不同层次之间的耦合度高的系统很难实现;</li>
</ol>
<h4 id="独立构件风格">独立构件风格</h4>
<p><img src="./../assets/images/ruankao/independent-component.png" alt="image-20230807200736666" /></p>
<p>基本思想:构件之间不直接交互,主函数触发事件,通过事件管理机制,通知执行子函数。</p>
<p>优点:</p>
<ol>
<li>松耦合;</li>
<li>良好的重用性/可修改性/可扩展性;</li>
</ol>
<p>缺点:</p>
<ol>
<li>构件放弃了对系统计算的控制。不能确定构件是否响应所触发的事件,也不能保证这些过程调用的顺序。</li>
<li>数据交换的问题。</li>
<li>过程的语义依赖于被触发事件的上下文约束,关于正确性的推理就存在问题。</li>
</ol>
<p>例如:事件调用、按钮响应;</p>
<h4 id="虚拟机风格">虚拟机风格</h4>
<p>例如:Java 虚拟机。C 语言代码通过编译生成机器语言代码,不同操作系统对机器语言的解释方式可能不同。Java 语言代码通过编译成<strong>字节码文件</strong>在 Java 虚拟机上执行,不同的操作系统拥有不同的 Java 虚拟机,通过 Java 虚拟机实现跨平台。</p>
<p>子风格:</p>
<ul>
<li>解释器:适用于需要 “自定义规则” 的场合;</li>
<li>规则系统:在解释器的基础上增加经验规则,适用于专家系统;</li>
</ul>
<p>优点:可以灵活应对自定义场景;</p>
<p>缺点:复杂度较高</p>
<h4 id="仓库风格">仓库风格</h4>
<p><img src="./../assets/images/ruankao/repo-style.png" alt="image-20230807202132160" /></p>
<p>仓库:用来存储数据的中央部件;</p>
<p>子风格:</p>
<ul>
<li>数据库系统:各种操作围绕中心数据进行处理;</li>
<li>黑板系统:语音识别、知识推理;黑板作为中央数据源,在数据库风格基础上增加了触发知识源的机制;</li>
<li>超文本系统</li>
</ul>
<p>应用:操作系统的注册表、剪贴板、</p>
<h4 id="其他风格">其他风格</h4>
<p><strong>闭环控制风格(过程控制)</strong></p>
<p><img src="./../assets/images/ruankao/close-controll-stype.png" alt="image-20230807203014346" /></p>
<p>适用于嵌入式系统,用于解决简单闭环控制问题。</p>
<p>经典应用:空调温控,定速巡航。</p>
<p><strong>C2风格</strong>:构件和连接件。</p>ingerchao软件架构的概念TED:3 Ways to plan for the long term2023-06-09T00:00:00+00:002023-06-09T00:00:00+00:00https://www.ingernotes.cn/long-term-plans<h2 id="ted3-ways-to-plan-for-the-long-term">TED:3 Ways to plan for the long term</h2>
<p><strong>Short-Termism</strong>:拒绝短期主义。短期主义会让我们都只想赚快钱。</p>
<p>LONGPATH: 制定出长期计划,但是两周就把它忘了。</p>
<ol>
<li>Transgenerational thinking:明确你在解决问题过程中,所扮演的角色。要意识到自己对孩子的影响,以及对孩子的孩子的影响。</li>
<li>Futures thinking: 以10年、15年的尺度去思考问题,透过时间来思考问题。不要讨论单一的未来,而是未来的无限可能。</li>
<li>Telos Thinking: 结果导向。问问自己:最后怎么样?</li>
</ol>
<p>Future 需要执行力和行动去推动,但在短期主义会束缚我们。身处一个短视的社会,我们开始怀疑自己把握未来的能力。实际上,未来是被我们完全掌握的。</p>ingerchaoTED:3 Ways to plan for the long term软件设计师备考 - 多媒体基础2023-05-02T00:00:00+00:002023-05-02T00:00:00+00:00https://www.ingernotes.cn/ruankao-duomeiti<h3 id="1-音频相关概念">1. 音频相关概念</h3>
<p>声音的带宽:</p>
<ul>
<li>人耳:20 Hz - 20 kHz</li>
<li>说话:300 - 3400 Hz</li>
<li>乐器:20 Hz - 20 kHz</li>
</ul>
<p>采样:声音(模拟信号)转为波形(数字信号);</p>
<ul>
<li>采样频率</li>
<li>采样精度</li>
<li>采样频率应为声音最高频率 2 倍</li>
</ul>
<h3 id="2-图像相关概念">2. 图像相关概念</h3>
<ul>
<li>亮度</li>
<li>色调</li>
<li>饱和度:颜色的鲜艳程度</li>
<li>彩色空间:RGB、YUV(电视,兼容)、CMY / CMYK(印刷领域)、HSV / HSB(艺术家空间)</li>
</ul>
<h3 id="3-媒体的种类">3. 媒体的种类</h3>
<ul>
<li>感觉媒体:人类接触信息的感觉形式,如:视觉、听觉、触觉、嗅觉和味觉;</li>
<li>表示媒体:信息的表示形式,如:文字、图形、图像、动画、音频和视频等;</li>
<li>显示媒体 / 表现媒体:表现和获取信息的物理设备(输入输出设备),如:键盘、鼠标、麦克风、显示器、打印机等;</li>
<li>存储媒体:存储数据的物理设备,如:磁盘、光盘和内存等;</li>
<li>传输媒体:传输数据的物理载体,如:光缆、电缆、交换设备等;</li>
</ul>
<h3 id="4-多媒体相关计算问题">4. 多媒体相关计算问题</h3>
<ol>
<li>图像容量计算:容量(B)= 像素 * 每个像素点的位数 / 8</li>
<li>音频容量计算:容量(B) = 采样频率 * 量化/采样位数 * 声道数 / 8</li>
<li>视频容量计算:容量(B)= 每帧图像容量 * 每秒帧数 * 视觉 + 音频容量 * 时间</li>
</ol>
<h3 id="5-常见多媒体标准">5. 常见多媒体标准</h3>
<ul>
<li>JPEG:最常见的图像标准,有损压缩标准,RGB转YUV,用到了离散余弦算法;</li>
<li>JPEG-2000:有损 & 无损都有,常用于医学图像应用,用到了小波变换;</li>
<li>MPEG-1、2、4、7、21;</li>
</ul>
<h3 id="6-数据压缩">6. 数据压缩</h3>
<p>压缩的前提:必须有冗余才可以压缩;</p>
<ul>
<li>空间冗余</li>
<li>时间冗余</li>
<li>视觉冗余</li>
<li>信息熵冗余</li>
<li>结构冗余</li>
<li>知识冗余</li>
</ul>
<p>无损压缩:也称之为熵编码法,可以还原的压缩,如:哈夫曼编码、rar、zip等;</p>
<p>有损压缩:也称之为熵压缩法,压缩过程中丢失了部分信息,导致无法还原的,如:JPEG;</p>ingerchao1. 音频相关概念论文阅读-Zookeeper: Wait-free coordination for Internet-scale system2022-11-07T00:00:00+00:002022-11-07T00:00:00+00:00https://www.ingernotes.cn/Zookeeper-notes<h2 id="zookeeper-无需等待的互联网规模协调系统">Zookeeper: 无需等待的互联网规模协调系统</h2>
<p>Zookeeper 是什么?动物园管理者?一图胜千言。Zookeeper 是由雅虎研发的顶层软件项目,为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。</p>
<p><img src="./../assets\images\program\backend\apache-and-zookeepter.png" alt="image-20221107173955674" /></p>
<p>目前,分布式应用往往是由多个独立的程序运行在多个机器上的,开发人员必须要处理协调逻辑和应用程序本身的逻辑。</p>
<p><img src="./../\assets\images\program\backend\zookeeper-question-1.png" alt="image-20221108153726865" /></p>
<p><img src="./../\assets\images\program\backend\zookeeper-question-2.png" alt="image-20221108153758367" /></p>
<p><img src="./../\assets\images\program\backend\zookeeper-question-3.png" alt="image-20221108153824934" /></p>
<p>具体来说,需要为每个特定任务都开发一个协调逻辑:</p>
<ul>
<li>主节点选择</li>
<li>锁服务</li>
<li>配置</li>
</ul>
<p>总的来说:提供一个API来实现上述多个服务</p>
<p>ZooKeeper:提供了公共的API,以便于开发人员可以实现自己的原语。</p>
<h4 id="专业术语定义">专业术语定义</h4>
<ul>
<li><em>Client</em>:客户端,ZooKeeper 服务的用户;</li>
<li><em>Server</em>: 服务端,提供 Zookeeper 服务的程序;</li>
<li><em>znode</em>: 内存里的 Zookeeper 数据节点,通过命名空间的层级来组织(the data tree);</li>
<li><em>Update/write</em>: 任何操作,更新 data tree 的状态;</li>
<li>当客户端连接到 ZooKeeper 时建立会话(<em>Session</em>)</li>
</ul>
<h4 id="zookeeper-的数据模型">ZooKeeper 的数据模型</h4>
<ul>
<li>znodes 由层级的命名空间来组织;</li>
<li>使用标准 Unix 文件系统路径的符号来表示;</li>
<li>znodes 不是通常的数据存储结构,而是为了映射到客户端应用程序的抽象。</li>
</ul>
<h4 id="znode">Znode</h4>
<ul>
<li>
<p>Znode 通常由客户端显式创建或删除;</p>
</li>
<li>临时情况下:显式删除 znode,或让系统在会话创建终止时自动移除 znode;</li>
<li><em>SEQUENTIAL</em> 标志位:
<ul>
<li>单调递增计数器,附加于znode的路径上</li>
<li>父节点下的新 znode 的计数值总是大于已有的子节点 znode 的计数器值;</li>
</ul>
</li>
<li><em>WATCH</em> 标志位:
<ul>
<li>允许客户端在无需轮询的情况下及时接受变更的通知;</li>
<li>Watches 表明发生了变化,但不提供变更逻辑;</li>
</ul>
</li>
</ul>
<h4 id="zookeeper-api"><a href="https://zookeeper.apache.org/doc/r3.4.6/api/org/apache/zookeeper/ZooKeeper.html">ZooKeeper API</a></h4>
<table>
<thead>
<tr>
<th>方法</th>
<th>入参</th>
<th>返回值</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>create</td>
<td>path, data, flags</td>
<td>String</td>
<td>创建znode</td>
</tr>
<tr>
<td>delete</td>
<td>path, version</td>
<td>void</td>
<td>删除znode</td>
</tr>
<tr>
<td>exists</td>
<td>path, watch</td>
<td>Stat</td>
<td> </td>
</tr>
<tr>
<td>getData</td>
<td>path, watch</td>
<td>(data, Stat)</td>
<td>获取znode数据和状态</td>
</tr>
<tr>
<td>setData</td>
<td>path, data, version</td>
<td>Stat</td>
<td>如果当前版本和入参</td>
</tr>
</tbody>
</table>
<p>ZooKeeper 不提供句柄来访问 znodes;</p>
<p>所有的方法都有同步和异步两种实现方式。</p>
<h4 id="zookeeper-原则">ZooKeeper 原则</h4>
<p>Zookeeper 线性写入:所有更新 Zookeeper 状态的请求都可序列化并服从优先级。</p>
<p>FIFO 客户端顺序:来自给定客户端的所有请求都按照客户端发送的顺序执行。</p>
<h4 id="原语的例子">原语的例子</h4>
<p>当选取一个新的主节点时,我们<strong>不希望其他进程使用的配置做出改变</strong>。如果新的主节点在配置文件更新的过程中挂了,我们<strong>不希望进程使用的是配置的一部分内容</strong>。</p>
<p>因此,删除 ready 态的 znode,随后,znodes 更新各种配置文件,再创建ready 态的 znode。</p>
<p><strong>1. 配置(Configuration)</strong></p>
<ol>
<li>新请求如何查询配置文件?
<ul>
<li>假设配置文件存储在 /app1/config 路径下, ` getData(/app/config, true)`</li>
</ul>
</li>
<li>管理员如何在运行时改变配置文件?
<ul>
<li><code class="language-plaintext highlighter-rouge">setData(/app1/config/config_data, -1)</code></li>
</ul>
</li>
<li>其他程序如何读取新配置文件?
<ul>
<li><code class="language-plaintext highlighter-rouge">getData(/app1/config, true)</code></li>
</ul>
</li>
</ol>
<p><strong>2. 组成员(Group Membership)</strong></p>
<p><img src="./../\assets\images\program\backend\zookeeper-question-group-memberships.png" alt="image-20221108175433393" /></p>
<p><strong>3. 简单的锁(Simple Locks)</strong></p>
<p>一个应用程序中的对象如何通过锁公用一个数据源?</p>
<p><img src="./../\assets\images\program\backend\zookeeper-simple-locks.png" alt="image-20221108175225762" /></p>
<p><strong>4. 没有羊群效应的简单锁(Simple Locks without Herd Effect)</strong></p>
<blockquote>
<p>Herd Effect 注:在计算机科学中,当事件发生时,大量等待事件的进程或线程被唤醒,但只有一个进程能够处理该事件时,就会出现从众问题。 当进程唤醒时,它们将各自尝试处理该事件,但只有一个会获胜。</p>
</blockquote>
<p><img src="./../\assets\images\program\backend\zookeeper-simple-locks-without-herd-effect.png" alt="image-20221108193034660" /></p>
<p><strong>5. 读/写锁</strong></p>
<p><img src="./../\assets\images\program\backend\zookeeper-simple-read-write-locks.png" alt="image-20221108193220354" /></p>
<p><img src="./../\assets\images\program\backend\read-write-lock.png" alt="image-20221108200009555" /></p>
<p>吞吐量:设置250个客户端,每个客户端至少又 100 个未完成的请求(对1k数据的读或写)。</p>
<p><img src="C:\Users\SFTC\AppData\Roaming\Typora\typora-user-images\image-20221108200319692.png" alt="image-20221108200319692" style="zoom:50%;" /></p>
<h4 id="总结">总结</h4>
<p>无需等待、事件排序、Watch 机制</p>
<hr />
<ul>
<li><a href="https://cwiki.apache.org/confluence/display/ZOOKEEPER/Index">ZooKeeper wiki</a></li>
<li>https://people.eecs.berkeley.edu/~istoica/classes/cs294/15/notes/18-zookeeper.pdf</li>
<li>https://pdfs.semanticscholar.org/e310/b53377ae41eb56167b12c828f12d799073e1.pdf</li>
</ul>ingerchaoZookeeper: 无需等待的互联网规模协调系统论文阅读笔记:The Chubby lock service for loosely-coupled distributed systems2022-09-21T00:00:00+00:002022-09-21T00:00:00+00:00https://www.ingernotes.cn/chubby-algorithm-paper<h3 id="chubby-algorithm--mike-burrows-google-inc-2006">Chubby Algorithm – Mike Burrows, Google Inc. (2006)</h3>
<h3 id="摘要">摘要</h3>
<p>我们描述了我们使用 Chubby 锁服务的经验,该服务旨在为松耦合(loosely-coupled)的分布式系统提供粗粒度(coarse-grained)的锁以及可靠的(尽管是低容量的)存储。 Chubby 提供的接口很像带有咨询锁的分布式文件系统,但设计重点是可用性(availability)和可靠性(reliability),而不是高性能。该服务的许多实例已经使用了一年多,其中几个实例同时处理了数万个客户端。本论文描述了初始设计和预期用途,将其与实际用途进行了比较,并解释了如何修改设计以适应差异。</p>
<hr />
<p>References:</p>
<ul>
<li><a href="https://www.geeksforgeeks.org/difference-between-loosely-coupled-and-tightly-coupled-multiprocessor-system/">Difference between Loosely Coupled and Tightly Coupled Multiprocessor System</a></li>
</ul>ingerchaoChubby Algorithm – Mike Burrows, Google Inc. (2006)松耦合和紧耦合系统2022-09-21T00:00:00+00:002022-09-21T00:00:00+00:00https://www.ingernotes.cn/difference-distributed-system<h3 id="0-相关定义">0. 相关定义</h3>
<p>多处理器(Multiprocessor)系统:多处理器是具有两个或多个中央处理单元 (CPU) 的计算机系统,它们共享对公共 RAM 的完全访问权限。</p>
<p>分布式系统(Distributed System):分布式系统是<strong>物理上独立</strong>的、<strong>可能是异构</strong>的<strong>计算机系统的集合</strong>,这些计算机系统通过<strong>网络</strong>(LAN 或 WAN)为用户提供对系统维护的各种资源的访问。</p>
<p>并行处理系统(Parallel Computer System):指同时执行多个任务或多条指令或同时对多个数据项进行处理的计算机系统。</p>
<p>###1. 松耦合多处理器系统</p>
<p>松耦合的多处理器系统,有分布式内存而不是共享内存,模块间通过 MTS(消息传输系统)网络连接。</p>
<p><img src="./../assets/images/program/backend/loosely-coupled-system.png" alt="img" /></p>
<h3 id="2-紧耦合多处理器系统">2. 紧耦合多处理器系统</h3>
<p>紧耦合多处理器系统有共享内存,模块间通过处理器-内存间连接 PMIN(processor-memory interconnection network)、I/O-处理器间连接 IOPIN(I/O-processor interconnection network) 和中断信号 ISIN(interrupt-signal interconnection network)连接。</p>
<p><img src="./../assets/images/program/backend/tightly-coupled-system.png" alt="img" /></p>
<h3 id="3-二者的不同">3. 二者的不同</h3>
<table>
<thead>
<tr>
<th>松耦合</th>
<th>紧耦合</th>
</tr>
</thead>
<tbody>
<tr>
<td>分布式内存</td>
<td>共享内存</td>
</tr>
<tr>
<td>数据传输速率低</td>
<td>数据传输速率高</td>
</tr>
<tr>
<td>费用低</td>
<td>费用高</td>
</tr>
<tr>
<td>模块间通过消息传输系统MTS通信</td>
<td>PMIN, IOPIN, ISIN</td>
</tr>
<tr>
<td>不存在内存冲突</td>
<td>存在内存冲突</td>
</tr>
<tr>
<td>任务间的交互程度低</td>
<td>任务间的交互程度高</td>
</tr>
<tr>
<td>处理器和 I/O 设备之间存在直接连接</td>
<td>IOPIN 处理 I/O设备和处理器之间的连接</td>
</tr>
<tr>
<td>松耦合多处理器的应用在分布式计算系统(distributed computing systems)</td>
<td>紧耦合多处理器的应用在并行处理系统(parallel processing systems)</td>
</tr>
</tbody>
</table>ingerchao0. 相关定义邓紫棋新专辑启示录MV剧情梳理2022-09-15T00:00:00+00:002022-09-15T00:00:00+00:00https://www.ingernotes.cn/gloria-qishilu<ol>
<li>受难曲 – GEM 和大明星谈恋爱被网络暴力;</li>
<li>Hell – GEM 和大明星男朋友吵架、发生车祸;</li>
<li>少年与海 – Nabi 和 GEM 之前的生活片段,以及事故发生后 GEM 封闭自己,不理 Nabi,Nabi 给她送了 VR 眼镜;</li>
<li>不想回家 – GEM 在虚拟世界(乐土)创建角色 Gloria,Gloria 和 Nabi 逛街,并选择了 Evan 谈恋爱,最后心动的时候把角色删除了;</li>
<li>只有我和你的地方 – Gloria 和 Evan 在虚拟世界谈恋爱;</li>
<li>你不是第一个离开的人 – Gloria 在废土醒来;</li>
<li>冰河时代 – 废土、现实世界里 删除角色的 GEM,乐凡在现实里找人,试图修复 Gloria;</li>
<li>老人与海 – 乐凡在现实里做了一个和 Gloria 一样的模型,试图唤醒 Gloria;</li>
<li>Gloria – 程序修复好了,虚拟世界里心碎的 GLoria 找到了逃离废土的门;</li>
<li>FIND YOU – Evan(孙晨竣饰)排除万难把Gloria(G.E.M.邓紫棋饰)的数据从乐土带到现实,带着这个刚苏醒的AI机器人重新认识世界。就像过往在乐土世界一样,如今他们在现实里一起分享着很多快乐的时光,而Gloria作为一个AI机器人,也快速地学习着Evan的一切,包括他的厨艺,和他的爱。</li>
<li>离心力 – 某一天,Gloria(G.E.M.邓紫棋饰)来到一间跟乐土世界里一模一样的YOUNG MAN & SEA线下酒吧,那是她和Evan在乐土第一次约会的地点。她进去点了当时的定情饮料「银色漩涡」,却意外地收到了一封信。Gloria拆开突如其来的信件,原来命运早有安排,这封信竟然是来自自己角色的创建者:秋(G.E.M.邓紫棋饰)。原来秋就住在Evan(孙晨竣饰)家对面的大厦。Gloria发现原来自己的创建者是个身体残缺的女孩,开始明白自己为什么会被抛弃到废土,开始理解她的难处。而在跟Evan相处的这段时光里,Gloria也从与Evan的相处中,慢慢感受到爱、学习到爱。如果爱是不求自己的益处,只求别人的益处,那Gloria会怎么做呢?(简介)</li>
<li>让世界暂停一分钟 – Gloria(G.E.M.邓紫棋饰)知道自己不属于这个世界,她做出了一个出于爱的决定。Evan(孙晨竣饰)发现Gloria自行删除数据回到废土,一时间无法接受,频临崩溃。那一夜Evan回到家中,发现Gloria在窗台留给自己的字条,他拉开了窗帘,第一次看见了那个坐在轮椅上,跟Gloria长得一模一样的女孩。</li>
<li>夜的尽头 – 已经能想到演唱会大家一起跳了,好喜欢。</li>
<li>天空没有尽头 – 现实里的 Gloria 和 Evan 真的在一起了,大结局。</li>
</ol>
<blockquote>
<p>从第十首 FIND YOU 开始故事线就和之前的一样啦。</p>
<p>注:这篇是从老人与海发布后开始写的。</p>
</blockquote>ingerchao受难曲 – GEM 和大明星谈恋爱被网络暴力; Hell – GEM 和大明星男朋友吵架、发生车祸; 少年与海 – Nabi 和 GEM 之前的生活片段,以及事故发生后 GEM 封闭自己,不理 Nabi,Nabi 给她送了 VR 眼镜; 不想回家 – GEM 在虚拟世界(乐土)创建角色 Gloria,Gloria 和 Nabi 逛街,并选择了 Evan 谈恋爱,最后心动的时候把角色删除了; 只有我和你的地方 – Gloria 和 Evan 在虚拟世界谈恋爱; 你不是第一个离开的人 – Gloria 在废土醒来; 冰河时代 – 废土、现实世界里 删除角色的 GEM,乐凡在现实里找人,试图修复 Gloria; 老人与海 – 乐凡在现实里做了一个和 Gloria 一样的模型,试图唤醒 Gloria; Gloria – 程序修复好了,虚拟世界里心碎的 GLoria 找到了逃离废土的门; FIND YOU – Evan(孙晨竣饰)排除万难把Gloria(G.E.M.邓紫棋饰)的数据从乐土带到现实,带着这个刚苏醒的AI机器人重新认识世界。就像过往在乐土世界一样,如今他们在现实里一起分享着很多快乐的时光,而Gloria作为一个AI机器人,也快速地学习着Evan的一切,包括他的厨艺,和他的爱。 离心力 – 某一天,Gloria(G.E.M.邓紫棋饰)来到一间跟乐土世界里一模一样的YOUNG MAN & SEA线下酒吧,那是她和Evan在乐土第一次约会的地点。她进去点了当时的定情饮料「银色漩涡」,却意外地收到了一封信。Gloria拆开突如其来的信件,原来命运早有安排,这封信竟然是来自自己角色的创建者:秋(G.E.M.邓紫棋饰)。原来秋就住在Evan(孙晨竣饰)家对面的大厦。Gloria发现原来自己的创建者是个身体残缺的女孩,开始明白自己为什么会被抛弃到废土,开始理解她的难处。而在跟Evan相处的这段时光里,Gloria也从与Evan的相处中,慢慢感受到爱、学习到爱。如果爱是不求自己的益处,只求别人的益处,那Gloria会怎么做呢?(简介) 让世界暂停一分钟 – Gloria(G.E.M.邓紫棋饰)知道自己不属于这个世界,她做出了一个出于爱的决定。Evan(孙晨竣饰)发现Gloria自行删除数据回到废土,一时间无法接受,频临崩溃。那一夜Evan回到家中,发现Gloria在窗台留给自己的字条,他拉开了窗帘,第一次看见了那个坐在轮椅上,跟Gloria长得一模一样的女孩。 夜的尽头 – 已经能想到演唱会大家一起跳了,好喜欢。 天空没有尽头 – 现实里的 Gloria 和 Evan 真的在一起了,大结局。Resources of Spring Framework2022-08-11T00:00:00+00:002022-08-11T00:00:00+00:00https://www.ingernotes.cn/Resources-of-Spring-Framework<p>Java 语言中如果要通过 HTTP 或 FTP 协议访问文件,可以通过 UML 类编写一些管道代码。‘</p>
<p>同样,如果要在应用程序的类路径下(或者在 servlet 上下文中)读文件,必须要知道该应用程序的跟路径在哪里。因此,需要编写大量模版代码来访问路径,而且,每个用例(URL、类路径、servlet 上下文)的代码都会有所不同。</p>
<p>Spring 的抽象资源(resource abstraction)解决了上述问题。以如下的代码为例:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">org.springframework.core.io.Resource</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyApplication</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">ApplicationContext</span> <span class="n">ctx</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">AnnotationConfigApplicationContext</span><span class="o">(</span><span class="n">someConfigClass</span><span class="o">);</span> <span class="c1">// (1)</span>
<span class="nc">Resource</span> <span class="n">aClasspathTemplate</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">getResource</span><span class="o">(</span><span class="s">"classpath:somePackage/application.properties"</span><span class="o">);</span> <span class="c1">// (2)</span>
<span class="nc">Resource</span> <span class="n">aFileTemplate</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">getResource</span><span class="o">(</span><span class="s">"file:///someDirectory/application.properties"</span><span class="o">);</span> <span class="c1">// (3)</span>
<span class="nc">Resource</span> <span class="n">anHttpTemplate</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">getResource</span><span class="o">(</span><span class="s">"https://marcobehler.com/application.properties"</span><span class="o">);</span> <span class="c1">// (4)</span>
<span class="nc">Resource</span> <span class="n">depends</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">getResource</span><span class="o">(</span><span class="s">"myhost.com/resource/path/myTemplate.txt"</span><span class="o">);</span> <span class="c1">// (5)</span>
<span class="nc">Resource</span> <span class="n">s3Resources</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">getResource</span><span class="o">(</span><span class="s">"s3://myBucket/myFile.txt"</span><span class="o">);</span> <span class="c1">// (6)</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>ingerchaoJava 语言中如果要通过 HTTP 或 FTP 协议访问文件,可以通过 UML 类编写一些管道代码。‘MySQL 开发规范2022-08-11T00:00:00+00:002022-08-11T00:00:00+00:00https://www.ingernotes.cn/MySQL-develop-principles<h3 id="核心原则">核心原则</h3>
<h4 id="1-尽量不在数据库做运算">1. 尽量不在数据库做运算</h4>
<p>SQL 不要使用 md5(), Order by Rand() 等这类运算函数,将复杂运算转移到程序端 CPU。</p>
<h4 id="2-控制单表数据量">2. 控制单表数据量</h4>
<p>单表数据量过大后会影响数据查询效率,严重情况下会导致整个库都卡住。一般情况下,按照一年内单表数据量预估:单表中纯 INT 不超过 10M 条元组,含 Char 不超过 5M 条元组。</p>
<p>同时,要尽量做好合理的分表,使单表数据量不超载,常见的分表策略有:</p>
<ul>
<li>通过 UserId 的 id 区间进行分表,常用于用户量大、用户特征明显的场景,例如:金融行业等;</li>
<li>通过 Date 字段的天、周、月分表,常用于时间计算频繁场景,例如:用户上网记录表、用户短信表、话费表等;</li>
<li>通过区域的省、市、区分表;</li>
<li>其他策略;</li>
</ul>
<p>分区表的适用场景主要有:</p>
<ol>
<li>表非常大,无法全部存在内存,或者只在表的最后有热点数据,其他都是历史数据;</li>
<li>分区表的数据更易维护,可以对独立的分区进行独立的操作;</li>
<li>分区表的数据可以分布在不同的机器上,从而高效使用资源;</li>
<li>可以使用分区表来避免某些特殊的瓶颈;</li>
<li>可以备份和恢复独立的分区;</li>
</ol>
<p>使用分区表时,需要注意一些相关的限制条件:</p>
<ol>
<li>一个表最多只能有 1024 个分区;</li>
<li>5.1 版本中,分区表表达式必须时整数,5.5 以上版本可以使用列分区;</li>
<li>分区字段中如果有主键和唯一索引列,那么主键列和唯一列都必须包含进来;</li>
<li>分区表中无法使用外键约束;</li>
<li>需要对现有表的结构进行修改;</li>
<li>所有分区都必须使用相同的存储引擎;</li>
<li>分区函数中可以使用的函数和表达式会有一些限制,todo:啥限制;</li>
<li>某些存储引擎不支持分区,todo 啥引擎;</li>
<li>对于 MyISAM 的分区表,不能使用 load index into cache;</li>
<li>对于 MyISAM 的分区表,使用分区表时需要打开更多的文件描述符。</li>
</ol>
<h4 id="3-尽量控制表字段数量">3. 尽量控制表字段数量</h4>
<p>单表的字段数量应该根据业务场景进行优化调整,使单表的字段数少而精,这样有以下好处:</p>
<ol>
<li>IO 高效;</li>
<li>全表遍历;</li>
<li>表修复快;</li>
<li>提高并发;</li>
<li>alter table 更快;</li>
</ol>
<p>按照单表 1G 体积,500W 行数据量进行评估:</p>
<ul>
<li>看顺序读 1G 文件所需的时间不超过 N 秒;</li>
<li>单行不超过 200 Byte,</li>
<li>不超过 50 个纯 int 字段;</li>
<li>不超过 20 个 char(10) 字段;</li>
</ul>
<p><strong>建议单表字段数上限控制在 20-50个</strong>。</p>
<h4 id="4-平衡范式与冗余">4. 平衡范式与冗余</h4>
<p>数据库表结构的设计要遵守三大范式:</p>
<ol>
<li>第一范式(确保每列保持原子性):单个字段不可再分;</li>
<li>第二范式(确保表中每列都和主键相关):不存在非主属性,只依赖部分主键,消除不完全依赖;</li>
<li>第三范式(确保每列都和主键直接相关):消除传递依赖。</li>
</ol>
<p>范式是以性能换取存储,冗余是以存储换取性能。因此,一般情况下工作中冗余更受欢迎。</p>
<p>模型设计时,这两方面的权衡首先应以企业提供的计算能力和存储资源为基础。其次,二者的权衡需要符合任务需要,因为一般互联网行业中都根据 Kimball 模式实施数据仓库,建模也是以任务驱动的。</p>
<h4 id="5-拒绝-3b">5. 拒绝 3B</h4>
<ul>
<li>Big SQL:应该将大 SQL 拆解成多条简单 SQL;</li>
<li>Big Transaction:事务/连接使用原则是 <strong>即开即用,用完即关</strong>;
<ul>
<li>与事务无关的操作应该放在事务外面,减少锁资源的占用;</li>
<li>不破坏一致性前提下,使用多个短事务代替一个长事务;</li>
</ul>
</li>
<li>Big Batch;</li>
</ul>
<p>在做数据库开发的时候要注意高并发下的瓶颈,防止因高并发造成数据库瘫痪 。</p>
<h3 id="字段类原则">字段类原则</h3>
<h4 id="1-用好数值字段类型">1. 用好数值字段类型</h4>
<p>MySQL 的三类数值类型有:</p>
<ul>
<li>整型:TINYINT(1Byte)、TINYINT(1Byte)、SMALLINT(2B)、MEDIUMINT(3B)、INT(4B)、BIGINT(8B)</li>
<li>浮点型:FLOAT(4B)、DOUBLE(8B)</li>
<li>十进制数字:DECIMAL(M, D)</li>
</ul>
<p><strong>INT(1) 和 INT(11)</strong>:1 与 11 是显示长度的区别,无论 INT(x) 的 x 是什么值,存储长度都是 4 Bytes。</p>
<p><strong>BIGINT AUTO_INCREMENT</strong>: 有符号 int 最大可以支持到约 22 亿,远远大于我们的需求和 MySQL 单表所能支持的性能上限。OLTP(On-Line Transaction Processing)应用中,单表规模一般保持在千万级别,不会达到 22 亿上限。如果加大预留量,可以把主键改为无符号整型,上限为 42 亿,预留量就会更加充足。</p>
<p>使用 bigint 会占用更大的磁盘和内存空间,无效占用会导致更多的数据换如换出,额外增加了 IO 的压力。因此,推荐主键使用 int unsigned 类型,不建议使用 bigint。</p>
<p><strong>DECIMAL(N, 0)</strong>: 如果采用 DECIMAL 类型,一般小数位不会默认是 0;如果要设置小数位数为0,建议直接使用整型。</p>
<h4 id="2-将字符转化为数字">2. 将字符转化为数字</h4>
<p>相比字符串型索引,数字型索引更高效、查询更快、占用空间更小,例如,将 IP 存储为 INT,而不是 CHAT(15),然后用 INET_ATON() 和 INET_NTOA() 实现 IP 字符串和数值之间的转换。</p>
<h4 id="3-优先使用-enum-或-set">3. 优先使用 ENUM 或 SET</h4>
<p>对于枚举型数据,推荐优先使用 ENUM 或 SET,主要适用于以下场景:</p>
<ol>
<li>字符串型枚举;</li>
<li>枚举值已知且有限</li>
</ol>
<p>ENUM 占用 1 Byte,转为数值运算;SET 视节点而定,最多占用 8 Byte。</p>
<p>注:比较时需要加单引号。</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">`sex`</span> <span class="nb">enum</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="s1">'M'</span><span class="p">)</span> <span class="k">COMMENT</span> <span class="s1">'性别'</span><span class="p">,</span>
<span class="nv">`c1`</span> <span class="nb">enum</span><span class="p">(</span><span class="s1">'0'</span><span class="p">,</span><span class="s1">'1'</span><span class="p">,</span><span class="s1">'2'</span><span class="p">,</span><span class="s1">'3'</span><span class="p">)</span> <span class="k">COMMENT</span> <span class="s1">'列'</span>
</code></pre></div></div>
<h4 id="4-避免使用-null-字段">4. 避免使用 NULL 字段</h4>
<p>NULL 字段的弊端:</p>
<ol>
<li>很难进行查询优化;</li>
<li>NULL 列加索引需要额外空间;</li>
<li>含 NULL 复合索引无效;</li>
</ol>
<p>因此,建议在数据库表字段设计的时候尽量加上 <code class="language-plaintext highlighter-rouge">NOT NULL DEFAULT ''</code> 或者<code class="language-plaintext highlighter-rouge">NOT NULL DEFAULT 0</code>。</p>
<h4 id="5-少用并拆分-textblob">5. 少用并拆分 TEXT/BLOB</h4>
<p><code class="language-plaintext highlighter-rouge">TEXT</code>数据不存储在数据库服务器的内存中,因此,每当查询<code class="language-plaintext highlighter-rouge">TEXT</code>数据时,MySQL都必须从磁盘读取它,这与<code class="language-plaintext highlighter-rouge">CHAR</code>和<code class="language-plaintext highlighter-rouge">VARCHAR</code>相比要慢得多。</p>
<p>TEXT 最多可以存储 64KB 数据量,相当于 VARCHAR(65535)。</p>
<p>如果业务必须要用到 TEXT 数据类型,建议将 TEXT 列拆分到单独的表,在该表中只存储 text 列的主键。</p>
<h4 id="6-不在数据库里存图片">6. 不在数据库里存图片</h4>
<p>这不是显而易见吗?图片的大小比其路径大的多得多,保存图片路径即可。</p>
<p>将图片按照固定规则分配到多个目录中去,进行保存和查找。</p>
<h3 id="索引类原则">索引类原则</h3>
<h4 id="1-谨慎添加索引">1. 谨慎添加索引</h4>
<blockquote>
<p>实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。</p>
</blockquote>
<ul>
<li>添加索引会降低更新效率,因为不仅要更新主表、还要保存索引文件;</li>
<li>能不加的索引尽量不加:综合评估数据密度和数据分布,索引数量最好不超过字段数的 20%;</li>
<li>结合核心 sql 有限考虑覆盖索引。</li>
</ul>
<h4 id="2-字符字段必须建前缀索引">2. 字符字段必须建前缀索引</h4>
<ul>
<li>单字母区分度 26</li>
<li>4 字母区分度 = 26^4 = 456,976;</li>
<li>6 字母区分度 = 26^6 = 308,915,776;</li>
</ul>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">`str`</span> <span class="nb">varchar</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span> <span class="k">DEFAULT</span> <span class="k">NULL</span> <span class="k">COMMENT</span> <span class="s1">'string'</span><span class="p">,</span>
<span class="k">KEY</span> <span class="nv">`idx_str`</span> <span class="p">(</span><span class="nv">`str`</span><span class="p">(</span><span class="mi">8</span><span class="p">)),</span>
<span class="p">)</span> <span class="n">ENGINE</span><span class="o">=</span><span class="n">InnoDB</span>
</code></pre></div></div>
<h4 id="3-不在索引列做运算">3. 不在索引列做运算</h4>
<ul>
<li>在索引列上做任何操作,都会导致索引失效;</li>
<li>为了避免出现各种意想不到的问题,一定要保证索引字段的类型和条件中参数的类型一致。</li>
</ul>
<h4 id="4-自增列或全局-id-做-innodb-主键">4. 自增列或全局 ID 做 INNODB 主键</h4>
<ul>
<li>对主键建立聚簇索引;</li>
<li>二级索引存储主键值;</li>
<li>主键不应更新修改;</li>
<li>按自增顺序插入值;</li>
<li>忌用字符串做主键;</li>
<li>聚簇索引分裂;</li>
<li>推荐用独立于业务的 AUTO_INCREMENT 列或全局 id 生成器做代理主键;</li>
<li>若不指定主键,InnoDB 会用唯一且非空索引代替。</li>
</ul>
<h4 id="5-尽量不用外键">5. 尽量不用外键</h4>
<p>外键约束保证了数据主从关系和产生的先后顺序。虽然外键可以节省开发量,但有额外开销:</p>
<ol>
<li>数据库需要维护外键的内部管理;</li>
<li>外键等于把数据的一致性交给数据库实现,但这应该是程序保证的,不要让脚思考;</li>
<li>有外键后,任何增、删、更新操作都需要触发相应操作去检查;</li>
<li>可到达其他表,因此,对其他表内部加锁可能出现死锁情况。</li>
</ol>
<h3 id="sql-类原则">SQL 类原则</h3>
<h4 id="1--尽可能避免使用存储过程触发器函数">1. 尽可能避免使用存储过程/触发器/函数</h4>
<p>mysql 自带了 Store Procedure / Triggers / Function,但他们本身都是一组为了完成特定功能的 SQL 语句集。</p>
<p>这些事情应该交给客户端程序负责。</p>
<h4 id="2-尽量不用-select-">2. 尽量不用 SELECT *</h4>
<p>在写查询语句时,应当尽量不用SELECT * ,只取需要的数据列。</p>
<ul>
<li>相比只查询需要的数据列,select * 会消耗更多的 CPU、内存、IO、网络带宽。</li>
<li>sql 语句更安全,可以一定程度上减少表变化带来的影响;</li>
</ul>
<h4 id="3-将-or-改写为-in">3. 将 OR 改写为 IN()</h4>
<p>OR效率:O(n)</p>
<p>IN效率:O(Log n)</p>
<h4 id="4-将-or-改写为-union">4. 将 OR 改写为 UNION</h4>
<p>不同字段筛选条件时,将 OR 改为 UNION。</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">Select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">opp</span>
<span class="k">WHERE</span> <span class="n">phone</span><span class="o">=</span><span class="s1">'010-88886666'</span>
<span class="k">union</span>
<span class="k">Select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">opp</span>
<span class="k">WHERE</span> <span class="n">cellPhone</span><span class="o">=</span><span class="s1">'13800138000'</span><span class="p">;</span>
</code></pre></div></div>
<h4 id="5-避免负向查询和--前缀的模糊查询">5. 避免负向查询和 % 前缀的模糊查询</h4>
<ul>
<li>NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE等判断可能会造成索引失效;</li>
<li>% 前缀会导致索引失效和全表扫描。</li>
</ul>
<h4 id="6-减少-count">6. 减少 COUNT(*)</h4>
<blockquote>
<p>COUNT(*)对表中行的数目进行计数,不管表列中包含的是空 值(NULL)还是非空值。</p>
<p>COUNT(column) 对特定列中具有值的行进行计数,忽略 NULL值。</p>
</blockquote>
<p>COUNT(*) 开销大,能不用尽量不用。</p>
<h4 id="7-limit-高效分页">7. LIMIT 高效分页</h4>
<pre><code class="language-mysql">SELECT _column,_column FROM _table [WHERE Clause] [LIMIT N][OFFSET M]
</code></pre>
<ul>
<li>limit N: 返回 N 条记录;</li>
<li>offset M:跳过 M 条记录,默认 M=0,单独使用不起作用;</li>
<li>LIMIT N,M == LIMIT M OFFSET N: 从第N条记录开始,返回 M 条记录;</li>
</ul>
<p>N 越大越慢,推荐分页方式:</p>
<pre><code class="language-mysql">SELECT * FROM table WHERE id>=123 LIMIT 11;
</code></pre>
<h4 id="8-用-union-all-而非-union">8. 用 UNION ALL 而非 UNION</h4>
<p>UNION 有去重开销。</p>
<h4 id="9-分解联结保证高并发">9. 分解联结保证高并发</h4>
<p>高并发数据库不建议进行两个表以上的 JOIN 查询,适当分解联结保证高并发。</p>
<h4 id="10-同数据类型的列值比较">10. 同数据类型的列值比较</h4>
<p>数值列与字符类型比较:同时转换为双精度进行对比;</p>
<p>字符列与数值类型比较:字符列整列转数值,不会使用索引查询。</p>
<blockquote>
<p>Strings are automatically converted to numbers and numbers to strings as necessary.</p>
<p>eg. ‘abc’ 转数值是 0,’1abc’转数值是1。</p>
</blockquote>
<h4 id="11-load-data-批量导入数据">11. Load data 批量导入数据</h4>
<p>批量数据用 Load data 命令导入更快,相比单行 insert,不需要每次刷新缓存。</p>
<h4 id="12-打散大批量更新">12. 打散大批量更新</h4>
<ul>
<li>大批量更新尽量凌晨操作,避开高峰;</li>
<li>白天上线默认为 100条/秒;</li>
</ul>
<h4 id="13-know-every-sql">13. Know Every SQL</h4>
<p>作为 DBA 和数据库开发人员,必须对数据库的每条 SQL 都非常了解。</p>
<h3 id="约定类原则">约定类原则</h3>
<h4 id="1-隔离线上线下环境">1. 隔离线上、线下环境</h4>
<p>构建数据库的生态环境,确保不同角色的数据库环境不同。</p>
<h4 id="2-永远不在程序端显式加锁">2. 永远不在程序端显式加锁</h4>
<ul>
<li>外部锁对数据库不可控;</li>
<li>高并发时是灾难;</li>
<li>极难调试和排查;</li>
</ul>
<p>对于类似并发扣款等一致性问题,采用事务处理,提交前进行二次校验冲突。</p>
<h4 id="3-统一字符集为-utf8">3. 统一字符集为 UTF8</h4>
<p>避免乱码</p>
<h4 id="4-统一命名规范">4. 统一命名规范</h4>
<ul>
<li>库、表名称统一用小写;</li>
<li>库名用缩写,长度尽量在 2-7 个字母之间;</li>
<li>避免保留字命名:例如 GROUP、DROP、LIMIT 等。</li>
</ul>
<hr />
<p>References:</p>
<ol>
<li><a href="https://www.yiibai.com/mysql/text.html">MySQL数据库开发的36条原则</a></li>
<li><a href="https://www.yiibai.com/mysql/text.html">MySQL Text 类型</a></li>
<li><a href="https://www.cnblogs.com/xiaomaomao/p/16267857.html">Mysql 索引上做计算为什么会导致索引失效</a></li>
</ol>ingerchao