原创作者:Mick Xu 甲骨文大学原厂首席讲师
( 我爱 oracle 技术学习 )
众所周知,目前最优秀的2款关系型数据库软件分别是甲骨文公司的Oracle Database产品和Mysql Server产品,Oracle 数据库做为全球第一的关系型数据库产品,在商业市场上取得了巨大的成功! 我们将从几个方面对比一下这2款产品的差异,以帮助数据库运维工程师更好的驾驭这两个产品。 首先,从物理文件结构上去认识的话,两者都属于大型的关系型数据库服务器软件,关系通常是指代的二维表格,所以两者都是二维表格管理系统, Oracle 数据库主要有三种核心文件类型,分别是控制文件,数据文件,和联机重做日志文件,控制文件里包含的是数据文件路径和名称,联机重做日志文件路径和名称,以及数据库状态信息,oracle 系统表,我们有时也称为数据字典表,是存放在system表空间的数据文件里,而应用程序的表是存放在用户永久性表空间的数据文件里,联机重做日志文件记录了对数据文件和控制文件的修改,在mysql 服务器环境里,通常我们创建了一个数据库,是仅仅创建了一个文件夹, e.g. create database hrdb; 参考图1:
在@@datadir参数或数据目录变量的路径下建立了一个文件夹,里面通常会包含一个db.opt的文件指明该数据库的字符集,8.0.x版本可以没有该文件,将使用缺省的utf8mb4字符集。 use hrdb; 打开数据库,在数据库里创建的表将根据不同存储引擎的类型,创建的表将产生不同的文件名,以myisam引擎的表为例子,将产生3个文件, t1.frm(表结构文件),对于8.0以上版本,表定义文件为t1_xxx.sdi,表的数据存放在t1.MYD(表数据文件), 索引存放在 t1.MYI(表索引文件), 参考图2:
如果是innodb存储引擎的表,每张表通常会产生两个文件, t2.frm(表结构文件),在mysql 8.0以上版本,一个重要的新特性就是mysql系统数据库里的字典表(也可以称为系统表) 由myisam引擎转为innodb存储引擎实现,从而对元数据(metadata)的操作也将保持事务的一致性,这对金融级的核心业务系统很有必要,接下来是表空间的数据文件 t2.ibd(表空间数据文件), 参考图3:
而在oracle数据库里,我们的表将存放在用户永久性表空间里,一个表空间可以有多个数据文件,有点类似于mysql 5.7版本里的通用表空间, 一个数据文件可以有多个表对象的数据,所以,磁盘上该表空间可能只有一个数据文件,里面可以包含多个表和索引对象,在oracle数据库里,推荐每个应用程序两个表空间,一个存放表对象,一个存放索引对象,这样即利于维护,也有利于I/O性能, Oracle的一些源代码对象,通常存放在系统表空间的字典表里,比如视图,存储过程,触发器,包声明和包体等源码对象,也就是在系统表空间的数据文件上, 参考图4:
对于Oracle服务器辅助文件,比如参数文件,有spfilesid.ora 二进制服务器参数文件和initsid.ora文本格式参数文件,主要使用二进制服务器参数文件为主,而mysql只有文本格式参数文件, 通常称为 my.cnf ,mysql 8.0 可以持久化修改参数,但和Oracle 服务器参数文件实现机制不一样,它是通过把修改的参数放在数据目录下的 mysqld-auto.cnf 文件里,单独保存修改的参数。
接下来,我们比较一下两种数据库管理系统里不同种类的表,以及表实现结构和对事务的支持,所谓的事务,通常是指一组DML sql 语句的集合,它们要么全部执行成功,要么全部撤销。对于一些基于 nosql技术实现的数据库技术,对事务的强一致性支持,就远远不如关系型数据库支持的成熟, 在oracle 数据库里,几乎所有类型的表都支持事务,最常用的标准表通常是堆结构实现的,堆(heap)表的特点通常是指大量的行,但在存储时,行并没有按照一定的顺序存储,所以堆表(你也可以认为是oracle 的标准表) 有物理行号,我们称它为rowid, 逻辑上,我们以一个数据段的形式来管理它,还有索引组织表,我们叫IOT表,表面上虽然是表对象,但底层的存储确是一个索引段,它是按照主键的顺序存放行记录数据,当堆表非常大的时候,比如行数超过一定数量,具体取决于机器的配置,我们将采用分区表,分区表在存储时,也是数据段,类似于堆表,还有一种类型的表叫簇表(cluster table), 特别适合更新比较少,经常要进行大量表连接的场景,比如有7张不太更新的表,要进行关联查询,用簇表结构实现就比较合适,我们经常使用的数据字典视图,底层的来源就是簇表结构实现的,这里不管是什么类型的表,在oracle 数据库里缺省都提供对事务的支持,然而在mysql数据库里,我们可以根据应用的需要,在表级别通过选择不同的存储引擎,来决定是否需要提供对事务的支持,比如: myisam, memory存储引擎的表就不提供对事务的支持,innodb存储引擎的表支持事务,Mysql这样的实现比较灵活,对不需要事务支持的表,通过选择myisam或memory等存储引擎的表,从而减少不必要的事务维护开销,当然,这些引擎的表不适合金融级别的交易数据库业务场景!在mysql 服务器环境里, innodb对事务支持的最好,它也是对金融级业务支持最好的存储引擎。 参考图5:
innodb存储引擎非常类似于oracle风格,有undo(rollback segment)和redo 保护机制,保证事务的强一致性,mysql 8.0中对mysql 5.7的一个重大改进就是对mysql系统数据库的表,由以前的myisam存储引擎实现转为innodb实现,这样无论是对应用生产数据的修改,还是对系统表元数据(关于数据的数据)的修改都将保证事务的强一致性,成功提交的数据不会丢失(联机日志文件损坏除外),没有提交的修改会被取消!
最后,我们对比一下oracle数据库和mysql 数据库里 schema模式和用户账号的区别,在oracle里,通常创建一个用户账号就创建了一个同名的模式,用户名和模式名是一对一的关系,在oracle里,所有的对象几乎都要存放在一个用户模式下,所以Oracle里模式的定义为:和用户账号同名,并且只有一个,该用户下对象的集合,简单的说就是对象的集合,比如:表,索引,视图,同义词,序列,存储过程,触发器,包声明和包体等对象。例如sys用户建立的会话,要访问hr模式下的对象,应该写成: select * from hr.employees; hr 说成是用户名也可以,准确的说应该是HR的模式名,只不过正好和用户名同名。 参考图6:
在mysql数据库服务器环境,oracle 里的schema 等价于 mysql 里的database, 在mysql服务器下,所有的对象通常要放在一个database里,同样也是代表对象的集合,两种数据库环境对用户账号的管理差别很大,Oracle里面通常我们只需要建立用户名即可, 比如: create user userdemo1 identified by oracle default tablespace users quota 100m on users; 而在mysql里,我们建立的是用户账号( account ), 它是由 ‘用户名’@'客户端主机名 ’ 两部分组成,在有相应的权限下,用户账号可以用来登录mysql服务器,通常这样虽然麻烦,但限定了登录的客户机,相对更加安全,而要在oracle 里实现这个特点,通常要在oracle 网络概要文件(sqlnet.ora)里适当设置,可以实现类似效果。两者在用户权限管理上也有很多差异,oracle里非常严谨,权限分配不允许用通配符,如有大量权限分配,可以用数据字典查询技巧生成重复赋权脚本,而mysql里可以直接使用通配符分配权限,比较灵活!此外,在oracle 删除用户时,即删除了用户账号,也删除了同名模式(schema), 以及这个模式里的全部对象, 这一点和mysql 有非常显著的不同,在mysql里,删除模式( shema ),就是删除数据库,drop database mydb; 数据库里的对象将全部删除,而不删除用户,因为 mysql里用户账号和database(shema)是分开的,所以mysql 里 drop user ‘user1’@‘client_ip’; 就是仅仅删除用户账号和账号相关的权限,不会对database里的对象带来影响,数据库要单独删除。 参考图7: Oracle 数据库从物理结构上去认识,就是一堆文件的集合,其中包含三种核心文件,它们分别是控制文件,联机重做日志文件和数据文件,参考下图:
这一期,oracle 数据库和mysql 数据库的比较我们就介绍到这里,希望对大家学习有所帮助! 2022/03/02
|