写点什么

DawnSql 解决 SAAS 的痛点

作者:陈飞
  • 2023-02-02
    四川
  • 本文字数:5314 字

    阅读完需:约 17 分钟

SAAS 系统的痛点

1、大客户定制化程度高

2、客户对自身数据安全的担忧,如何防止数据的泄露也滥用

DawnSql 的解决方案

众所周知,软件 = 程序 + 数据。


  1. 如果客户的数据需要上传到 SAAS 厂商的服务器,那么 SAAS 厂商只需要对相应的数据设置用户组,并对这个用户组设置相应的权限,就可以将该用户组的权限,发给客户,客户就可以根据自己的实际需求来修改、扩展相应的功能!

  2. 客户对自身数据安全的担忧。客户只需要将自己的数据根据 SAAS 厂商提供的表格式部署到 DawnSql 中,同时设置好用户组权限,SAAS 厂商就可以使用这个用户组来访问数据,用户直接使用 SAAS 厂商提供的服务即可。

DawnSql 例子

所有的例子来自于,NorthWind 实例数据库。

1、设置配置文件

1.1、设置 consistentId,如果是集群的话,每个节点的 consistentId 应该是不一样,这个属性可以不设置。(不过我们建议设置)

<property name="consistentId" value="dawn_node"></property>
复制代码

1.2、设置超级管理员的 root token

 <!-- 超级管理员的 root token, 用户可以直接来设置一个 root token --> <!-- 本例中 root token 为 dafu --><property name="root_token" value="dafu"/>
复制代码

1.3、用户是否实现了 log 事务接口。默认是没有实现,这个需要用户根据自己的实际需求来实现。

<!-- 设置实现 log 事务接口的类 --><!--<property name="myLogCls" value="org.gridgain.smart.logClient.MyLogTransactionClient"/>-->
复制代码

1.4、是否实现了初始化后就执行的方法,默认是没有实现

<!-- 设置启动的时候,初始化 rpc 服务器 --><!-- org.dawn.rpc.MyRpcStartImpl 是实现了 IDawnSqlStart 接口的类 --><!-- 不设置则不启动这个服务,具体代码可以参看开源的例子 --><!--<property name="startAppCls" value="org.dawn.rpc.MyRpcStartImpl"/>-->
复制代码

1.5、创建表的模板 (这个是必须要设置的)

例子中设置了两个模板:base 模板:复制模式,支持事务 manage 模板:分区模式,同一份数据,在集群中备份 3 次,支持事务


<!-- 创建表的模板 --><property name="templateConfiguration">    <map key-type="java.lang.String" value-type="org.apache.ignite.configuration.TableTemplateConfiguration">        <entry key="base">            <bean class="org.apache.ignite.configuration.TableTemplateConfiguration">                <property name="templateValue" value="template=REPLICATED,ATOMICITY=TRANSACTIONAL"></property>                <property name="description" value="复制模式,来保存数据!"></property>            </bean>        </entry>        <entry key="manage">            <bean class="org.apache.ignite.configuration.TableTemplateConfiguration">                <property name="templateValue" value="template=partitioned,backups=3,ATOMICITY=TRANSACTIONAL"></property>                <property name="description" value="分片模式,来保存数据!"></property>            </bean>        </entry>    </map></property>
复制代码

2、创建表

