当前位置: 首页 > news >正文

在Oracle\PG\GaussDB库中实现用户甲在其它用户的SCHEMA中创建表的方法及所属属主的差异

第一章 案例总结概要

1.1 User概念

在SQL标准中,User(用户)是指能够连接到数据库并执行操作的实体,通常对应一个个体或应用程序。每个用户拥有唯一的标识符(如用户名)和认证机制(如密码)。User在数据库集簇(指由同一个数据库实例中的多个逻辑数据库的集合)中是共享的。即只要用户有相应的权限,就可以访问到数据库实例中的所有数据库。

与User相关的,还是一个role(角色)的术语,其是一组权限的抽象集合,用于简化权限管理。角色可以分配给用户或其他角色,支持权限的层次化继承。

但在不同的数据库中,其实现也是有差异的。比如在PG系数据库中(包括opengauss\gaussdb),这两者是同一概念,两者通过是否具有LOGIN权限来区分。有LOGIN权限的,就是用户,否则,则是角色。也正因如此,命令CREATE USER是命令 CREATE ROLE的一个别名。两者唯一的区别是 CREATE USER中LOGIN 被作为默认值,而NOLOGIN是 CREATE ROLE的默认值;而在Oracle数据库中,这两者是严格区分的,用户是用户,角色是角色,其更接近SQL标准中的定义。

1.2 Schema概念

在数据库中,SCHEMA(模式) 是一个逻辑容器,用于组织和管理数据库对象(如表、视图、函数、索引等)。它定义了数据库对象的命名空间和权限边界。SCHEMA是属于特定数据库的,它不能在不同的数据库中共享。

同样,在不同的数据库中,SCHEMA的实现也是不同的。比如在PG数据库中,有专门的创建SCHEMA的命令(create schema),一个用户可以有专属的SCHEMA,也可以没有,而共用名为PUBLIC的SCHEMA。甚至,一个用户还可以有多个SCHEMA。而在Oracle数据库中,并无创建SCHEMA的命令。当创建用户时,会自动创建出一个同名的SCHEMA。在Oracle库中,一个用户有且只有一个对应的SCHEMA。而在GaussDB和OpenGauss中,则是前述两者的混合:在GaussDB和OpenGauss中,创建用户时,会自动创建出一个同名的SCHEMA。这一点,类似Oracle。但是,它又类似PG数据库,可以创建新的SCHEMA,允许一个用户有多个SCHEMA。

1.3 需求背景及描述

正因为上述的这些差异,当我们面临希望一个用户,可以在另一个用户所属的SCHEMA中创建表的需求时,实现的方法就有了不同。下面三章,我们将通过实例,演示分别在Oracle、PG和GaussDB库操作的过程,以及其行为表现。
具体的需求如下:

1、 在数据库中创建两个用户user1和user2,并各自拥有相应的同名SCHEMA。
2、 实现user1可以在schema user2中创建表。

第二章 Oracle库中操作和表现

2.1 创建用户和SCHEMA

