发表日期: 2021-03-27 15:40:03 浏览次数:390
永兴400电话申请开通【永兴企业网站建设】永兴微信公众号小程序开发运营价格、永兴微信公众号APP软件客户端设计运营、永兴网页页面设计公司费用、永兴公司网站制作方案流程改版维护大概需要多少钱
永兴县是郴州市下辖县,地处湖南省东南部、郴州市北陲,东邻资兴市,南连苏仙区,西靠桂阳县,北接安仁县及衡阳市耒阳,辖10镇4乡2街道办事处,总人口71.1万人(常住54.4万人),是郴州市人口第二大县,国家“城市矿产”示范基地。 [1]
地域狭长貌似蚕形,东西长90公里,南北宽56公里。全县土地总面积为1979.4平方公里,占湖南省土地总面积的0.93%,东部多山,西部以丘陵为主,中部丘岗平原间布,京广铁路、京珠高速公路、国道G107、省道S212纵横境内,耒水上游的便江四季通航。
2020年7月,全国爱卫会决定命名永兴县为2017-2019周期国家卫生县城。
为了应对海量用户的产品愿景需求,PhalApi设计了一个分布式的数据库存储方案,以便能满足数据量的骤增、云服务的横向扩展、接口服务开发的兼容性,以及数据迁移等问题,避免日后因为全部数据都存放在单台服务器而导致的限制。
分表策略,即是通过可配置的路由规则,将海量的数据分散存储在多个数据库表。主要涉及的内容有:
分库分表
对于不需要进行必要关联查询的数据库表,进行分库分表存放。即对于同一张数据库表,若存放的数据量是可预见式的暴增,例如每时每刻都会产生大量的来自用户发布的事件信息,为了突破 数据库单表的限制以及其他问题,需要将此数据库表创建多个副本,并按照一定规则进行拆分存放。
路由规则
在进行了分库分表后,开发人员在对数据库表进行操作时,就需要根据相应的规则找到对应的数据库和数据库表,即需要有一个参考主键。这里建议每个表都需要有数值类型的主键字段,以便作为分表的参考。
扩展字段
在完成了分库分表和制定路由规则后,考虑到日后有新增表字段而导致数据库表结构的变更。为了减少数据库变更对现有数据库表的影响,这里建议每个表都增加text类型的extra_data字段,并且使用JSON格式进行序列化转换存储。
可配置
在有了多台数据库服务器以及每个表都拆分成多张表后,为减少后端接口开发人员的压力,有必须提供可配置的支持。即:数据库的变更不应影响开发人员现有的开发,也不需要开发人员作出代码层面的改动,只需要稍微配置一下即可。
自动生成SQL语句
对于相同表的建表语句,可以通过脚本来自动生成,然后直接导入数据即可,避免人工重复编辑维护SQL建表语句。
PhalApi框架主要提供了表名 + ID与数据库服务器 + 数据库表之间的映射规则。
下面结合一个示例,讲解如何使用分表策略。假设我们有一个需要数据库分表的demo表,且各个表所映射的数据库实例如下。
表2-17 demo分表示例
数据库表 | 数据库实例 |
---|---|
tbl_demo | db_demo |
tbl_demo_0 | db_demo |
tbl_demo_1 | db_demo |
tbl_demo_2 | db_demo |
首先,需要配置数据库的路由规则。这里的demo表存储比较简单,即有3张分表tbl_demo_0、tbl_demo_1、tbl_demo_2,缺省主表tbl_demo是必要的,当分表不存在时将会使用该缺省主表。数据库的路由规则在前面所说的数据库配置文件./Config/dbs.php中,其中tables为数据库表的配置信息以及与数据库实例的映射关系。因此可以在tables选项中添加此demo表的相关配置。
return array( ... ... 'tables' => array( 'demo' => array( 'prefix' => 'tbl_', 'key' => 'id', 'map' => array( array('db' => 'db_demo'), array('start' => 0, 'end' => 2, 'db' => 'db_demo'), ), ), ),);复制代码
上面配置map选项中array('db' => 'db_demo')
用于指定缺省主表使用db_demo数据库实例,而下一组映射关系则是用于配置连续在同一台数据库实例的分表区间,即tbl_demo_0、tbl_demo_1、tbl_demo_2都使用了db_demo数据库实例。
这里再侧重讲解一下map选项。map选项用于配置数据库表与数据库实例之前的映射关系,通俗来说就是指定哪张表使用哪个数据库。不管是否使用分表存储,都至少需要配置默认缺省主表。如:
'map' => array( array('db' => 'db_demo'),)复制代码
缺省主表的配置很简单,只需要配置使用哪个数据库实例即可。而当需要使用分表时,则要增加相应的映射关系配置。通常分表以“下划线 + 连续的自然数”为后缀,作为分表的标识。在配置时,对于使用同一个数据库实例的分表区间,可以配置成一组,并使用start下标和end下标来指定分表闭区间:[start, end]。如上面示例中,[0, 2]这一区间的分表使用了db_demo这一数据库实例,则可以添加配置成:
'map' => array( array('db' => 'db_demo'), array('start' => 0, 'end' => 2, 'db' => 'db_demo'),)复制代码
假设,对于tbl_demo_2分表,需要调整成使用数据库实例db_new,则可能调整配置成:
'map' => array( array('db' => 'db_demo'), array('start' => 0, 'end' => 1, 'db' => 'db_demo'), array('start' => 2, 'end' => 2, 'db' => 'db_new'),)复制代码
配置好路由规则后,就可以使用脚本命令生成建表语句。把数据库表的基本建表语句保存到./Data目录下,文件名与数据库表名相同,后缀统一为“.sql”。如这里的./Data/demo.sql文件。
`name` varchar(11) DEFAULT NULL,复制代码
需要注意的是,这里说的基本建表语句是指:仅是这个表所特有的字段,排除已固定公共有的自增主键id、扩展字段ext_data和CREATE TABLE关键字等。
然后可以使用phalapi-buildsqls脚本命令,快速自动生成demo缺省主表和全部分表的建表SQL语句。如下:
$ ./PhalApi/phalapi-buildsqls ./Config/dbs.php demo复制代码
正常情况下,会生成类似以下的SQL语句:
CREATE TABLE `demo` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(11) DEFAULT NULL, `ext_data` text COMMENT 'json data here', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `tpl_demo_0` ... ...;CREATE TABLE `tpl_demo_1` ... ...;CREATE TABLE `tpl_demo_2` ... ...;复制代码
在将上面的SQL语句导入数据库后,或者手动创建数据库表后,便可以像之前那样操作数据库了。下面是一些大家已经熟悉的示例:
DI()->notorm->demo->where('id', '1')->fetch();复制代码
假设分别的规则是根据ID对3进行求余。当需要使用分表时,在使用Model基类的情况下,可以通过重写PhalApi_Model_NotORM::getTableName($id)
实现相应的分表规则。
// $ vim ./Shop/Model/demo.php<?phpclass Model_Demo extends PhalApi_Model_NotORM { protected function getTableName($id) { $tableName = 'demo'; if ($id !== null) { $tableName .= '_' . ($id % 3); } return $tableName; }}复制代码
然后,便可使用之前一样的CURD基本操作,但框架会自动匹配分表的映射。例如:
$model = new Model_Demo();$row = $model->get('3', 'id'); // 使用分表tbl_demo_0$row = $model->get('10', 'id'); // 使用分表tbl_demo_1$row = $model->get('2', 'id'); // 使用分表tbl_demo_2复制代码
当使用全局方式获取NotORM实例时,则需要手动指定分表。上面的操作等效于下面使用全局NotORM实例并指定分表的实现。
$row = DI()->notorm->demo_0->where('id', '3')->fetch();$row = DI()->notorm->demo_1->where('id', '10')->fetch();$row = DI()->notorm->demo_2->where('id', '2')->fetch();复制代码
回到使用Model基类的上下文,更进一步,我们可以通过$this->getORM($id)
来获取分表的实例从而进行分表的操作。如:
<?phpclass Model_Demo extends PhalApi_Model_NotORM { ... ... public function getNameById($id) { $row = $this->getORM($id)->select('name')->fetchRow(); return !empty($row) ? $row['name'] : ''; }}复制代码
通过传入不同的$id,即可获取相应的分表实例。
当需要使用多个数据库时,可以先在servers选项配置多组数据库实例,然后在tables选项中为不同的数据库表指定不同的数据库实例。
假设我们有两台数据库服务器,分别叫做db_A、db_B,即:
return array( 'servers' => array( 'db_A' => array( //db_A 'host' => '192.168.0.1', //数据库域名 ... ... ), 'db_B' => array( //db_B 'host' => '192.168.0.2', //数据库域名 ... ... ), ),复制代码
若db_A服务器中的数据库有表a_table_user、a_table_friends,而db_B服务器中的数据库有表b_table_article、b_table_comments,则:
<?phpreturn array( ... ... 'tables' => array( //通用路由 '__default__' => array( 'prefix' => 'a_', //以 a_ 为表前缀 'key' => 'id', 'map' => array( array('db' => 'db_A'), //默认,使用db_A数据库 ), ), 'table_article' => array( //表b_table_article 'prefix' => 'b_', //表名前缀 'key' => 'id', //表主键名 'map' => array( //表路由配置 array('db' => 'db_B'), // b_table_article表使用db_B数据库 ), ), 'table_comments' => array( //表b_table_article 'prefix' => 'b_', //表名前缀 'key' => 'id', //表主键名 'map' => array( //表路由配置 array('db' => 'db_B'), // b_table_comments表使用db_B数据库 ), ), ),复制代码
如果项目存在分表的情况,可结合上述的分表的说明再进行配置。为了让大家更容易明白,假设db_A服务器中的数据库有表a_table_user、a_table_friends_0到a_table_friends_9(共10张表),而db_B服务器中的数据库有表b_table_article、b_table_comments_0到b_table_comments_19(共20张表),则结合起来的完整配置为:
<?phpreturn array( ... ... 'tables' => array( //通用路由 '__default__' => array( 'prefix' => 'a_', //以 a_ 为表前缀 'key' => 'id', 'map' => array( array('db' => 'db_A'), //默认,使用db_A数据库 ), ), 'table_friends' => array( //分表配置 'prefix' => 'a_', //表名前缀 'key' => 'id', //表主键名 'map' => array( //表路由配置 array('db' => 'db_A'), // b_table_comments表使用db_B数据库 array('start' => 0, 'end' => 9, 'db' => 'db_A'), //分表配置(共10张表) ), ), 'table_article' => array( //表b_table_article 'prefix' => 'b_', //表名前缀 'key' => 'id', //表主键名 'map' => array( //表路由配置 array('db' => 'db_B'), // b_table_article表使用db_B数据库 ), ), 'table_comments' => array( //表b_table_article 'prefix' => 'b_', //表名前缀 'key' => 'id', //表主键名 'map' => array( //表路由配置 array('db' => 'db_B'), // b_table_comments表使用db_B数据库 array('start' => 0, 'end' => 19, 'db' => 'db_B'), //分表配置(共20张表) ), ), ),);复制代码
通过这样简单配置,即可完成对多个数据库的配置,其他代码层面上对数据库的操作保持不变。
永兴400电话申请开通【永兴企业网站建设】永兴微信公众号小程序开发运营价格、永兴微信公众号APP软件客户端设计运营、永兴网页页面设计公司费用、永兴公司网站制作方案流程改版维护大概需要多少钱
备案号: 苏ICP备11067224号
CopyRight © 2011 书生商友信息科技 All Right Reserved
24小时服务热线:400-111-6878 E-MAIL:1120768800@qq.com QQ:1120768800
网址: https://www.768800.com 网站建设:上往建站
关键词: 网站建设| 域名邮箱| 服务器空间| 网站推广| 上往建站| 网站制作| 网站设计| 域名注册| 网络营销| 网站维护|
企业邮箱| 虚拟主机| 网络建站| 网站服务| 网页设计| 网店美工设计| 网站定制| 企业建站| 网站设计制作| 网页制作公司|
400电话办理| 书生商友软件| 葬花网| 调温纤维| 海洋馆运营维护| 北京保安公司| 殡仪馆服务| 殡葬服务| 昌平殡葬| 朝阳殡葬|
欢迎您免费咨询,请填写以下信息,我们收到后会尽快与您联系
服务热线:400-111-6878