-- 1、产品类型表CREATE TABLE IF NOT EXISTS public.Categories (     -- 产品类型ID    CategoryID INTEGER NOT NULL auto,    -- 产品类型名    CategoryName VARCHAR(15) NOT NULL,    -- 类型说明    Description VARCHAR,    -- 产品样本    Picture VARCHAR,    PRIMARY KEY (CategoryID)) WITH "template=manage";
-- 2、 顾客信息表CREATE TABLE IF NOT EXISTS public.Customers ( -- 客户ID CustomerID VARCHAR(5) NOT NULL, -- 所在公司名称 CompanyName VARCHAR(40) NOT NULL, -- 客户姓名 ContactName VARCHAR(30), -- 客户头衔 ContactTitle VARCHAR(30), -- 联系地址 Address VARCHAR(60), -- 所在城市 City VARCHAR(15), -- 所在地区 Region VARCHAR(15), -- 邮编 PostalCode VARCHAR(10), -- 国家 Country VARCHAR(15), -- 电话 Phone VARCHAR(24), -- 传真 Fax VARCHAR(24), PRIMARY KEY (CustomerID)) WITH "template=manage";
-- 3、 产品类别表CREATE TABLE IF NOT EXISTS public.Products ( -- 产品ID ProductID INTEGER NOT NULL, -- 产品名称 ProductName VARCHAR(40) NOT NULL, -- 供应商ID SupplierID INTEGER, -- 类型ID CategoryID INTEGER, -- 数量 QuantityPerUnit VARCHAR(20), -- 单价 UnitPrice DECIMAL(10,4) DEFAULT 0, -- 库存数量 UnitsInStock SMALLINT(2) DEFAULT 0, -- 订购量 UnitsOnOrder SMALLINT(2) DEFAULT 0, -- 再次订购量 ReorderLevel SMALLINT(2) DEFAULT 0, -- 中止 Discontinued BIT NOT NULL DEFAULT 0, PRIMARY KEY (ProductID)) WITH "template=manage";
-- 4、 运货商CREATE TABLE IF NOT EXISTS Shippers ( -- 运货商ID ShipperID INTEGER NOT NULL auto, -- 公司名称 CompanyName VARCHAR(40) NOT NULL, -- 联系电话 Phone VARCHAR(24), PRIMARY KEY (ShipperID)) WITH "template=manage";
-- 5、 供应商表 CREATE TABLE IF NOT EXISTS Suppliers ( -- 地区描述 SupplierID INTEGER NOT NULL, -- 供应商姓名 CompanyName VARCHAR(40) NOT NULL, -- 联系人 ContactName VARCHAR(30), -- 联系人职务 ContactTitle VARCHAR(30), -- 地址 Address VARCHAR(60), -- 城市 City VARCHAR(15), -- 销售大区域 Region VARCHAR(15), -- 邮政编码 PostalCode VARCHAR(10), -- 国家 Country VARCHAR(15), -- 联系电话 Phone VARCHAR(24), -- 传真 Fax VARCHAR(24), -- 首页 HomePage VARCHAR, PRIMARY KEY (SupplierID)) WITH "template=manage";
-- 6、 雇员表,存放员工的一些基本信息CREATE TABLE IF NOT EXISTS Employees ( -- 员工编号 EmployeeID INTEGER NOT NULL, -- 员工姓 LastName VARCHAR(20) NOT NULL, -- 员工名 FirstName VARCHAR(10) NOT NULL, -- 头衔 Title VARCHAR(30), -- 尊称 TitleOfCourtesy VARCHAR(25), -- 出生日期 BirthDate DATETIME, -- 雇用日期 HireDate DATETIME, -- 家庭地址 Address VARCHAR(60), -- 所在城市 City VARCHAR(15), -- 所在地区 Region VARCHAR(15), -- 邮编 PostalCode VARCHAR(10), -- 国家 Country VARCHAR(15), -- 住宅电话 HomePhone VARCHAR(24), -- 分机 Extension VARCHAR(4), -- 照片 Photo VARCHAR, -- 备注 Notes VARCHAR NOT NULL, -- 上级 ReportsTo VARCHAR, -- 照片路径 PhotoPath VARCHAR(255), -- 工资 Salary FLOAT, PRIMARY KEY (EmployeeID)) WITH "template=manage";
-- 7、 雇员销售区域表CREATE TABLE EmployeeTerritories ( -- ID ID INTEGER NOT NULL auto, -- 员工编号 EmployeeID INTEGER NOT NULL, -- 区域代号 TerritoryID VARCHAR(20) NOT NULL, PRIMARY KEY (ID)) WITH "template=manage";
-- 8、 销售小区域表CREATE TABLE Territories ( -- 地域编号 TerritoryID VARCHAR(20) NOT NULL, -- 地域描述 TerritoryDescription VARCHAR(50) NOT NULL, -- 地区编号 RegionID INTEGER NOT NULL, PRIMARY KEY (TerritoryID)) WITH "template=manage";
-- 9、 订单详情表CREATE TABLE OrderDetails ( -- 订单编号 OrderID INTEGER NOT NULL, -- 产品编号 ProductID INTEGER NOT NULL, -- 单价 UnitPrice DECIMAL(10,4) DEFAULT 0, -- 订购数量 Quantity SMALLINT(2) DEFAULT 1, -- 折扣 Discount REAL(8,0) NOT NULL, PRIMARY KEY (OrderID, ProductID)) WITH "template=manage";
-- 10、 订单表CREATE TABLE IF NOT EXISTS Orders ( -- 订单编号 OrderID INTEGER NOT NULL, -- 客户编号 CustomerID VARCHAR(5), -- 员工编号 EmployeeID INTEGER, -- 订购日期 OrderDate DATETIME, -- 预计到达日期 RequiredDate DATETIME, -- 发货日期 ShippedDate DATETIME, -- 运货商 ShipVia INTEGER, -- 运费 Freight DECIMAL(10,4) DEFAULT 0, -- 货主姓名 ShipName VARCHAR(40), -- 货主地址 ShipAddress VARCHAR(60), -- 货主所在城市 ShipCity VARCHAR(15), -- 货主所在地区 ShipRegion VARCHAR(15), -- 货主邮编 ShipPostalCode VARCHAR(10), -- 货主所在国家 ShipCountry VARCHAR(15), PRIMARY KEY (OrderID)) WITH "template=manage";
复制代码