由于Oracle库中并无创建schema的命令,而是在创建用户时,自动创建同名的schema。所以,并不需要单独创建schema。
创建过程如下:

  [oracle@localhost ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.4.0 Production on Wed May 7 08:57:45 2025
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
Connected to an idle instance.
SQL> startup
ORACLE instance started.
Total System Global Area 3206836224 bytes
Fixed Size		    2257520 bytes
Variable Size		  536874384 bytes
Database Buffers	 2650800128 bytes
Redo Buffers		   16904192 bytes
Database mounted.
Database opened.
SQL> create user user1 identified by user1;
User created.
SQL> grant connect,resource to user1;
Grant succeeded.
SQL> create user user2 identified by user2;
User created.
SQL> grant connect,resource to user2;
Grant succeeded.

2.2 授权前建表测试

尝试分别使用用户USER1和USER2,在各自的SCHEMA中创建表。过程如下:

  SQL> conn user1/user1
Connected.
SQL> create table user1_tab1 (id number);
Table created.
SQL> conn user2/user2
Connected.
SQL> create table user2_tab1 (id number);
Table created.

再尝试使用用户user1,在user2中创建表,过程如下:

  SQL> conn user1/user1
Connected.
SQL> create table user2.user1_tab2 (id number);
create table user2.user1_tab2 (id number)
*
ERROR at line 1:
ORA-01031: insufficient privileges

如上所示,报权限不足。

2.3 为用户USER1授权

为用户USER1授予create any table的系统权限。过程如下:

  SQL> conn / as sysdba
Connected.
SQL> grant create any table to user1;
Grant succeeded.

然后,再测试使用用户user1,在user2中创建表,过程如下:

  SQL> conn user1/user1
Connected.
SQL> create table user2.user1_tab2 (id number);
Table created.
SQL>

2.4 查询相关表的OWNER信息

查询前述创建表的OWNER信息,结果如下:

  SQL> select owner,table_name from dba_tables where table_name in ('USER1_TAB1','USER2_TAB1');
OWNER                          TABLE_NAME
------------------------------ ------------------------------
USER1                          USER1_TAB1
USER2                          USER2_TAB1
SQL>

如上所示,可以看到各表的OWNER与该表的创建者是一致的。即,谁创建的,OWNER就是谁。

第三章 PG库中的操作和表现

PG库的版本为12.2。

3.1 创建用户和SCHEMA

创建过程如下:

 [postgres@localhost ~]$ psql -d mydb
psql (12.2)
Type "help" for help.
mydb=# \conninfo
You are connected to database "mydb" as user "postgres" via socket in "/tmp" at port "1921".
mydb=# create user user1 password 'user1@1234';
CREATE ROLE
mydb=# create user user2 password 'user2@1234';
CREATE ROLE

如上所示,我们在mydb库中,创建了两个用户:user1和user2。但此时,查询库中的schema,可以发现,并没有同名的schema。如下所示:

 mydb=# \dnList of schemasName  |  Owner   
--------+----------public | postgres
(1 row)

我们手工创建与用户同名的SCHEMA,如下所示:

  mydb=# create schema user1 authorization user1;
CREATE SCHEMA
mydb=# create schema user2 authorization user2;
CREATE SCHEMA
mydb=# \dn+List of schemasName  |  Owner   |   Access privileges    |      Description       
--------+----------+------------------------+------------------------public | postgres | postgres=UC/postgres  +| standard public schema|          | =UC/postgres          +| |          | sqm_monitor=U/postgres | user1  | user1    |                        | user2  | user2    |                        | 
(3 rows)

如上所示,我们为用户user1,创建了同名的schema:user1;为用户user2 ,创建了同名的schema:user2。

3.2 授权前建表测试

尝试分别使用用户USER1和USER2,在各自的SCHEMA中创建表。过程如下:

  [postgres@localhost ~]$ psql -d mydb -U user1 
psql (12.2)
Type "help" for help.
mydb=> \conninfo
You are connected to database "mydb" as user "user1" via socket in "/tmp" at port "1921".
mydb=> 
mydb=> 
mydb=> create table user1_tab1 (id int);
CREATE TABLE
mydb=> 
mydb=> \q
[postgres@localhost ~]$ psql -d mydb -U user2
psql (12.2)
Type "help" for help.
mydb=> \conninfo
You are connected to database "mydb" as user "user2" via socket in "/tmp" at port "1921".
mydb=> 
mydb=> create table user2_tab1 (id int);
CREATE TABLE
mydb=> 
mydb=>

再尝试使用用户user1,在user2中创建表,过程如下:

  [postgres@localhost ~]$ psql -d mydb -U user1 
psql (12.2)
Type "help" for help.
mydb=> create table user2.user1_tab2 (id int);
ERROR:  permission denied for schema user2
LINE 1: create table user2.user1_tab2 (id int);^
mydb=>

如上所示,报权限不足。

3.3 为用户USER1授权

为用户USER1授予create on schema user2的权限(注:在pg中,并无create any table的系统权限存在)。过程如下:

  [postgres@localhost ~]$ psql -d mydb 
psql (12.2)
Type "help" for help.
mydb=# \conninfo
You are connected to database "mydb" as user "postgres" via socket in "/tmp" at port "1921".
mydb=# grant create on schema user2 to user1;
GRANT
mydb=# \q

然后,再测试使用用户user1,在user2中创建表,过程如下:

  [postgres@localhost ~]$ psql -d mydb -U user1 
psql (12.2)
Type "help" for help.
mydb=> \conninfo
You are connected to database "mydb" as user "user1" via socket in "/tmp" at port "1921".
mydb=> 
mydb=> create table user2.user1_tab2 (id int);
CREATE TABLE
mydb=>

3.4 查询相关表的OWNER信息

查询前述创建表的OWNER信息,结果如下:

  [postgres@localhost ~]$ psql -d mydb -U user1
psql (12.2)
Type "help" for help.
mydb=> \dt+ user1_tab2
Did not find any relation named "user1_tab2".
mydb=> 
mydb=> \dt+ user2.user1_tab2;List of relationsSchema |    Name    | Type  | Owner |  Size   | Description 
--------+------------+-------+-------+---------+-------------user2  | user1_tab2 | table | user1 | 0 bytes | 
(1 row)

如上所示,我们可以看到user1在schema user2中创建的表,其owner仍然是user1。
查看两个用户在各自SCHEMA中创建的表user1_tab1和user2_tab1的owner信息,结果如下所示:

mydb=> \dt+ user1.user1_tab1List of relationsSchema |    Name    | Type  | Owner |  Size   | Description 
--------+------------+-------+-------+---------+-------------user1  | user1_tab1 | table | user1 | 0 bytes | 
(1 row)
mydb=> \dt+ user2.user2_tab1List of relationsSchema |    Name    | Type  | Owner |  Size   | Description 
--------+------------+-------+-------+---------+-------------user2  | user2_tab1 | table | user2 | 0 bytes | 
(1 row)

如上所示,可以看到各表的OWNER与该表的创建者是一致的。即,谁创建的,OWNER就是谁。该行为与Oracle中的表现是相同的。

第四章 GaussDB库中的操作和表现

4.1 创建用户和SCHEMA

创建过程如下:

  [gaussdb@localhost ~]$ gsql -d testdb -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=# create user user1 password 'user1@1234';
CREATE ROLE
testdb=# create user user2 password 'user2@1234';
CREATE ROLE
testdb=#

如上所示,我们在mydb库中,创建了两个用户:user1和user2。此时,查询库中的schema,可以发现,已经自动创建了同名的schema。如下所示:

  testdb=# \dnList of schemasName         |  Owner
----------------------+---------blockchain           | gaussdbcstore               | gaussdbdb4ai                | gaussdbdbe_application_info | gaussdb<省略部分输出信息>sys                  | gaussdbtest                 | testuser1                | user1user2                | user2
(41 rows)

4.2 授权前建表测试

尝试分别使用用户USER1和USER2,在各自的SCHEMA中创建表。过程如下:

  [gaussdb@localhost ~]$  gsql -d testdb -Uuser1 -Wuser1@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user1" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> create table user1_tab1 (id int);
CREATE TABLE
testdb=> \q
[gaussdb@localhost ~]$  gsql -d testdb -Uuser2 -Wuser2@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user2" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> create table user2_tab1 (id int);
CREATE TABLE
testdb=> \q
[gaussdb@localhost ~]$

再尝试使用用户user1,在user2中创建表,过程如下:

[gaussdb@localhost ~]$  gsql -d testdb -Uuser1 -Wuser1@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user1" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> create table user2.user1_tab2 (id int);
ERROR:  Permission denied for schema user2.
DETAIL:  N/A.
testdb=>

如上所示,提示权限不足。

4.3 为用户USER1授权

为用户USER1授予create any table的权限。过程如下:

 [gaussdb@localhost ~]$ gsql -d testdb -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=# \conninfo
You are connected to database "testdb" as user "gaussdb" via socket in "/gaussdb/tmp" at port "8000".
testdb=#
testdb=# grant create any table to user1;
GRANT
testdb=# \q
[gaussdb@localhost ~]$

然后,再测试使用用户user1,在user2中创建表,过程如下:

 [gaussdb@localhost ~]$  gsql -d testdb -Uuser1 -Wuser1@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user1" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> create table user2.user1_tab2(id int);
CREATE TABLE
testdb=>

4.4 查询相关表的OWNER信息

查询前述创建表的OWNER信息,结果如下:

[gaussdb@localhost ~]$  gsql -d testdb -Uuser1 -Wuser1@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user1" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> create table user2.user1_tab2(id int);
CREATE TABLE
testdb=>
testdb=> \dt+ user2.user1_tab2;List of relationsSchema |    Name    | Type  | Owner |  Size   |                             Storage                              | Descrip
tion
--------+------------+-------+-------+---------+------------------------------------------------------------------+--------
-----user2  | user1_tab2 | table |       | 0 bytes | {orientation=row,compression=no,storage_type=USTORE,segment=off} |
(1 row)
testdb=> \q

如上所示,此时owner列中的值为空。切换到user2,再次查看该表的OWNER信息:

[gaussdb@localhost ~]$  gsql -d testdb -Uuser2 -Wuser2@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user2" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> \dt+ user2.user1_tab2;List of relationsSchema |    Name    | Type  | Owner |  Size   |                             Storage                              | Descrip
tion
--------+------------+-------+-------+---------+------------------------------------------------------------------+--------
-----user2  | user1_tab2 | table | user2 | 0 bytes | {orientation=row,compression=no,storage_type=USTORE,segment=off} |
(1 row)
testdb=>

如上所示,我们可以看到显示该表的OWNER为user2,即该表所在SCHEMA同名的OWNER。
但当不存在与所在SCHEMA同名的用户时,会是什么情况呢?我们通过实际操作来验证:
首先,我们创建一个新的SCHEMA,名为USER2_B,且并不存在名为USER2_B的用户。设置该SCHEMA的OWNER为USER2,创建过程如下:

 [gaussdb@localhost ~]$ gsql -d testdb -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=# \conninfo
You are connected to database "testdb" as user "gaussdb" via socket in "/gaussdb/tmp" at port "8000".
testdb=#
testdb=# create schema user2_b authorization user2;
CREATE SCHEMA
testdb=# \dnList of schemasName         |  Owner
----------------------+---------blockchain           | gaussdbcstore               | gaussdbdb4ai                | gaussdbdbe_application_info | gaussdbdbe_compression      | gaussdb
<省略部分输出>
sys                  | gaussdbtest                 | testuser1                | user1user2                | user2user2_b              | user2
(42 rows)
testdb=#

然后使用user1,在schema user2_b 中创建一个新表,过程如下:

  [gaussdb@localhost ~]$  gsql -d testdb -Uuser1 -Wuser1@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> create table user2_b.user1_tab3(id int);
CREATE TABLE
查看该表的OWNER:testdb=> \dt+ user2_b.user1_tab3;List of relationsSchema  |    Name    | Type  | Owner |  Size   |                             Storage                              | Descri
ption
---------+------------+-------+-------+---------+------------------------------------------------------------------+-------
------user2_b | user1_tab3 | table | user1 | 0 bytes | {orientation=row,compression=no,storage_type=USTORE,segment=off} |
(1 row)
testdb=>

如上所示,该表的OWNER为USER1。虽然所在的SCHEMA USER2_B的OWNER是USER2,但因为无与USER2_B同名的用户,所以,该表的OWNER仍为其初始创建者–USER1。
继续查看两个用户最初创建的user1_tab1和user2_tab1两张表的OWNER信息:

 [gaussdb@localhost ~]$  gsql -d testdb -Uuser1 -Wuser1@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user1" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> \dt+ user1_tab1List of relationsSchema |    Name    | Type  | Owner |  Size   |                             Storage                              | Descrip
tion
--------+------------+-------+-------+---------+------------------------------------------------------------------+--------
-----user1  | user1_tab1 | table | user1 | 0 bytes | {orientation=row,compression=no,storage_type=USTORE,segment=off} |
(1 row)
testdb=>
testdb=> \q
[gaussdb@localhost ~]$  gsql -d testdb -Uuser2 -Wuser2@1234 -r
gsql ((GaussDB Kernel 505.2.0.SPC0100 build 8db8eac8) compiled at 2024-11-02 19:03:49 commit 9980 last mr 20502 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
testdb=> \conninfo
You are connected to database "testdb" as user "user2" via socket in "/gaussdb/tmp" at port "8000".
testdb=>
testdb=> \dt+ user2_tab1List of relationsSchema |    Name    | Type  | Owner |  Size   |                             Storage                              | Descrip
tion
--------+------------+-------+-------+---------+------------------------------------------------------------------+--------
-----user2  | user2_tab1 | table | user2 | 0 bytes | {orientation=row,compression=no,storage_type=USTORE,segment=off} |
(1 row)
testdb=>

如上所示,可以看到各表的OWNER是与该表所在的SCHEMA同名的OWNER。即,表在哪个SC。


文章转载自:

http://JPGvsjvT.yysqz.cn
http://jRjmabW4.yysqz.cn
http://EKptqVn5.yysqz.cn
http://PsPpOQw5.yysqz.cn
http://FRBmhaFn.yysqz.cn
http://AILZE6dH.yysqz.cn
http://NGCh8fpT.yysqz.cn
http://P0T4VeHI.yysqz.cn
http://4tSZMjRf.yysqz.cn
http://2gAj2ics.yysqz.cn
http://09g5VVcp.yysqz.cn
http://qVDVwRmV.yysqz.cn
http://ZofdghAh.yysqz.cn
http://OeIbpHrj.yysqz.cn
http://GsErOM8I.yysqz.cn
http://MKDFTPDS.yysqz.cn
http://P37X4pAB.yysqz.cn
http://5VivG8w0.yysqz.cn
http://5YMXk1Yh.yysqz.cn
http://oRaiqzwQ.yysqz.cn
http://uBNbC4OD.yysqz.cn
http://TAnzMqZF.yysqz.cn
http://GqjGqBqu.yysqz.cn
http://Y7z5EFqE.yysqz.cn
http://aH7s3lER.yysqz.cn
http://DlFLZpYB.yysqz.cn
http://b3NItJvw.yysqz.cn
http://R5DCptRv.yysqz.cn
http://veYKhsK3.yysqz.cn
http://goQQgEms.yysqz.cn
http://www.dtcms.com/a/386676.html

相关文章:

  • TDengine IDMP 基本功能——数据可视化
  • SpringMVC静态资源与Servlet容器指南
  • 安卓实现miniLzo压缩算法
  • [deepseek]LNK2001错误即单独编译汇编并链接
  • Interview X,新一代面试工具
  • Oracle sql tuning guide 翻译 Part 6 --- 优化器控制
  • Git 原理与使用
  • 什么是向量数据库
  • 利用postgres_proto和pgproto测试postgres协议访问duckdb
  • 拼多多-----anti_content逆向分析
  • 【一文了解】Unity的协程(Coroutine)与线程(Thread)
  • 贪心算法在网络入侵检测(NID)中的应用
  • 数据搬家后如何处理旧 iPhone
  • [react native招聘]
  • IDE工具RAD Studio 13 Florence重磅发布:64 位 IDE + AI 组件全面升级!
  • session存储
  • Another Redis Desktop Manager 的 SCAN 使用问题与风险分析
  • MATLAB绘制一个新颖的混沌图像(新四翼混沌系统)
  • AI起名工具
  • typeScript 装饰器
  • 【算法磨剑:用 C++ 思考的艺术・单源最短路进阶】Bellman-Ford 与 SPFA 算法模板精讲,突破负权边场景
  • 单元测试:驱动模块与桩模块在自顶向下和自底向上的策略中的作用
  • SpringBoot MVC 快速入门
  • Nature Communications 北京大学联合德国马普所在触觉传感器方面取得进展,实现机器人指尖超分辨率力感知
  • 解决一次 “Failed to load model because protobuf parsing failed”:从现象到根因与修复
  • 从ppm到ppb:全面解读浓度单位转换的诀窍
  • 贪心算法应用:霍夫曼编码详解
  • NLP Subword 之 BBPE(Byte-level BPE) 算法原理
  • 【nodejs】Windows7系统下如何安装nodejs16以上版本
  • Part05 数学