【项目升级】单库、多库、读写分离 · 任你选
本期配套视频:
https://www.bilibili.com/video/BV1BJ411B7mn?p=6
(点击阅读原文,可看,如果没有,最晚下午可看)
继上周增加【任务调度】以后,继续对项目进行2.0版本升级,其实改动的地方并不多,主要的功能上,更丰富了,之前其实项目已经实现了多库的更新:
单单多库操作还不够完美,所以这几天就把读写分离给加上了,你可能会好奇,多库不就是读写分离么?主库和从库相互不影响的操作,满足xxxx的需求等等,其实不是的,至少在我这里两者不是一回事,下面我就简单的文字说一下,如果读不懂,或者不想读,可以直接看视频。
Github:相关代码目前在Is4分支。
单库模式就不说了,我们所有的项目都必须至少要支持这个,不然如何持久化?
多库操作,我理解的是,可以任意操作指定的任意数据库,只要允许访问,我们配置好连接字符串,并做一定的处理后,就可以CURD了,我这里可以简化称之为——C和Q,也就是命令和查询模式,命令就是指的写入、编辑、删除的操作。这里多个数据库是平等的,举个例子,我们可以在资源服务器Blog.Core中,来操作认证中心的role角色表,不仅可以读取,如果有必要,还可以修改,当然,这里业务上是不允许修改的。
读写分离,顾名思义,就是读(Q)和写(C)的动作是分开的,虽然也是多个数据库,虽然也是分主库和从库,但是读只能读取从库,写只能写在主库,这就是和普通的多库操作最大的也是最本质的不同之处。
简单解释过后,那我就说一下,Blog.Core项目中,如果实现单库模式、多库模式以及读写分离模式。
这个很简单,当你第一次下载的时候,默认的就是单库模式:
MutiDBEnabled和CQRSEnabled都为false,所以如果你就只想连接一个数据库,那就把MainDB配置成下边对应的ConnId,然后把他对应Enabled设置为true就行了,其他的不用管,其他的就算设置为true,也不会影响。
举个例子,我只想配置一个SqlServer,连接字符串为xxxxxx:
"MainDB": "WMBLOG_MSSQL_1", //当前项目的主库,所对应的连接字符串的Enabled必须为true
"MutiDBEnabled": false, //是否开启多库模式
"CQRSEnabled": false, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
"DBS": [
{
"ConnId": "WMBLOG_SQLITE",
"DBType": 2,
"Enabled": false,
"HitRate": 50, // 值越大,优先级越高
"Connection": "WMBlog.db" //只写数据库名就行,我会拼接字符串
},
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
{
"ConnId": "WMBLOG_MSSQL_1",
"DBType": 1,
"Enabled": true,
"HitRate": 40,
"Connection": "xxxxxx",
"ProviderName": "System.Data.SqlClient"
},
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
{
"ConnId": "WMBLOG_MSSQL_2",
"DBType": 1,
"Enabled": true,
"HitRate": 30,
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQ",
"ProviderName": "System.Data.SqlClient"
},
{
"ConnId": "WMBLOG_MYSQL",
"DBType": 0,
"Enabled": false,
"HitRate": 20,
"Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"
},
{
"ConnId": "WMBLOG_ORACLE",
"DBType": 3,
"Enabled": false,
"HitRate": 10,
"Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;",
"OracleConnection_other1": "User ID=sss;Password=789;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"
}
],
就是这么简单,那下边简单说一下,如何配置多库。
这个可能稍微麻烦一丢丢,我就直接写步骤了:
1、配置MainDB —— 主库Id;
2、配置MutiDBEnabled —— true,开启多库模式;
3、配置DBS —— 将需要用到的数据库节点,Enabled=true;
4、在指定的实体类上边增加特性,指定对应的从库的连接Id;
举例说明,我想配置一个多库操作,主库是Sqlite,从库是Sqlserver:
"MainDB": "WMBLOG_SQLITE", //当前项目的主库,所对应的连接字符串的Enabled必须为true
"MutiDBEnabled": true, //是否开启多库模式
"CQRSEnabled": false, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
"DBS": [
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
{
"ConnId": "WMBLOG_SQLITE",
"DBType": 2,
"Enabled": true,// 主库
"HitRate": 50, // 值越大,优先级越高
"Connection": "WMBlog.db" //只写数据库名就行,我会拼接字符串
},
{
"ConnId": "WMBLOG_MSSQL_1",
"DBType": 1,
"Enabled": true,// 从库
"HitRate": 40,
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_1;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
"ProviderName": "System.Data.SqlClient"
},
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
{
"ConnId": "WMBLOG_MYSQL",
"DBType": 0,
"Enabled": false,// 不开启
"HitRate": 20,
"Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"
},
{
"ConnId": "WMBLOG_ORACLE",
"DBType": 3,
"Enabled": false,// 不开启
"HitRate": 10,
"Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;",
"OracleConnection_other1": "User ID=sss;Password=789;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"
}
],
这样配置好后,我们的主库就是WMBLOG_SQLITE,一个从库是WMBLOG_MSSQL_1
然后配置下对应的实体类特性,指定这个表是从库的表:
然后我们可以看看,系统启动后,是怎么样的:
从启动日志上,我们可以看出来,已经实现了我们的目的。
这个读写分离模式,其实和多库模式差不多,只不过更简单了:
1、配置MainDB —— 主库Id;
2、配置CQRSEnabled —— true,开启读写分离模式,必须是单库;
3、配置DBS —— 将需要用到的数据库节点,Enabled=true;
举个例子,我想开启主库为WMBLOG_MSSQL_1,从库为WMBLOG_MSSQL_2:
"MainDB": "WMBLOG_MSSQL_1", //当前项目的主库,所对应的连接字符串的Enabled必须为true
"MutiDBEnabled": false, //是否开启多库模式
"CQRSEnabled": true, //是否开启读写分离模式,必须是单库模式,且数据库类型一致,比如都是SqlServer
"DBS": [
{
"ConnId": "WMBLOG_SQLITE",
"DBType": 2,
"Enabled": false,
"HitRate": 50, // 值越大,优先级越高
"Connection": "WMBlog.db" //只写数据库名就行,我会拼接字符串
},
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
{
"ConnId": "WMBLOG_MSSQL_1",
"DBType": 1,
"Enabled": true,
"HitRate": 40,
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_1;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
"ProviderName": "System.Data.SqlClient"
},
{
"ConnId": "WMBLOG_MSSQL_2",
"DBType": 1,
"Enabled": true,
"HitRate": 30,
"Connection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WMBLOG_MSSQL_2;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
"ProviderName": "System.Data.SqlClient"
},
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
{
"ConnId": "WMBLOG_MYSQL",
"DBType": 0,
"Enabled": false,
"HitRate": 20,
"Connection": "Server=localhost; Port=3306;Stmt=; Database=wmblogdb; Uid=root; Pwd=456;"
},
{
"ConnId": "WMBLOG_ORACLE",
"DBType": 3,
"Enabled": false,
"HitRate": 10,
"Connection": "Provider=OraOLEDB.Oracle; Data Source=WMBlogDB; User Id=sss; Password=789;",
"OracleConnection_other1": "User ID=sss;Password=789;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.8.65)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = orcl)))"
}
],
这里要注意一下:
1、开启读写分离模式的话,就必须要是单库模式,把MutiDBEnabled关掉,其实不关也行,只不过后期你可能会绕不过来,干脆禁掉。
2、不用再配置实体类了。
我们来看看系统启动日志:
目前是按照完美的设想进行的,那到底数据是不是成功呢,我们做下测试。
我们执行博客数据查询,总数是41条,这是读操作,走的是从库:
然后,我们添加一条数据,这是写命令,走的是主库:
可以看到,我们新建了一个Id是54的博客,但是我们能查询出来么?
答案是否定的,因为我们的查询是从库,这也就是证明了我们的读写分离已经生效了。
好啦,今天的内容暂时就写到这里吧,详细的说明和操作都在视频里,感兴趣的可以去看看。