MatrixOne 实战系列回顾 | 建模与多租户

news/2024/7/10 19:53:32 标签: 数据库, 云原生, 分布式, 开源, 数据库架构

本次分享主要介绍MatrixOne建模与多租户相关内容。

1 建模

#1 与MySQL的区别

使用create table语句建表和MySQL建表语句基本相同,也有几点要注意。

  • MatrixOne暂不支持空间数据类型,其他数据类型在保持与 MySQL 命名一致的情况下,在精度与范围上,与 MySQL 存在有着细微的差异,具体可参见数据类型。
  • MatrixOne主键主键必须包含 UNIQUE 值,不能包含 NULL 值
  • MatrixOne索引目前支持主键索引、唯一索引,二级索引仅支持语法,暂无加速效果。
  • MatrixOne目前只支持utf8编码,不支持修改,建表时可不指定编码。
  • MatrixOne中仅有 TAE 一种存储引擎,它可以同时支持行和列存储以及事务处理能力,建表时无需使用 ENGINE=XXX 来更换引擎。
  • MatrixOne中临时表只在当前会话中可见,在会话关闭时自动删除。这表示两个不同的会话可以使用相同的临时表名,而不会彼此冲突或与同名的现有非临时表冲突。在删除临时表之前,会隐藏现有表。

#2 序列

序列(Sequence)是一种特殊的数据库对象,它可以被用来自动生成唯一的数字序列。通常情况下,序列被用来为一个表的主键字段自动生成唯一的值。

▶ 2.1 创建序列

要在表格中使用序列,首先使用CREATE SEQUENCE创建一个序列对象my_sequence。

▶ 2.2 表中使用序列

将 my_sequence序列应用到表中的字段,为了将序列应用到表中的字段,需要在表定义中指定一个默认值为序列的下一个值,如下所示:

CREATE TABLE my_table (
  id INTEGER DEFAULT nextval('my_sequence'),
  name VARCHAR(50));

注意:在表中使用 SEQUENCE 时,需要注意 auto_increment 与 sequence 不能一起用,否则会报错。

▶ 2.3 插入数据 

当插入一行数据时,如果没有指定 "id" 字段的值,那么 MatrixOne 将会自动从序列中获取下一个唯一的值作为其默认值。

▶ 2.4 验证序列

通过使用序列,可以轻松地在表格中自动分配唯一的标识符,从而避免了手动分配标识符可能带来的错误。使用下面的语句进行查询验证

#3 分区

▶ 3.1 范围分区

范围分区是一种基于连续值的分区方式,分区键可以是整数类型或日期类型中的 DATE 或 DATETIME。分区之间必须是互不重叠的,分区的定义使用 VALUES LESS THAN 运算符。需要注意的是,如果插入或更新的数据中,分区列的值没有对应的分区,那么相应的插入或更新操作将会失败。

▶ 3.2 列表分区

列表分区要求每个分区必须由明确定义的值列表组成,且每个分区的列表成员不能有重复值。列表分区只能使用整数类型作为分区键。

▶ 3.3 哈希分区

哈希分区通常用于将数据均匀分布在不同的分区中。常见的哈希分区有 HASH 函数分区和 KEY 函数分区。

在 HASH 函数分区中,必须明确指定用于分区的列或表达式,该列或表达式的类型必须是整数,并且建议明确指定分区数量,该数量必须是正整数。

CREATE TABLE tm1 (
s1 CHAR(32) PRIMARY KEY
)
PARTITION BY KEY();

与 HASH 函数分区不同的是,KEY 函数分区支持除大对象类型(TEXT/BLOB)之外的所有类型作为分区键,而且不一定需要指定分区数量。如果分区键是该表的主键列,那么在不显式指定分区键时,系统会默认以主键列作为分区键。

#4 Cluster by

单列语法为:create table() cluster by col;

多列语法为:create table() cluster by (col1, col2);

在建表时使用 Cluster by 命令,对于无主键的表,可以按照指定的列对表进行物理排序,并将数据行重新排列成与该列的值的顺序相同的顺序。这种物理排序有助于提高查询性能。

以下是使用 Cluster by 的一些注意事项:

  • Cluster by 不能和主键同时存在,否则会语法报错。
  • Cluster by 只能在建表时指定,不支持动态创建。

2 用户、角色与权限

#1 MatrixOne 权限管理概述

