ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

*MySql常用函数总结及Sharding分库分表**

2021-11-12 16:34:43  阅读:164  来源: 互联网

标签:分库 shardingsphere MySql sharding 分片 Sharding table id SELECT


一、单行函数

一、字符函数

1. length 获取参数值的字节个数
SELECT LENGTH('john');
SELECT LENGTH('张三丰hahaha');
SHOW VARIABLES LIKE '%char%'
2. concat 拼接字符串
SELECT CONCAT(last_name,'_',first_name) 姓名 FROM employees;
3. upper、lower
SELECT UPPER('john');
SELECT LOWER('joHn');
 示例:将姓变大写,名变小写,然后拼接
SELECT CONCAT(UPPER(last_name),LOWER(first_name))  姓名 FROM employees;
4. substr、substring
注意:索引从1开始
 截取从指定索引处后面所有字符
SELECT SUBSTR('李莫愁爱上了陆展元',7)  out_put;

 截取从指定索引处指定字符长度的字符
SELECT SUBSTR('李莫愁爱上了陆展元',1,3) out_put;


 案例:姓名中首字符大写,其他字符小写然后用_拼接,显示出来

SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2)))  out_put
FROM employees;
5. instr 返回子串第一次出现的索引,如果找不到返回0
SELECT INSTR('杨不殷六侠悔爱上了殷六侠','殷八侠') AS out_put;
6. trim
SELECT LENGTH(TRIM('    张翠山    ')) AS out_put;

SELECT TRIM('aa' FROM 'aaaaaaaaa张aaaaaaaaaaaa翠山aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')  AS out_put;
7. lpad 用指定的字符实现左填充指定长度
SELECT LPAD('殷素素',2,'*') AS out_put;
8. rpad 用指定的字符实现右填充指定长度
SELECT RPAD('殷素素',12,'ab') AS out_put;
9. replace 替换
SELECT REPLACE('周芷若周芷若周芷若周芷若张无忌爱上了周芷若','周芷若','赵敏') AS out_put;
//替换某个字段里面的某个字符
update 表名 set 字段名=REPLACE (字段名,'原来的值','要修改的值')

二、数学函数

1.round 四舍五入
SELECT ROUND(-1.55);
SELECT ROUND(1.567,2);
2.ceil 向上取整,返回>=该参数的最小整数
SELECT CEIL(-1.02);
3.floor 向下取整,返回<=该参数的最大整数
SELECT FLOOR(-9.99);
4.truncate 截断
SELECT TRUNCATE(1.69999,1);
5.mod取余
/*
mod(a,b) :  a-a/b*b

mod(-10,-3):-10- (-10)/(-3)*(-3)=-1
*/
SELECT MOD(10,-3);
SELECT 10%3;

三、日期函数

1.now 返回当前系统日期+时间
SELECT NOW();
2.curdate 返回当前系统日期,不包含时间
SELECT CURDATE();
3.curtime 返回当前时间,不包含日期
SELECT CURTIME();
4.可以获取指定的部分,年、月、日、小时、分钟、秒
SELECT YEAR(NOW()) 年;
SELECT YEAR('1998-1-1') 年;
SELECT  YEAR(hiredate) 年 FROM employees;
SELECT MONTH(NOW()) 月;
SELECT MONTHNAME(NOW()) 月;
5.str_to_date 将字符通过指定的格式转换成日期
SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS out_put;
查询入职日期为1992--4-3的员工信息
SELECT * FROM employees WHERE hiredate = '1992-4-3';
SELECT * FROM employees WHERE hiredate = STR_TO_DATE('4-3 1992','%c-%d %Y');
6.date_format 将日期转换成字符
SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS out_put;
查询有奖金的员工名和入职日期(xx月/xx日 xx年)
SELECT last_name,DATE_FORMAT(hiredate,'%m月/%d日 %y年') 入职日期
FROM employees
WHERE commission_pct IS NOT NULL;

四、其他函数

SELECT VERSION();
SELECT DATABASE();
SELECT USER();

五、流程控制函数

1.if函数: if else 的效果

SELECT IF(10<5,‘大’,‘小’);

SELECT last_name,commission_pct,IF(commission_pct IS NULL,‘没奖金,呵呵’,‘有奖金,嘻嘻’) 备注
FROM employees;

连接查询

一、内链接

select * from tabale_a a inner join table_b b on a.id=b.id;

组合两个表中的记录,返回关联字段相符的记录,也就是返回两个表的交集(阴影)部分

img

二、左(外)连接

select * from table_a a left join table_b b on a.id = b.id;
--有点类似于子查询(在特定情况下)

left join 是left outer join的简写,它的全称是左外连接,是外连接中的一种。 左(外)连接,左表(a_table)的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。

img

三、右(外)连接

select * from table_a a right join table_b b on a.id = b.id

right join是right outer join的简写,它的全称是右外连接,是外连接中的一种。与左(外)连接相反,右(外)连接,左表(a_table)只会显示符合搜索条件的记录,而右表(b_table)的记录将会全部表示出来。左表记录不足的地方均为NULL。

img

四、全(外)连接 注:MySQL中不支持

select * from table_a a full join table_b b on a.id = b.id

左右两个表的记录都会显示出来。没有匹配字段的值用null填充但是注意:mysql是没有全外连接的(mysql中没有full outer join关键字),想要达到全外连接的效果,可以使用union关键字连接左外连接和右外连接。例如:

 select e.empName,d.deptName
      FROM t_employee e 
     left JOIN t_dept d
      ON e.dept = d.id
 UNION
 select e.empName,d.deptName
      FROM t_employee e 
      RIGHT JOIN t_dept d
      ON e.dept = d.id;

五、交叉连接

