写点什么

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

作者:MatrixOrigin
  • 2023-11-16
    上海
  • 本文字数:6876 字

    阅读完需:约 23 分钟

本次分享主要介绍 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 中,为了方便管理多种操作权限,于是便把权限封装在一个实体内,这个实体就是对象。例如,SelectInsertUpdate 等操作权限,便封装在了 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 需要这么做:


Tom 使用集群管理员的账号登录 MatrixOne。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 实现了租户间的资源隔离。


4 用户创建与授权场景


#1 场景描述


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


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


Robert 先给 Joe 创建了一个用户账号(即,用户),名字叫做 Joe_G,Joe 就使用 Joe_G 这个账号登录到 MatrixOne。Robert 又给 Joe 创建了一个角色,名字叫做 Appdeveloper,并且把 Appdeveloper 角色赋予给 Joe 的用户账号 Joe_G 上。Robert 又给角色 Appdeveloper 授予了 ALL ON DATABASE 的权限。Joe 就可以使用 Joe_G 这个账号登录到 MatrixOne,并且全权操作数据库进行开发了。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 插入数据,也无法创建新表。


5 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:支持白名单,目前不支持黑名单。

发布于: 刚刚阅读数: 2
用户头像

MatrixOrigin

关注

还未添加个人签名 2021-12-06 加入

一个以技术创新和用户价值为核心的基础软件技术公司。

评论

发布
暂无评论
MatrixOne 实战系列回顾 | 建模与多租户_分布式数据库_MatrixOrigin_InfoQ写作社区