MatrixOne 权限管理帮助你管理租户、用户帐号生命周期,分配给用户相应的角色,控制 MatrixOne 中资源的访问权限。当数据库或集群单位中存在多个用户时,权限管理确保用户只访问已被授权的资源,赋予用户最少权限原则可降低企业信息安全风险。MatrixOne 也可以通过权限管理实现多租户方案。在 MatrixOne 中,每个租户在集群中所拥有的数据或资源被安全的隔离,跨集群单位的用户不可访问其他集群单位的资源,在该集群中被赋权访问资源的用户才有权访问本集群单位内的资源。

>> 集群 

集群是 MatrixOne 权限管理中最高层级的对象,当部署完 MatrixOne 后便创建了集群这个对象。

注意: 对集群对象的操作权限的集合被称为系统权限。

>> 租户 

MatrixOne 集群内可以创建和管理多个数据和用户权限体系完全隔离的租户,并对这些资源隔离的租户进行管理,这种多租户功能既节省了部署和运维多套数据业务系统的成本,又能利用租户间的硬件资源共享最大限度的节约机器成本。

在 MatrixOne 中将租户称为 Account。

>> 系统租户 

为了兼容传统非多租户数据库的使用习惯,MatrixOne 在集群创建完成后会自动新建一个系统默认租户,也就是系统租户,即 Sys Account,如果你现在只有一套数据业务系统需要 MatrixOne 管理,便不需要创建更多的租户,直接登录并访问系统租户 (Sys Account) 即可。

>> 角色 

角色也是一个对象,它是 MatrixOne 中用来管理和分配权限的对象。

在租户中,用户如果没有被赋予角色,那么用户就不能做任何操作。首先,需要先有一个高权限的账号先做一些初期的资源分配,比如说,由系统租户或者租户创建一些角色和用户,将对象权限授予给角色,再将角色赋予给用户,这个时候,用户就可以对对象进行操作了。

#2 初始化配置

系统集群创建后自动生成并授予root集群管理员权限,可以创建、编辑、删除租户。root还是系统租户管理员,管理系统租户下的所有资源,包含用户、角色、数据库/表/视图,授权管理。也就是说系统其实默认存在一个系统租户,不单独创建租户也可以使用MatrixOne。租户管理员在租户创建成功后默认可以管理普通租户下的所有资源,包含用户、角色、数据库/表/视图,授权管理。普通用户被创建后则被授予了public角色,只有连接MatrixOne的权限。

#3 登录

