Oracle 架构篇+应用设计原理

说明:本文为面向Oracle数据库应用设计原理初学者的指导手册
标签:数据库架构、架构设计、Oracle优化、架构师
用途:帮助你设计出更加高效和可靠的数据库应用架构
易学:文中删去了不需要的多余部分,让初学者一目了然一学就会
温馨提示:如果您发现本文哪里写的有问题或者有更好的写法请留言或私信我进行修改优化


★ 相关文档
Oracle官方文档(21c)


应用设计原理

应用程序设计简单

应用程序与任何其他设计和制造的产品没有什么不同。设计良好的结构,计算机和工具通常可靠,易于使用和维护且概念简单。用最笼统的术语来说,如果设计看起来正确,则可能是正确的。构建应用程序时应始终牢记这一原则。

请考虑以下设计问题:

  • 如果表格设计过于复杂,以至于没人能完全理解它,那么表格的设计可能就很糟糕。

  • 如果SQL语句太长且涉及太多,以至于任何优化程序都不可能实时有效地对其进行优化,则可能存在错误的语句,基础事务或表设计。

  • 如果表上有索引,并且相同的列被重复索引,则可能是不良的索引设计。

  • 如果提交的查询没有在线用户快速响应的适当资格,则可能是用户界面或交易设计不佳。

  • 如果通过多层软件从应用程序逻辑中抽象出对数据库的调用,则可能是一种不良的软件开发方法。

资料建模

数据建模对于成功的关系应用程序设计很重要。您必须以快速表示业务实践的方式执行此建模。关于正确的数据模型可能会引起激烈的争论。重要的是将最大的建模工作应用于那些受最频繁的业务交易影响的实体。在建模阶段,人们非常愿意花太多时间对非核心数据元素进行建模,这会导致开发交付时间增加。然后,使用建模工具可以快速生成模式定义,并且在需要快速原型时很有用。

表和索引设计

表设计在很大程度上是灵活性和核心事务性能之间的折衷。为了保持数据库的灵活性并能够容纳不可预见的工作负载,表设计应与数据模型非常相似,并且应规范化为至少第三范式。但是,出于性能目的,用户所需的某些核心事务可能需要选择性地进行非规范化。

此技术的示例包括存储预先连接的表,添加派生列和聚合值。Oracle数据库通过集群和实例化视图功能提供了多种存储聚合和预联接数据的选项。这些功能使最初可以采用更简单的表设计。

同样,应将重点和资源用于关键业务表,以便获得最佳性能。对于非关键表,可以采用设计中的快捷方式来实现更快的应用程序开发。但是,如果原型设计和测试非核心表成为性能问题,则应立即采取补救性设计工作。

基于应用程序设计人员生成的SQL,索引设计在很大程度上也是一个迭代过程。但是,可以通过建立强制执行主键约束的索引和基于已知访问模式(例如人名)的索引来明智地开始。随着应用程序的发展以及对实际数据量的测试,您可能需要通过构建更好的索引来提高特定查询的性能。构建新索引时,请考虑以下索引设计思想列表:

将列追加到索引或使用索引组织的表

加快查询速度的最简单方法之一是通过从执行计划中消除对表的访问来减少逻辑I / O的数量。这可以通过将查询引用的所有列附加到索引来完成。这些列是选择列表列,以及任何必需的联接或排序列。当减少耗时的I / O时,此技术对于加快联机应用程序的响应时间特别有用。首次使用适当大小的数据测试应用程序时,最好使用此方法。

该技术最激进的形式是建立索引组织表(IOT)。但是,您必须注意,增加IOT的叶子大小不会损害减少I / O的努力。

使用其他索引类型

有几种可用的索引类型,每种索引在某些情况下都有好处。下表列出了与每种索引类型相关的性能思想。

B树索引

这些索引是标准索引类型,非常适合主键索引和高度选择的索引。用作串联索引,数据库可以使用B树索引来检索按索引列排序的数据。

位图索引