select * from table_a a cross join table_b;
--相当于92中的
select * from table_a a ,table_b b ;

取的笛卡尔积。感觉没什么实际意义

六、联合查询(union(union all))

select * from a,b,c from table_a where....
union
select * from a,b,c from table_b where ...
union
.....

当查询的结果来自于多个表,每个表之间又没有直接的关联时,就可以使用联合查询。

注:

  1. 多条查询语句的查询列数必须一致;
  2. 多条查询语句的每一列的自段类型和顺序必须一致;
  3. union默认去掉重复的记录,union all 不会去重。为保证效率,常用union all

常见知识点

  1. truncate [table] table_name;--清空表中的数据;比delete效率要高;
    

    delete和truncate的区别

    img

    高水位重置

    随着不断地进行表记录的DML操作,会不断提高表的高水位线(HWM),DELETE操作之后虽然表的数据删除了,但是并没有降低表的高水位,随着DML操作数据库容量也只会上升,不会下降。所以如果使用DELETE,就算将表中的数据减少了很多,在查询时还是很和DELETE操作前速度一样。而TRUNCATE操作会重置高水位线,数据库容量也会被重置,之后再进行DML操作速度也会有提升。

    例如:假如某一列是自增长的。用delete删除后再增加数据会从以前的断点开始。而用truncate删除后会从1重新开始计数;

分库分表(sharding -jdbc)

一、配置文件

#配置数据源
spring.shardingsphere.datasource.names= m1,m2..#每一个数据源代表一个数据库
#分别对每一个数据源进行配置.以下仅以m1为例,其他的配置都以此为例
spring.shardingsphere.datasource.m1.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name = com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url = jdbc:mysql://172.168.0.78:3306/tlms_test?useUnicode=true
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = root


# 默认分库策略,以id为分片键,分片策略为id % 2 + 1,也就是store_info_id为双数的
#数据进入m1,为单数的进入m2
spring.shardingsphere.sharding.default‐database‐strategy.inline.sharding‐column = id
spring.shardingsphere.sharding.default‐database‐strategy.inline.algorithm‐expression = m$‐>
{store_info_id % 2 + 1}


#指定表的数据分布情况,配置数据节点,以单库m1为例
#表示真实的表名为test_1,test_2;这两个
spring.shardingsphere.sharding.tables.test.actual-data-nodes=m1.test_$->{1..2} 

#指定主键生成策略为SNOWFLAKE,防止主键重复,数据库主键类型应为bigint,不能设置自增长
spring.shardingsphere.sharding.tables.test.key-generator.column=id
spring.shardingsphere.sharding.tables.test.key-generator.type= SNOWFLAKE

#指定表的分片策略,包括分片键和分片算法(行表达式分片策略)
spring.shardingsphere.sharding.tables.test.table-strategy.inline.sharding-column = id #分片建
spring.shardingsphere.sharding.tables.test.table-strategy.inline.algorithm-expression = test_$->{id%2+1} #分片策略(相当于分片算法)

二、分片策略

包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。目前提供5种分片策略

  • 标准分片策略

对应StandardShardingStrategy。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

  • 复合分片策略

对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

  • 行表达式分片策略

对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0t_user_7

  • Hint分片策略

对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略。

  • 不分片策略

对应NoneShardingStrategy。不分片的策略。

2.1分片键

用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片。

2.2分片算法

  • 精确分片算法

对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。

  • 范围分片算法

对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景。需要配合StandardShardingStrategy使用。

  • 复合分片算法

对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。

  • Hint分片算法

对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。

2.3代码示例

以下拿标准分片策略(StandardShardingStrategy),精确分片算法举例

2.3.1 配置文件中配置标准分片策略
#指定表的数据分布情况,配置数据节点  根据季节将表分为四个
spring.shardingsphere.sharding.tables.testbydate.actual-data-nodes=m1.testbydate_20210$->{1..4}

#指定主键生成策略为SNOWFLAKE
spring.shardingsphere.sharding.tables.testbydate.key-generator.column=id
spring.shardingsphere.sharding.tables.testbydate.key-generator.type= SNOWFLAKE

#指定表的分片策略,包括分片键和分片算法
spring.shardingsphere.sharding.tables.testbydate.table-strategy.standard.sharding-column=birthday
spring.shardingsphere.sharding.tables.testbydate.table-strategy.standard.precise-algorithm-class-name=com.guo.boot.sharding.shardingAlgorithm.MyPreciseShardingAlgorithm

2.3.2算法实现

package com.guo.boot.sharding.shardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Date;
//根据不同的分片算法实现不同的接口。重写doSharding方法
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Date> {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyPreciseShardingAlgorithm.class);
    /*
    * @param shardingValue 包含逻辑表名,列名,列的值
    * @availableTargetNames 所有合法的真实表的集合
    * @return 返回的就是根据算法确定的唯一真实表名
    * */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) {
        Date bir = shardingValue.getValue();
        int month = bir.getMonth();
        for (String table:availableTargetNames) {
            String realtable = shardingValue.getLogicTableName()+"_20210"+getWearther(month);
            if(table.equals(realtable)){
                return table;
            }
        }
        return null;
    }
    public int getWearther(int month){
        int  wearther=0;
        if(month>=1 && month<=3){
            wearther = 1;
        }else if(month>=4 && month<=6){
            wearther = 2;
        }else if(month>=7 && month<=9){
            wearther = 3;
        }else {
            wearther = 4;
        }
        return wearther;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rndjltc2-1636705066112)(C:\Users\guo\AppData\Roaming\Typora\typora-user-images\image-20210428153929773.png)]

标签:分库,shardingsphere,MySql,sharding,分片,Sharding,table,id,SELECT
来源: https://blog.csdn.net/jiangjiangxiaooo/article/details/121290437

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有