由于MatrixOne与Mysql8.0的协议具有高度的兼容性,我们使用Mysqlclient来连接MatrixOne。其中 -h、-p、-P`参数与 MySQL 相同,不同之处在于-u 代表用户,在 MatrixOne 的用户体系中,用户是位于租户 account以下一层的概念,因此登录时需要先指定租户 account_name,再指定租户中的用户 username才能完成登录。如果不指定accountname,则默认为系统租户sys(root)。

#4 租户

我们先使用root登录,create account命令来建立我们的第一个租户a1,租户管理员为admin,密码为test123。如果需要修改租户管理员密码,可以使用alter account命令。在系统运行过程中,可能需要暂停或恢复租户账号,这时我们可以使用alter account命令将租户状态设置为suspend或open。当租户不再使用时,可以使用drop account命令删除租户。我们退出登录,使用刚创建的租户来登录系统。

#5 用户

创建用户命令和租户类似,用户是位于租户 account以下一层的概念,user_name创建后无法修改。我们可以使用create user命令新建用户jack,创建用户时必须同时指定用户密码。需要修改用户密码可以使用alter user命令,用户不再使用时,可以使用drop user删除用户。租户。查询当前登录用户及租户信息,可以使用select user()命令。在创建用户时,可以同时指定用户角色。

#6 角色

角色可以被看做是一组权限的集合。新创建的用户可以被赋予某一角色,授予角色即表示用户被自动赋予该角色所拥有的权限。后续对角色的权限变更,也会体现在所有属于该角色的用户权限上。

创建角色使用create role,此时该角色无权限,后续可以通过 GRANT 命令赋予该角色权限;删除角色使用drop role,值得注意的是如果使用这个角色的用户正在会话中,当角色被移除,会话随即断开,无法再使用这个角色进行操作。

使用show roles可以查看你的账户下创建的角色的元信息,包括角色名称、创建者、创建时间以及注释内容。

角色之间可以继承,但不能形成环形依赖;一个角色可以授权给多个用户;一个用户也可以有多个角色,但在某一时刻只能使用其中一个角色。

>> 角色切换

一个用户被授予多个角色,用于执行不同类型的数据业务。

主要角色:用户在某一时刻只能使用其中一个角色,我们称当前所使用的这个角色为主要角色。

次要角色:除了主要角色之外该用户所拥有的其他角色集合称为次要角色。

在默认情况下,如果用户想去执行另一个角色权限的 SQL 时,需要先切换角色(即 set role)。此外,为了兼容经典数据库的权限行为,MatrixOne 还支持开启使用次要角色的功能:使用 set secondary role all,执行这条 SQL 后,该用户便可同时拥有他所有角色的权限了,执行 set secondary role none 即可关闭此功能。

#7 权限

在 MatrixOne 中,为了方便管理多种操作权限,于是便把权限封装在一个实体内,这个实体就是对象。例如,`Select`,`Insert`,`Update` 等操作权限,便封装在了 Table 对象内。图中的层级关系均为 1:n 的关系,即一个集群中可以创建多个租户(Account),一个租户下可以创建多个用户和角色,一个数据库中可以创建多个表和视图。

MatrixOne 的访问控制权限分为系统权限和对象权限。系统权限为集群管理员(默认用户名为 root)的权限。对象权限可以按照赋权的对象细分为租户权限、用户权限、角色权限、数据库权限、表权限、发布订阅权限。

在MatrixOne中只能指定角色权限,再将角色授权给用户,不能直接授权给用户。

授权使用grant命令,撤销授权使用REVOKE命令,下面我们对权限相关进行一个演示。

首先使用create database创建一个数据库db1,创建数据库语句和MySQL完全相同。

授予所有库权限给我们刚创建的角色,使用GRANT ALL ON database *.* TO tm_mo_role;

授予指定库表的指定权限给角色,使用GRANT SELECT,INSERT,UPDATE ON table db1.* TO tm_mo_role;

撤销权限使用REVOKE命令,比如撤销数据库db1所有表的UPDATE权限,使用REVOKE UPDATE ON table db1.* FROM tm_mo_role;

给已创建的用户jack配置角色,使用 GRANT 'tm_mo_role' TO jack;

撤销jack的tm_mo_role角色,使用REVOKE tm_mo_role FROM jack;

我们前面说过角色可以继承,这里再新建一个tm_mo_role2,然后将tm_mo_role授权给tm_mo_role2,这样tm_mo_role2也拥有了tm_mo_role的权限。使用GRANT tm_mo_role TO tm_mo_role2;

查看当前用户权限,使用SHOW GRANTS;

租户管理员查看指定用户比如jack的权限,可以使用SHOW GRANTS FOR jack;

3 资源隔离场景

#1 场景描述

A 公司购买了 MatrixOne 集群,并且完成了部署。由于 A 公司规模比较大,业务线多且复杂,数据量也非常庞大,想要针对某个业务线开发一款应用程序,假设命名为 BusinessApp,但是需要跟其他业务线的数据进行隔离,那么 MatrxiOne 怎么隔离出这些数据资源、权限资源呢?

完成部署 MatrixOne 集群,研发部门的 Tom 获取到集群管理员的账号,公司指派他来完成资源隔离这一任务。Tom 需要这么做:

  1. Tom 使用集群管理员的账号登录 MatrixOne。
  2. Tom 需要先创建两个租户,租户账号一个是 BusinessAccount,一个是 ElseAccount。
  • BusinessAccount 内的数据资源主要用于开发应用程序 BusinessApp。
  • ElseAccount 内的数据资源可以用于其他业务目的。

#2 实操

使用集群管理员的用户名(默认 root)和密码登录 MatrixOne。

▶ 2.1 创建租户 

  • 租户 businessAccount 的登录用户名和密码分别为:admin1,test123;
  • 租户 elseAccount 的登录用户名和密码分别为:admin2,test456。

▶ 2.2 租户businessAccount操作 

使用 admin1 登录租户 businessAccount,并创建数据库db1,数据表 db1.t1,并向t1中插入数据,并使用select 验证表是否创建成功。

▶ 2.3 租户elseAccount操作 

使用 admin2 登录租户 elseAccount,查看租户 businessAccount中的 db1.t1数据,提示表不存在。在租户elseAccount中也可以创建库db1和表db1.t1,在租户elseAccount 的db1.t1这张表内插入与租户businessAccount中表db1.t1不同的数据并查看,表中的数据和租户 businessAccount的t1表中的数据不同,说明MatrixOne实现了租户间的资源隔离。

用户创建与授权场景

#1 场景描述


还是沿用上面的场景示例,Tom 把 BusinessAccount 这个租户账号给了公司的数据管理员 Robert,让 Robert 去分配新的用户账号和权限给其他研发同事。

研发同事 Joe 是这个 A 公司项目 BusinessApp 的应用开发者,Joe 有一个开发任务,Joe 需要使用数据库内所有的数据。那么 Robert 就要帮 Joe 开通账号,给 Joe 授权:

  1. Robert 先给 Joe 创建了一个用户账号(即,用户),名字叫做 Joe_G,Joe 就使用 Joe_G 这个账号登录到 MatrixOne。
  2. Robert 又给 Joe 创建了一个角色,名字叫做 Appdeveloper,并且把 Appdeveloper 角色赋予给 Joe 的用户账号 Joe_G 上。
  3. Robert 又给角色 Appdeveloper 授予了 ALL ON DATABASE 的权限。
  4. Joe 就可以使用 Joe_G 这个账号登录到 MatrixOne,并且全权操作数据库进行开发了。
  5. Smith是运营人员,需要使用数据库中的数据进行最终业务报表的呈现,我们给他一个账号smith,赋予角色operator,把数据库db1的所有表的读权限授予角色operator

#2 实操

系统集群创建后自动生成并授予root集群管理员权限,可以创建、编辑、删除租户。root还是系统租户管理员,管理系统租户下的所有资源,包含用户、角色、数据库/表/视图,授权管理。也就是说系统其实默认存在一个系统租户,不单独创建租户也可以使用MatrixOne。租户管理员在租户创建成功后默认可以管理普通租户下的所有资源,包含用户、角色、数据库/表/视图,授权管理。普通用户被创建后则被授予了public角色,只有连接MatrixOne的权限。

▶ 2.1 新建用户、角色 

  • 用户Joe 的用户名和密码分别为:Joe_G,user123
  • 用户 Smith的用户名和密码分别为:smith,user456
  • 角色 Appdeveloper的命名为:appdeveloper
  • 角色 Operator的命名为:operator

▶ 2.2 授权

将 db1 的ALL ON DATABASE,ALL ON TABLE 的权限授予给 appdeveloper,表的SELECT权限授予给 operator。

此时的角色权限如下图所示:

将角色 Appdeveloper授予给用户 Joe_G;将角色 operator授予给用户 u2。

▶ 2.3 使用 Joe_G登录businessAccount进行权限验证

Joe可以在数据库db1中创建表,向表中插入数据,查询刚刚插入的数据。

▶ 2.4 使用smith登录businessAccount进行权限验证

只能查询db1中的表t2的数据,但无法向表t2插入数据,也无法创建新表。

Q&A环节

感谢大家和我一起学习MatrixOne建模与多租户的相关知识,下面进入Q&A环节。

Q:MySQL中的表引擎能直接迁移吗?MO兼容InnoDB这些?

A:MatrixOne不支持MySQL的InnoDB,MyISAM等引擎,但可以直接使用MySQL的语句在,MO会忽略这些引擎,在MatrixOne中仅有TAE一种存储引擎,它是完全独立研发的,可以友好的适用于各类场景,无需使用ENGINE=XXX来更换引擎。

Q:支不支持物化视图?

A:MatrixOne目前不支持物化视图,在目前的AP性能支撑下,直接进行分析也可以获得较高的分析体验。物化视图功能也已经在MatrixOne的Roadmap中,如果您对物化视图有刚性较高的需求,欢迎给我们提Issue来描述您的场景:https://github.com/matrixorigin/matrixone/issues

Q:多租户之间是如何实现资源隔离的?

A:MatrixOne的资源隔离核心是ACCOUNT可以对应到CN Set的资源组上,或者可以认为租户的隔离就是CN的容器隔离。除了多租户可以分配不同资源组以外,单个租户内部也可以根据业务类型进一步分配CN资源组,进行更细粒度的控制。关于资源隔离的完整描述,您可以参考:https://docs.matrixorigin.cn/1.0.0-rc2/MatrixOne/Deploy/mgmt-cn-group-using-proxy/#_2

Q:MO的权限也是基于RBAC模型设计的吗?可不可以将权限直接授予到用户?

A:MatrixOne的权限管理是结合了基于角色的访问控制(RBAC,Role-based access control)和自主访问控制(DAC,Discretionary access control)两种安全模型设计和实现的,不支持将权限直接授予用户,需要通过角色进行授权。

Q:普通用户能授予MOADMIN角色吗?

A:不可以的,MOADMIN为最高的集群管理员权限,只有root用户拥有。

Q:MO对标识符大小写是否敏感?

A:MatrixOne默认对标识符大小写不敏感,并支持通过lower_case_table_names参数来进行大小写敏感的支持,对于参数的详细介绍您可以参考:https://docs.matrixorigin.cn/1.0.0-rc2/MatrixOne/Reference/Variable/system-variables/lower_case_tables_name/

Q:怎么查看临时表?show tables看不到,怎么知道是不是创建了?

A:目前可以通过"show create table 临时表名"来查看,由于临时表在创建后只在当前会话可见,在当前会话结束时,数据库自动删除临时表并释放所有空间,在它的生命周期内我们通常是可以人为感知的。

Q:目前连接MO支持哪些编程语言?

A:Java、Python、Golang语言连接器和ORM都是支持,其他语言逻辑上也可以当作MySQL来进行连接。

Q:MO在事务处理这块,与MySQL有什么区别?

A:MatrixOne 默认为悲观事务,也不支持表级锁。MatrixOne 中的 DDL 语句是支持事务性的,可以在一个事务中回滚 DDL 操作,与 MySQL 不同。

MySQL DDL语句却不支持事务。也就是说,如果在执行DDL语句时出现错误,无法回滚到之前的状态,但是msyql 执行ALTER TABLE时 有专门的语法支持事务, mysql是支持表级锁的、行级锁。

Q:MO支持设置连接白名单或者黑名单吗?

A:支持白名单,目前不支持黑名单。


http://www.niftyadmin.cn/n/5186115.html

相关文章

城市生命线丨城市燃气管网监测系统功能效果

11月6日,福建泉州某小区发生煤气闪爆导致1死三伤,这起事故再次为我们敲响了城市燃气管网安全监测的警钟。在城市生命线的建设中,城市燃气管网监测系统以其独特的作用和价值,成为保障城市安全的重要一环。 根据应急管理部《全国城镇…

LeetCode - 232.用栈实现队列 225.用队列模拟实现栈 (C语言,配图)

目录 232.用栈实现队列 225.用队列模拟实现栈 注:本文是基于C语言实现的代码,所以栈和队列是在力扣上制造实现的,如果你使用C等语言,可以忽略前面相当大部分的代码。 在栈模拟实现栈和队列之前,我们先来复习一下栈和…

行情分析——加密货币市场大盘走势(11.16)

大饼昨日突然回调诱多上涨到38000附近,现在又重新跌回到37500,现在仓位小的可以加仓入场,而已经有仓位的不要动即可。 空单策略:入场37500附近 止盈34000-32000 止损39000 以太今日可以入场空单2060附近即可 策略:入…

杨辉三角c语言程序

以下是一个简单的 C 语言程序&#xff0c;用于打印杨辉三角的前 n 行&#xff1a; #include <stdio.h>int main() { int n, i, j; int arr[n][n]; printf("Enter the number of rows: "); scanf("%d", &n); arr[0][0] 1; fo…

如何开发OA系统场景的系统架构

1.开发OA系统场景的系统架构 针对开发OA系统的场景&#xff0c;以下是一个简单的系统架构示例&#xff0c;包括前端、后端和数据库三个基本部分&#xff1a; 前端&#xff1a; 使用React框架进行前端开发&#xff0c;构建用户界面和交互逻辑。前端模块包括日程管理模块、文档管…

Linux进程之进程的状态简述

文章目录 1.百度搜索2.对进程状态的认识2.0创建状态2.1就绪状态2.2运行状态2.3阻塞状态2.4挂起状态 3.认识LinuxOS下的进程3.0进程状态的简述3.1了解R/S状态3.2D深度睡眠状态3.3信号/调试暂停状态3.4僵尸状态 1.百度搜索 2.对进程状态的认识 一个进程所具有的状态为操作系统的…

HarmonyOS开发:动态共享包的依赖问题

一、共享包的依赖方式 在需要依赖的模块包目录下oh-package.json5文件中添加依赖&#xff1a; "dependencies": {"ohos/srpaasUI": "file:../../srpaasUI","ohos/srbusiness": "file:../../feature/srbusiness"} 引入之后…

Python编程陷阱(九)

陷阱36:不要使用list.sort方法来对列表进行排序。 列表是Python中最常用的数据结构之一,它可以存储任意类型的元素,并且可以动态地增加或删除元素。有时候,我们需要对列表中的元素进行排序,比如根据元素的值或类型或顺序来分析或修改列表,就需要使用list.sort方法或sorte…