这些索引适用于具有相对较少数量的不同值的列,在这些列中添加B树索引的好处可能会受到限制。这些索引适用于DML活动低和临时过滤模式的数据仓库应用程序。在列合并位图索引实现高效ANDOR用最少的I / O操作。此外,通过压缩技术,它们可以使用最少的I / O生成大量的rowid。位图索引在使用进行查询时特别有效COUNT(),因为可以在索引中满足查询要求。

基于功能的索引

这些索引允许通过B树访问从基础数据中的函数派生的值。基于函数的索引在使用null方面有一些限制,它们要求您启用查询优化器。

当查询复合列以产生派生结果或克服数据在数据库中存储方式的限制时,基于函数的索引特别有用。一个示例是查询订单项中某个订单项是否超过某个特定值,这些订单项是从(销售价格-折扣)x数量(表中的列)得出的。另一个示例是将UPPER功能应用于数据以允许不区分大小写的搜索。

分区索引

对全局索引进行分区允许在索引访问中进行分区修剪,从而减少了I / O。通过定义良好的范围或列表分区,正确索引分区的快速索引扫描可以导致非常快的查询时间。

反向键索引

这些索引旨在消除插入应用程序上的索引热点。这些索引具有出色的插入性能,但由于数据库无法将其用于索引范围扫描而受到限制。

寻找指数成本

建立和维护索引结构可能会很昂贵,并且会消耗磁盘空间,CPU和I / O容量等资源。设计人员必须确保任何索引的好处都超过索引维护的负面影响。

使用这个简单的估算指南索引维护成本:每个索引维护通过INSERTDELETEUPDATE索引键大约需要三倍的资源作为餐桌上的实际的DML操作。因此,如果您INSERT将数据插入具有三个索引的表中,则插入速度大约比INSERT没有索引的表中的插入慢10倍。对于DML,尤其是对于INSERT繁重的应用程序,应认真审查索引设计,这可能需要在查询和INSERT性能之间进行折衷。

也可以看看:

《 Oracle数据库管理员指南》以了解如何监视索引使用情况

索引内的序列化

使用序列或时间戳来生成自己索引的键值可能会导致数据库热点问题,从而影响响应时间和吞吐量。这通常是单调增长的键导致索引正确增长的结果。为避免此问题,请尝试生成在整个索引范围内插入的键,以使工作负载更具可伸缩性。您可以使用以下任何一种方法来实现:

  • 使用反向键索引

  • 使用哈希分区索引

  • 使用循环序列为序列值添加前缀

  • 使用可伸缩序列

也可以看看:

《 Oracle数据库管理员指南》中有关可伸缩序列的更多信息

索引中的排序列

设计人员在定义任何索引建立规则时应该保持灵活。根据您的情况,使用以下两种方法之一对索引中的键进行排序:

  • 订单列最多 选择性第一。该方法是最常用的方法,因为它以最少的I / O提供了最快的访问权限,从而使所需的实际rowid最少。该技术主要用于主键和非常有选择性的范围扫描。

  • 对列进行排序,以通过对数据进行聚类或排序来减少I / O。在大范围扫描中,通常可以通过以最小选择性的顺序对列进行排序或以应检索数据的方式对数据进行排序的方式来减少I / O。

使用视图

视图可以加快和简化应用程序设计。简单的视图定义可以掩盖程序员的数据模型复杂性,这些程序员的首要任务是检索,显示,收集和存储数据。

但是,尽管视图提供了干净的编程接口,但它们可能导致次优的资源密集型查询。视图使用的最差类型是视图引用其他视图,以及将它们合并到查询中时。在许多情况下,开发人员可以直接从表中满足查询,而无需使用视图。通常,由于其固有的属性,视图使优化器难以生成最佳执行计划。

SQL执行效率

