一、分布式数据库系统
分布式数据库系统
分布式数据库系统:物理上分散而逻辑上集中的数据库系统.
物理上分散:指各站点分散在不同的地方,大可为不同国家,小可为同一建筑物的不同位置。逻辑上集中:指各站点之间不是互不相关的,它们是一个逻辑整体,并由一个统一的分布式数据库管理系统进行管理。
分布式数据库系统 =硬件+软件(OS,Compiler,App.) +DB(全局DB ,局部DB ) +DBMS(全局DBMS ,局部DBMS ) +DBA(全局DBA ,局部DBA ) +用户(全局用户,局部用户)
同构型:如果各个站点上的数据库的数据模型都是同一数据模型的(例如都是关系型)的,则称为同构型分布式数据库系统。
同质型: 如果是同一种DBMS(例如有Oracle,DB2等),则称为同质的,否称为异质的.
分布式数据库系统和分散的数据库系统的区别?
如果用户既可以通过客户机对本地服务器中的数据库执行局部应用,也可以对两个或两个以上结点中的数据库执行全局应用,这样的系统是分布式数据库系统。
不支持全局应用的系统不能称为分布式数据库系统,即只是分散的数据库系统。
分布式的特征
场地自治性(Local Autonomy)非集中式管理(NoReliance On Central Site)
高可靠性(Contiuous Operation) (连续运行)
位置独立性(Location Transparency and Location Independence)
数据分割独立性(Fragmentation Independence)
数据复制独立性(Replication Independence)
分布式查询处理(Distributed Query Processing)
分布式事务管理(Distributed Transaction Management)
硬件独立性(Hardware Independence)
操作系统独立性 (Operating System Independence)
网络独立性(Network Independence)
数据库管理系统独立性(DBMS Independence)
3 数据分片
数据分片(Data Fragmentation),亦称数据分割
------在分布式数据库中,全局数据库是由各个局部数据库逻辑组合而成,反之,各个局部数据库是由全局数据库的某种逻辑分割而得.
逻辑片段:分割后得到的各部分元组,存放在相应的站点上
------数据存放的单位
分片(割)方法:
1 水平分片:按特定条件把全局关系的所有元组,分划成若干个互不相交的子集,每个子集位全局关系的一个逻辑片段。对全局关系施加选择运算.
2 垂直分片:把全局关系的属性集分成若干个子集。对全局关系施加投影运算.
3 混合分片:先水平分片再垂直分片,或先垂直分片再水平分片.
分片原则:
1. 完全性条件:全局关系的每一数据项必须在至少一个分片中2. 重建性条件: 全局关系可从各分片中产生
3. 不相交条件:不同分片无公共数据(控制数据冗余)
位置透明性:全局关系分割为分片后,要把分片定位到各个节点上,使每一分片至少有一个节点地址。如果应用程序中不必包括数据的节点地址,称为系统的位置透明性,应用程序中只提供要访问的关系名或分片名,节点地址由系统从数据字典中查出。具有位置透明性的系统,分片在节点间有移动时只要改变数据字典中的登录数据,不影响应用程序的可用性。
实现位置透明时,数据字典中要有分片的地址信息,系统对数据操纵语句要作多复本处理:修改语句要自动地修改所有复本,查询语句要选择最合适的复本。
全局关系的垂直分割是把属性分组,然后把关系投影到每一组得到各分片。这种方法适用于各节点有自已特殊属性的全局关系。
1 完全性条件:取所有节点的属性为全局关系的属性即满足
2 垂直分割方法的不相交条件和可重建条件是矛盾的
------因为全局关系是各分片的自然联接,可重建条件就是关系分解的无损性条件,即要满足投影联接依赖。例如在分解成两个分片时,只有这两个分片相交,且交集能多值决定任一分片时,全局关系才是可重建的。
解决办法:有的系统中设有系统维护的元组标识,如ORACLE的rowid
(该元组标识可函数决定全局关系中所有属性,且对用户是透明的(可使用而不能修改),因此在这些系统中就用户定义的属性而言可以使垂直分割不相交且可重建,只要把全局关系的元组标识用作各分片的附加属性。)
数据分片的优点是:数据不是按照关系而是按片段来存放,有利于更好地根据用户需求来组织数据的分布,也有利于控制数据的冗余度。
4 数据分布
所谓数据分布是指分布式数据库中的数据不是存储在一个站点的计算机存储设备上,而是根据需要将数据划分成逻辑片断,按某种方法将这些片断分散地存储在各个站点上。
分布透明性包括分片透明性、位置透明性和局部数据模型透明性。
1 分片透明性指用户或应用程序只对全局关系进行操作而不必考虑关系的分片。当分片模式改变了,由于全局模式到分片模式的映象,全局模式不变,应用程序不必改写。
2 位置透明性指用户或应用程序不必了解片段的存储场地,当存储场地改变了,由于分片模式到分布模式的映象,应用程序不必改变。同时,若片段的重复副本数目改变了,数据的冗余度改变了,用户也不必关心如何保持各副本的一致性,这就是重复副本的透明性。
3 局部数据模型透明性指用户或用户程序不必了解局部场地上使用的是哪种数据模型。
为什么会出现上述问题?
因为在分片策略上的问题和数据库系统的问题,设计表时我们就首先对其分片,选择水平或垂直或混合分配策略,然后选择站点存放。所以就出现了上述现象。不过根据系统字典这种现象应该可以解决。在设计时我们就建立对应的表。这样程序员使用表时可以建立最高的分布透明性。
------------------------------------
二、分布式数据库系统的设计
1 数据库设计
数据库设计的基本步骤:需求分析
概念结构设计
逻辑结构设计
物理结构设计
数据库的建立和测试
数据库运行和维护。
2 命名规范
不使用tab或tbl作为表前缀(本来就是一个表,为什么还要说明)表名以代表表内的内容的一个和多个名词组成,以下划线分隔,每个名词的第一个字母大写。
使用表的内容分类作为表名的前缀:如,与用户信息相关的表使用前缀User_,与内容相关的信息使用前缀Content_。
表的前缀以后,是表的具体内容的描述。如:用户登录信息的表名为:User_Login,用户在论坛中的信息的表名为:User_BBS_Info
一些作为多对多连接的表,可以使用两个表的前缀作为表名:
如:用户登录表User_Login,用户分组表Group_Info,这两个表建立多对多关系的表名为:User_Group_Relation
当系统中有一些少量的,重复出现的值时,使用字典表来节约存储空间和优化查询。如地区、系统中用户类型的代号等。这类值不会在程序的运行期变化,但是需要存储在数据库中。
字段不使用任何前缀(表名代表了一个名称空间,字段前面再加前缀显得罗嗦)
字典名也避免采用过于普遍过于简单的名称:例如,用户表中,用户名的字段为UserName比Name更好。
布尔型的字段,以一些助动词开头,更加直接生动:如,用户是否有留言HasMessage,用户是否通过检查IsChecked等。
字段名为英文短语、形容词+名词或助动词+动词时态的形式表示,大小写混合,遵循“见名知意”的原则。
3 SQL语句规范
在一些块形式的SQL语句中,就算只有一行代码,也要加上BEGIN…END块。如:IF EXISTS(…)
SET @nVar = 100
应该写成:
IF EXISTS(…)
BEGIN
SET @nVar = 100
END
所有的SQL关键字大写
4 存储过程编码规范
只允许应用程序通过存储过程访问数据库将主要的业务逻辑封装在存储过程中,能够避免在应用程序层写大量的代码(在应用程序中通过字符串插入太长的SQL语句影响效率,而且维护困难)
在网站一类的应用系统中,SQL注入式漏洞一直是难以完全杜绝的漏洞。如果只通过存储过程来访问数据库,能够大大减少这类安全性问题。
需求变更,表的结构必须要改变。使用存储过程,只要参数不变,我们就只需要修改相应的存储过程,而不需要修改应用程序的代码。
为提高效率,使部分字段冗余;为提高效率,使用冗余表(拆分表);
使用存储过程,便于在项目后期或者运行中集中优化系统性能。
问题一:存储过程编译后,将作为数据库的全局对象保存,太多的存储过程将占用大量的数据库服务器的内存。
问题二:在存储过程中实现大量的逻辑,将使大量的运算在数据库服务器上完成,而不是在应用服务器上完成。当访问量很大的时候,会大大消耗数据库服务器的CPU占用率。
每个存储过程内的代码前后必须加上SET NOCOUNT ON 和SET NOCOUNT OFF。
5 数据库设计规范
5.1 数据完整性规范(编码期)
1、为便于在程序的编码期查错,可以在设计数据库的时候尽可能多的加上约束(check)。如,整型的字段的取值范围等,常常为field>0。
2、同理,尽可能地在开发期间使用触发器来验证数据的完整性。
3、如果字段之间存在冗余,应该编写触发器来管理冗余的字段
3、在开发阶段保存完整的主键、外键和唯一索引的约束。
4、原则:编码期间,数据完整性优先于性能。在保障系统正确运行的前提下尽可能的提高效率。
6 数据库优化
6.1 数据库性能优化规范
1、在运行阶段删除不必要的约束(check)。
2、尽量不要使用触发器
3、尽量保留主键约束
4、适当删除外键,以提高性能
5、在运行期间,通过分析系统的访问量,创建索引来优化性能
6、分析每个表可能的数据增长量,定义自动拆分表规则。将大表进行拆分来提高性能。
7、预先考虑数据清理规则:在什么情况下删除数据库中的旧数据,以此来提高性能。
8、制定数据库备份和灾难恢复计划。
9、为效率考虑,可以在系统测试阶段适当增加冗余字段,或者冗余表。
10、分页的记录输出必须通过存储过程来实现,不能使用API游标来分页,这样可以提高分页的效率。
6.2 拆分表示例
案例:网站有200万用户,有很多模块围绕用户提供服务。
为提高效率,每个表最多只保存与用户有关的10万记录,200万条记录拆分到20个表中。编号为1-10万的用户将记录保存到表一,100001-200000编号的记录保存到表二,以此类推。
建立一个拆分信息表,表中保存了哪些表是经过拆分的,拆分到什么程度,拆分规则是什么。
当插入记录的时候,首先判断插入这条记录的用户的ID。存储过程根据ID的范围,自动把表插入到相应的拆分表中去。
当按照条件查询,存储过程自动连接所有的拆分表,丛中筛选出记录。(一般情况下:同类型的查询远远大于按照条件的全体查询)
6.3 冗余字段建立示例
案例:留言本表中,要保存用户的ID作为外键。通常,通过连接留言表和用户表来得知是哪个用户发布了留言。
为提高效率,在留言本表中增建用户名的字段。插入记录的时候,同时保存用户ID和用户名。这样,当查询时,就不必连接两个表,使效率大大提高。
但是,当用户修改用户名时,要吗更新其他表中的用户名,要吗忽略这种用户名不一致的影响。如何处理取决于用户名在模块中的重要程度。
6.4 冗余表建立示例
案例:有用户表和分组表,两个表之间是多对多的关系,建立一个用户与组的关系表来实现这种关系。
用户表中有百万条记录,组表中几千条记录。如果每个用户都属于多个组的化,关联表中将存在几百万条记录。
现在将用户表和关联表进行拆分,拆分规则为用户的ID范围。当查询某用户的组时,效率大大提高。但是当查询某组下的用户时,需要关联所有的拆分表,效率很低。
为提高效率,建立一个冗余的用户和组的关系表,这个关系表中保存第一个关系表中统一的内容,但是拆分规则为组ID的范围。这样,当查询组中的用户时,丛第二个关系表中查询,效率大大提高。
6.5 存储过程中分页方案
方案一:
1、首先统计得到符合条件的记录数2、定义表变量:表变量的第一个字段为自增长类型,第二个字段为记录集中的唯一值字段(一般是主键)
3、使用insert () select 语句将符合条件的记录的唯一值字段保存在表变量中。
4、使用where ID in (select ID From 表变量 WHERE ……) 的方法从表两边中读出需要的唯一值字段。
方案二:
1、首先统计符合条件的记录数,并根据页大小计算页数2、如果读取第一页,直接使用TOP子句读取
3、如果页数在前一半:
结果集1:SELECT TOP CurPage*PageSize Fields FROM Table ORDER BY ID ASC
结果集2:SELECT TOP PageSize * FROM (结果集1) ORDER BY ID DESC
最终结果:SELECT * FROM (结果集2) ORDER BY ID ASC
4、如果页数在后一半:
结果集1:SELECT TOP (PageCount-CurPage)*PageSize Fields FROM Table ORDER BY ID DESC
最终结果:SELECT TOP PageSize * FROM Table ORDER BY ID ASC
声明:
博客转载地址:blog.csdn.net/longronglin/article/details/5469463.来源:CSDN
作者:辛修灿
链接:https://blog.csdn.net/u012743772/article/details/51209944