zoukankan      html  css  js  c++  java
  • 数据库结构的优化有多种方法

    1.建立索引

    2.使用储存过程 ,减少sql语句解析编译的过程

    3.使用数据库分区 减少查询量

    4.水平垂直拆分 垂直 是业务一般业务拆分, 水平 一般是数量拆分

    5.oralce物化视图  相当于中间表

     
    数据库 分区的好处:
    1) 增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
    2) 维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
    3) 均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能;
    4) 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
     
    水平表分区和垂直表分区。
     水平分区:目的是将一个表分为多个表。每个表包含的列数(表字段)都是相同的,但是记录数(数据行)会减少。比如,我们可以将一个包含1亿行记录的数据库表,按照水平分区的方式,分成12个小表,每个小表分别表示这一年份内从1月到12月的数据。这样,任何需要查询特定月份数据的查询只需查询相应月份的表,而避免从存储在1个大表中的所有月份的数据进行查询。根据SQL语句的执行效率,毫无疑问,从小表中的查询效率会远远高于从大表中查询的效率。
    垂直分区:该方式则与水平分区方式相反,从纵向进行分区,是将一个原始表分成多个只包含较少列的表。在日常的应用中,水平分区可以说是最常用的分区方式。
     
    1、Partition 技术介绍
    ORACLE的分区是一种处理超大型表、索引等的技术。通过将大表和索引按照分区规则分成可以管理的若干小块,从而避免了对每个表作为一个大的、单独的对象进行管理,为大量数据提供了可伸缩的性能。分区通过将操作分配给更小的存储单元,减少了需要进行管理操作的时间,并通过增强的并行处理提高了性能,通过屏蔽故障数据的分区,还增加了可用性。
    2、数据库分区设计优化方案
    2.1确定哪些大表需要进行分区:
     
    使用分区技术时,并不是对数据库中的所有表都进行分区,而只针对数据量比较大的一些大表才进行分区。根据分区的定义可知:分区其实就是将一个大数据段按规则划分成若干个小数据段,如果表对象本身很小,就失去了分区的意义。根据经验,数据量大于1000万的表才需要做分区。
     
    2.2讨论分区类型及分区字段的选择:
    这一步至关重要,分区类型和分区字段的选择严重影响到数据表的访问性能。选择了错误的分区类型或分区字段给数据库性能带来的负面影响会比不做分区更大,因此在决定分区类型和分区字段时一定要与项目组讨论,按照业务需求及业务逻辑共同制定。
    根据经验,选择分区类型的步骤:
    1)先确定该表中哪个字段在select语句的谓词中使用最频繁,此字段将做为分区字段。
    因为分区的目的是将一个大表的数据段按规则分离成若干个小数据段,索引也分离为若干小索引段,在数据访问时,根据索引只需要访问其中的一个小索引段,最后访问其中的一个数据段,从而减小了需要访问的数据量,达到优化的目的。如果select语句的谓词中不包括分区字段,则必须访问完整个索引段,最后访问所有的小数据段,才能定位出需要访问的数据。
    2)根据分区字段的特点,确定分区类型。
    如果该字段有明确的顺序先后关系,则该表合适做范围分区。如:时间,如果该字段没有明确的范围顺序关系,则是具有唯一值或若干值,则该表合适做列表分区。如:部门、分公司,如果该字段既无明确的范围顺序关系,也无具体值,而是些流水号,则该表合适做散列分区。如:批处理号、流水号。
    2.3数据表空间及索引表空间设计
    表对象和索引对象的第一个规则是把表和索引分离。把表和相应的索引建立在不同的表空间中,最好在不同的磁盘上。这样可以避免在数据管理和查询时出现的许多I/O冲突。
    在此优化方案中,我们将为每个分区创建一个对应的表空间,让表分区存放在不同的表空间中,达到不同分区间数据访问的分离。同时为每个索引分区也创建独立的索引分区表空间。
     
     
    读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
    为什么要分库、分表、读写分?
    单表的数据量限制,当单表数据量到一定条数之后数据库性能会显著下降。数据多了之后,对数据库的读、写就会很多。分库减少单台数据库的压力。接触过几个分库分表的系统,都是通过主键进行散列分裤分表的。这类数据比较特殊,主键就是唯一的获取该条信息的主要途径。比如:京东的订单、财付通的交易记录等。。。该类数据的用法,就是通过订单号、交易号来查询该笔订单、交易。
    还有一类数据,比如用户信息,每个用户都有系统内部的一个userid,与userid对应的还有用户看到的登录名。那么如果分库分表的时候单纯通过userid进行散列分库,那么根据登录名来获取用户的信息,就无法知道该用户处于哪个数据库中。
    或许有朋友会说,我们可以维护一个email----userid的映射关系,根据email先查询到userid,在根据userid的分库分表规则到对应库的对应表来获取用户的记录信息。这么做是可以的,但是这个映射关系的条数本身也是个瓶颈,原则上是没有减少单表内数据的条数,算是一个单点。并且要维护这个映射关系和用户信息的一致性(修改登录名、多登录名等其他特殊需求),最大一个原因,其实用户信息是一个读大于写的库,web2.0都是以用户为中心,所有信息都和用户信息相关联,所以对用户信息拆分还是有一定局限性的。
    对于这类读大于写并且数据量增加不是很明显的数据库,推荐采用读写分离+缓存的模式,试想一下一个用户注册、修改用户信息、记录用户登录时间、记录用户登录IP、修改登录密码,这些是写操作。但是以上这些操作次数都是很小的,所以整个数据库的写压力是很小的。唯一一个比较大的就是记录用户登录时间、记录用户登录IP这类信息,只要把这些经常变动的信息排除在外,那么写操作可以忽略不计。所以读写分离首要解决的就是经常变化的数据的拆分,比如:用户登录时间、记录用户登录IP。这类信息可以单独独立出来,记录在持久化类的缓存中(可靠性要求并不高,登陆时间、IP丢了就丢了,下次来了就又来了)
    以oracle为例,主库负责写数据、读数据。读库仅负责读数据。每次有写库操作,同步更新cache,每次读取先读cache在读DB。写库就一个,读库可以有多个,采用dataguard来负责主库和多个读库的数据同步。
     
     
  • 相关阅读:
    python命令行传参详解,optparse模块OptionParse类的学习
    设计模式之共享模式
    用flask搭建一个测试数据生成器(v1.1)
    用flask搭建一个测试数据生成器(v1.0)
    jmeter中使用beanshell断言
    jmeter中beanshell脚本的使用
    从上帝视角看OS进程调度
    Linux网络内部原理系列
    从文件read/write一个字节的过程和所发生的磁盘IO
    深入理解系统中断(INTERUPT)
  • 原文地址:https://www.cnblogs.com/bug1024/p/11393121.html
Copyright © 2011-2022 走看看