在任何系统开发的设计和体系结构阶段,应注意确保应用程序开发人员了解SQL执行效率。为了实现此目标,开发环境必须支持以下特征:

  • 良好的数据库连接管理

    连接到数据库是一项昂贵的操作,高度不可扩展。因此,应尽可能减少与数据库的并发连接数。用户在应用程序初始化时进行连接的简单系统是理想的。但是,在基于Web的或多层的应用程序中,使用应用程序服务器将数据库连接复用到用户,这可能很困难。对于这些类型的应用程序,设计工作应确保池化数据库连接,并且不会针对每个用户请求重新建立数据库连接。

  • 良好的光标使用和管理

    维护用户连接对于最小化系统上的解析活动同样重要。解析是解释SQL语​​句并为其创建执行计划的过程。此过程分为多个阶段,包括语法检查,安全检查,执行计划生成以及将共享结构加载到共享池中。有两种类型的解析操作:

    • 硬解析

      第一次提交SQL语句,但在共享池中找不到匹配项。硬解析是最耗费资源且不可扩展的,因为硬解析执行了解析中涉及的所有操作。

    • 软解析

      一个SQL语句提交给第一次,比赛发现在共享池中。匹配可以是另一个用户先前执行的结果。SQL语句是共享的,这对性能有好处。但是,软解析不是理想的,因为它们仍然需要语法和安全性检查,这会消耗系统资源。

    由于应尽可能减少解析,因此应用程序开发人员应设计其应用程序以解析SQL语句一次并执行多次。这是通过游标完成的。有经验的SQL程序员应该熟悉打开和重新执行游标的概念。

    应用程序开发人员还必须确保在共享池中共享SQL语句。为了实现此目标,请使用绑定变量来表示查询在执行之间变化的部分。如果不这样做,则该SQL语句很可能仅被解析一次,而不会被其他用户重复使用。为确保共享SQL,请使用绑定变量,并且不要在SQL语句中使用字符串文字。

实施应用程序

开发环境和编程语言的选择很大程度上取决于开发团队中可用的技能以及在指定应用程序时所做出的体系结构决策。但是,有一些简单的性能管理规则可以导致可伸缩的高性能应用程序。

  1. 选择适合软件组件的开发环境,不要让它限制您的设计以决定性能。如果是这样,则您可能选择了错误的语言或环境。

    • 用户界面

      编程模型可以在HTML生成和直接调用窗口系统之间变化。开发方法应专注于用户界面代码的响应时间。如果通过网络发送HTML或Java,请尝试最小化网络量和交互。

    • 商业逻辑

      解释性语言(例如Java和PL / SQL)是对业务逻辑进行编码的理想选择。它们是完全可移植的,这使得升级逻辑相对容易。两种语言在语法上都很丰富,以允许易于阅读和解释的代码。如果业务逻辑需要复杂的数学函数,则可能需要编译的二进制语言。业务逻辑代码可以位于客户端计算机,应用程序服务器和数据库服务器上。但是,应用程序服务器是业务逻辑的最常见位置。

    • 用户请求和资源分配

      其中大多数不受编程语言的影响,但是掩盖数据库连接和光标管理的工具和第四代语言可能使用效率低下的机制。在评估这些工具和环境时,请检查它们的数据库连接模型以及它们对游标和绑定变量的使用。

    • 数据管理与交易

      其中大多数不受编程语言的影响。

  2. 在实现软件组件时,请实现其功能,而不要实现与其他组件关联的功能。实现另一个组件的功能会导致次优的设计和实现。这适用于所有组件。

  3. 不要在功能上留下空白,也不要在设计,实施或测试中对软件组件进行任何研究。在许多情况下,直到应用程序以实际量推出或测试后才发现差距。这通常表示体系结构不佳或初始系统规格不佳。在初始系统设计,构建和实施过程中,经常会忽略数据存档和清除模块。

  4. 在实现过程逻辑时,请以过程语言(例如C,Java或PL / SQL)实现。实施数据访问(查询)或数据更改(DML)时,请使用SQL。此规则特定于代码的业务逻辑模块,其中过程代码与数据访问(非过程SQL)代码混合在一起。将过程逻辑放入SQL访问存在很大的诱惑。这往往会导致占用大量资源的不良SQL。带有DECODEcase语句的SQL语句通常是优化的候选对象,带有大量OR谓词或set运算符(例如UNION和)的语句也经常是优化对象MINUS

  5. 缓存经常访问的,很少更改的数据,这些数据重复获取的代价很高。但是,使此缓存机制易于使用,并确保它确实比访问原始方法中的数据便宜。这适用于所有模块,在这些模块中,应将经常使用的数据值缓存或本地存储,而不是从远程或昂贵的数据存储中反复检索。

    本地缓存候选者的最常见示例包括:

    • 今天的日期。SELECT SYSDATE FROM DUAL可以占数据库工作量的60%以上。

    • 当前的用户名。

    • 重复的应用程序变量和常量,例如税率,折现率或位置信息。

    • 本地缓存数据可以进一步扩展为在应用服务器中间层中构建本地数据缓存。这有助于减轻中央数据库服务器的负担。但是,在构造本地缓存时应格外小心,以免它们变得过于复杂而不会停止提高性能。

    • 本地序列生成。

    应该考虑使用缓存的设计含义。例如,如果用户在午夜连接并且缓存了日期,则该用户的日期值将变为无效。

  6. 优化组件之间的接口,并确保所有组件都在可扩展性最高的配置中使用。该规则需要最少的解释,并适用于所有模块及其接口。

  7. 使用外键引用。通过应用程序强制执行引用完整性非常昂贵。您可以通过从父级中选择子级的列值并确保其存在来维护外键引用。Oracle提供的不使用SQL的外键约束实施速度快,易于声明并且不会创建网络流量。

  8. 考虑在应用程序中设置操作和模块名称以用于 端到端应用程序跟踪。这在跟踪工作负载问题时提供了更大的灵活性。

