Database、Schema、User都是数据库的基本概念,SQL标准中也有明确规范。但不同数据库的具体实现也不尽相同,有些甚至大相径庭。这就导致用户在做国产化选型和数据库迁移时可能会遇到种种困难。本文从这几个基本概念展开,说说为什么openGauss系数据库是国产数据库替换的当下之选。
同事的问题
今天有个同事问了我一个问题:
这位同事之前是搞MySQL的,对Oracle不甚了解。我们先来看看这两个图:
图1就是Oracle DBA经常用到的静态数据字典视图dictionary,可以查询数据库中所有的表和视图及其注释。我本人也经常模糊查询dictionary视图找到完整的表名。
图2的内容就有点陌生了。经验丰富的Oracle DBA应该很容易做出判断。图2会话应该并非使用sys登录的,恰好这个用户下有个同名的对象dictionary。
问题本身并不复杂,但却体现了不同数据库对这些基本概念实现上的差异。我借此机会整理一下Oracle、MySQL、openGauss这几个主流数据库在Database、schema、user这几个概念上的差异,也分享一下这些差异在国产数据库替换方面的影响。
概念说明
Database,是一个有组织的数据单元。这个概念所有数据库都是一致的。三家并无太大的不同。
Schema,是一个命名的数据库对象的集合,是一个逻辑范畴。如果把数据库比喻成一个大楼,那schema可以认为是每个房间。每个房间都可以配置自己的物品。也就是每个schema都可以有自己的表、视图、索引这些对象。
User,数据库中的用户,也就是数据的使用者。就如同进入大楼的人,可以进入自己的房间,也可以进入被授权的其它房间。
数据库中的所有对象(表、视图等)都是在这三个概念下组织起来的。具体组织方式则各不相同。
openGauss
openGauss源于PostgreSQL,而PostgreSQL又被称为学院派数据库,一板一眼的按规范完全实现了这些概念:
上图可知openGauss中用户独立于数据库之外,不属于数据库的一部分。数据库管理员登录到数据库创建用户时,openGauss自动在数据库中创建一个与用户名同名的schema。
vastbase=# create user appuser with password 'Password#0000' login;
CREATE ROLE
vastbase=# \dnList of schemasName | Owner
-------------------------+----------appuser | appuser...
登录的用户可以通过set search_path命令切换有权限的其它schema,并创建对象:
vastbase=# set search_path=appuser;
SET
vastbase=# show current_schema;current_schema
----------------appuser
(1 row)
vastbase=# create table zqhtest_1125(id number,name varchar2(20));
CREATE TABLE
当需要更多schema时,可以通过create schema命令创建:
vastbase=# create schema appuser2;
CREATE SCHEMA
vastbase=#
vastbase=# set search_path=appuser2;
SET
vastbase=# create table zqhtest_1125(id number,name varchar2(20));
CREATE TABLE
可以看到不同schema下面可以创建同名的对象,所以说schema又叫namespace。是一个命名空间,不同schema下可以创建同名对象。
值得一提的是openGauss创建schema的语法也与SQL规范完全兼容,下面的截图来自Vastbase官方文档:
CREATE SCHEMA AUTHORIZATION user_name [ schema_element [ ... ] ];
Oracle
Oracle的实例在其生命周期内只能打开一个数据库,无法在一个实例下创建多个数据库,自然user也就没法独立于数据库之外。所以Oracle将user设计成了数据库的一部分,同时允许在一个数据库内创建多个user。
当用户被创建时Oracle会自动为其创建同名的schema,这一点是与openGauss一致的。
Oracle也可以在用户不变的情况下切换schema,但几乎没有人这么用:
可以看到用户名还是sys,但schema已经变了。之所以没有人切换schema,是因为Oracle不能脱离用户单独创建传统意义上的schema,也就是说用户名和schema必须是一一对应的。
读者可能注意到了,我上面说的是Oracle不能创建“传统意义“上的schema。这是因为Oracle为schema引入了新的内涵。查阅官方文档可知Oracle同样支持create schema语法:
Oracle的解释是这样的:
Use theCREATE SCHEMA statement to create multiple tables and views and perform multiple grants in your own schema in a single transaction.
To execute aCREATE SCHEMA statement, Oracle Database executes each included statement. If all statements execute successfully, then the database commits the transaction. If any statement results in an error, then the database rolls back all the statements.
没错!这根本与我们说的schema不是一个概念。Oracle相比其它数据库一直有个不足:DDL是隐式提交的,不支持回滚。所以Oracle使用这个create schema语句解决了DDL回滚的问题,将DDL放到schema中就实现回滚。
这样既实现了SQL规范,又实现了DDL回滚的功能。
MySQL
MySQL的user也是独立于数据库之外的:
但在Schema方面MySQL跟Oracle走了两个相反的方向,它把schema和database合起来了。
下图来自MySQL官方文档:
而且文档也做了说明:
CREATE DATABASE creates a database with the given name. To use this statement, you need the CREATE privilege for the database. CREATE SCHEMA is a synonym for CREATE DATABASE.
Create schema就是Create Database的同义词,在MySQL中是完全相同的。所以在MySQL中无法创建与数据库名相同的schema:
2021年有个客户做国产化替代工作,将MySQL中的数据库一对一的迁移到了openGauss,结果应用中的跨数据库的两表关联查询无法支持了。找我们协助我才知道MySQL竟然支持跨数据库关联查询。这在Oracle DBA和openGauss DBA眼里是多么离谱的功能!
我查阅了MySQL的官方文档看了上面的语法解释才豁然明白,其实本质上也就是两个schema关联查询。
MySQL这样设计的弊端就是同一个数据库下无法创建同名对象了,比如:
这是显而易见的,因为只有一个schema。用户只能为每个业务创建单独的database,所以MySQL DBA管理的数据库数量都特别多。
总结
相对于这些大众普遍熟知的概念和SQL规范,MySQL和Oracle都有所偏离。
Oracle将user和schema合并了。而create schema命令的行为与创建传统意义的schema完全是风马牛不相及。因为不能脱离user单独创建schema,所以Oracle里要创建更多的user。
MySQL将Database和schema合并了,create schema其实就是create database的同义词。这在一定程度上降低了使用难度,但与其它数据库兼容性变差。跨数据库关联查询和同一个数据库中不能有同名对象这些行为在Oracle和openGauss/PostgreSQL的用户看来是如此的离谱。
openGauss源于PostgreSQL,也继承了PostgreSQL学院派风格,完整的实现了SQL规范。所以也就有更多灵活性和兼容性。替代Oracle时因为user和schema都是对应的,所以不需要做更多的转换。替换MySQL时可以将每个database迁移到openGauss的schema中。
可以这样说:openGauss是当下国产化数据库替代的最佳选择。
本文作者:传奇队长
转自:高斯茶话会