3、导入数据

在 DawnSql 中导入数据有两种方式。


  1. 通过 JDBC 来 insert 来导入数据。例如:由于要插入的数据比较多,所以这里只做实例,具体的数据,我们放在文档后面的下载链接中。


INSERT INTO Categories (CategoryName, Description, Picture) VALUES('Beverages','Soft drinks, coffees, teas, beers, and ales', '');INSERT INTO Categories (CategoryName, Description, Picture) VALUES('Condiments','Sweet and savory sauces, relishes, spreads, and seasonings', '');
复制代码


用 JDBC 导入


        Class.forName("org.apache.ignite.IgniteJdbcDriver");        String url = "jdbc:ignite:thin://127.0.0.1:10800/public?lazy=true&userToken=dafu";        Connection conn = DriverManager.getConnection(url);        Statement stmt = conn.createStatement();        stmt.executeUpdate("SET STREAMING ON; INSERT INTO public.Categories (CategoryName, Description, Picture) VALUES('Seafood','草鱼', ''), ('"+ CategoryName +"', '"+ Description +"', '"+ Picture +"')");
stmt.close(); conn.close();
复制代码


  1. 通过 JDBC 批量导入数据。


-- 批量导入SET STREAMING ON;INSERT INTO public.Categories (CategoryName, Description, Picture) VALUES('Seafood','草鱼', ''), ('吴大富','金毛', '');
-- 或者SET STREAMING ON;INSERT INTO public.Categories (CategoryName, Description, Picture) VALUES ('Seafood','草鱼', '');INSERT INTO public.Categories (CategoryName, Description, Picture) VALUES ('吴大富','金毛', '');
复制代码


  1. 快速批量导入。这种方法可以绕开 SQL 解析,直接将数据存入集群。但是这种方法需要对 Dawn Sql 比较了解且具备一定的编程能力。如果想了解这种方法请联系作者。

4、添加 schema

-- 添加 schema 名字为 myycreate schema myy;-- 或者create SCHEMA IF NOT EXISTS myy;
复制代码

5、添加用户组

-- 添加用户组add_user_group('myy_group', 'myy_token', 'all', 'myy');-- 通过 user_token 获取用户组get_user_group('myy_token');
复制代码

6、为用户组设置权限

为 myy_group 设置用户权限。1、


-- 对用户组 myy_group 设置访问  public.Employees 表的权限,让它只能查询-- EMPLOYEEID < 6 的数据my_view('myy_group', "SELECT * from public.Employees where EMPLOYEEID < 6");
复制代码

7、添加方法

-- 统计只出过一单的员工数量function get_emp_count(){    let rs = query_sql("SELECT COUNT(DISTINCT o.EmployeeID)                        FROM public.Orders o                        LEFT JOIN public.Employees e  ON o.EmployeeID=e.EmployeeID");    rs.next().FIRST();}
-- 查询只卖过一件商品SELECT p.ProductName,COUNT(DISTINCT wo.EmployeeID) FROM public.Orders wo JOIN public.Employees e ON wo.EmployeeID=e.EmployeeID JOIN public.OrderDetails od ON wo.OrderID=od.OrderID JOIN public.Products p ON od.ProductID=p.ProductID GROUP BY p.ProductName HAVING COUNT(DISTINCT wo.EmployeeID) = get_emp_count();
复制代码

8、用 NoSql 来描述业务流程或提升程序性能

8.1、在 to B 的系统中业务的流程和规则往往特别的复杂,业务变动大,时效性要求高

例如:在保险中,代理人的组织结构是金字塔型的,佣金项几十个,不同的产品有不同的佣金比例,代理人级别不同也有所不同。可以将代理人的 em_no 作为主键,将代理的上下级、保单、佣金项作为数据,形成一个树形结构。当保单改变,或者上下级变化时候,动态修改该树。当需要计算佣金的时候,只需要扫描这棵树的佣金项即可。

8.2、在需要对海量数据高并发读写的场景下

具体用法:NoSql 的支持

9、DawnSql 的 root 用户可以自己扩展方法

具体方法:自定义扩展方法


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

陈飞

关注

还未添加个人签名 2020-02-13 加入

还未添加个人简介

评论

发布
暂无评论
DawnSql解决SAAS的痛点_陈飞_InfoQ写作社区