应用程序开发趋势

当今应用程序开发中的两个最大挑战是,越来越多地使用Java来代替已编译的C或C ++应用程序,以及越来越多地使用面向对象的技术,从而影响了模式设计。

Java为程序员提供了更好的代码可移植性和可用性。但是,与Java有关的性能有几个方面。因为Java是一种解释型语言,所以它执行类似逻辑的速度比诸如C之类的编译语言要慢。结果,客户端计算机的资源使用量增加了。这需要在客户端或中间层计算机中应用功能更强大的CPU,并需要程序员更加谨慎地产生高效的代码。

因为Java是一种面向对象的语言,所以它鼓励将数据访问隔离到不执行业务逻辑的类中。结果,程序员可能在不知道所使用的数据访问方法的效率的情况下调用方法。这往往导致最少的数据库访问,并使用最简单和最原始的数据库接口。

使用这种类型的软件设计,查询并不总是包含所有有效的WHERE谓词,而是在Java程序中执行行过滤。这是非常低效的。另外,对于DML操作(尤其是对于INSERTs),INSERT将执行单个s,从而无法使用数组接口。在某些情况下,过程调用会使效率降低。与实际的数据库调用相比,将更多的资源用于将数据移入和移出数据库。

通常,最好将数据访问调用放在业务逻辑旁边,以实现最佳的总体事务设计。

在编程级别接受面向对象已导致在Oracle Server中创建面向对象的数据库。从在BLOBs中存储对象结构到仅将数据库有效地用作索引卡文件,再到使用Oracle数据库对象关系功能,这已经以多种方式体现出来。

如果您采用面向对象的方法进行架构设计,请确保您不会失去关系存储模型的灵活性。在许多情况下,面向对象的方案设计方法最终会导致严重的非规范化数据结构,这需要大量维护和REF与对象关联的指针。通常,这些设计代表了被关系存储方法取代的分层和网络数据库设计的后退。

总之,如果您将数据长期存储在数据库中,并且如果您期望在同一模式下进行一定程度的即席查询或应用程序开发,则关系存储方法可能会提供最佳性能和灵活性。


※ 如果您觉得文章写的还不错, 别忘了在文末给作者点个赞哦 ~

over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值