-
一、concat函数相关的几种用法1-1、函数:concat(str1,str2,…)concat 函数一般用在SELECT 查询语法中,用于修改返回字段内容,例如有张LOL英雄信息表如下mysql> select * from `LOL`; +----+---------------+--------------+-------+ | id | hero_title | hero_name | price | +----+---------------+--------------+-------+ | 1 | D刀锋之影 | 泰隆 | 6300 | | 2 | X迅捷斥候 | 提莫 | 6300 | | 3 | G光辉女郎 | 拉克丝 | 1350 | | 4 | F发条魔灵 | 奥莉安娜 | 6300 | | 5 | Z至高之拳 | 李青 | 6300 | | 6 | W无极剑圣 | 易 | 450 | | 7 | J疾风剑豪 | 亚索 | 450 | +----+---------------+--------------+-------+ 7 rows in set (0.00 sec)我需要返回一列:英雄称号 - 英雄名称 的数据,这是就用到了concat函数,如下:SELECT CONCAT(hero_title,' - ',hero_name) as full_name, price from `LOL`;mysql> SELECT CONCAT(hero_title,' - ',hero_name) as full_name, price from `LOL`; +------------------------------+-------+ | full_name | price | +------------------------------+-------+ | D刀锋之影 - 泰隆 | 6300 | | X迅捷斥候 - 提莫 | 6300 | | G光辉女郎 - 拉克丝 | 1350 | | F发条魔灵 - 奥莉安娜 | 6300 | | Z至高之拳 - 李青 | 6300 | | W无极剑圣 - 易 | 450 | | J疾风剑豪 - 亚索 | 450 | +------------------------------+-------+ 7 rows in set (0.00 sec)如果拼接的参数中有NULL,则返回NULL;如下:SELECT CONCAT(hero_title,NULL,hero_name) as full_name, price from `LOL`;mysql> SELECT CONCAT(hero_title,'NULL',hero_name) as full_name, price from `LOL`; +-------------------------------+-------+ | full_name | price | +-------------------------------+-------+ | D刀锋之影NULL泰隆 | 6300 | | X迅捷斥候NULL提莫 | 6300 | | G光辉女郎NULL拉克丝 | 1350 | | F发条魔灵NULL奥莉安娜 | 6300 | | Z至高之拳NULL李青 | 6300 | | W无极剑圣NULL易 | 450 | | J疾风剑豪NULL亚索 | 450 | +-------------------------------+-------+ 7 rows in set (0.00 sec)mysql> SELECT CONCAT(hero_title,NULL,hero_name) as full_name, price from `LOL`; +-----------+-------+ | full_name | price | +-----------+-------+ | NULL | 6300 | | NULL | 6300 | | NULL | 1350 | | NULL | 6300 | | NULL | 6300 | | NULL | 450 | | NULL | 450 | +-----------+-------+ 7 rows in set (0.00 sec)1-2、函数:concat_ws(separator,str1,str2,…)CONCAT_WS() 函数全称: CONCAT With Separator ,是CONCAT()的特殊形式。第一个参数(separator)是其它参数的分隔符。分隔符的位置在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它字段参数。需要注意的是:如果分隔符为 NULL,则结果为 NULL;但如果分隔符后面的参数为NULL,只会被直接忽略掉,而不会导致结果为NULL。我们依旧用上面的LOL表,连接各字段,以逗号分隔:select concat_ws(',',hero_title,hero_name,price) as full_name, price from `LOL`;mysql> select concat_ws(',',hero_title,hero_name,price) as full_name, price from `LOL`; +---------------------------------+-------+ | full_name | price | +---------------------------------+-------+ | D刀锋之影,泰隆,6300 | 6300 | | X迅捷斥候,提莫,6300 | 6300 | | G光辉女郎,拉克丝,1350 | 1350 | | F发条魔灵,奥莉安娜,6300 | 6300 | | Z至高之拳,李青,6300 | 6300 | | W无极剑圣,易,450 | 450 | | J疾风剑豪,亚索,450 | 450 | +---------------------------------+-------+ 7 rows in set (0.00 sec)分隔符后的拼接参数为NULL时,直接忽略,不会影响整体结果,如下:select concat_ws(',',hero_title,NULL,hero_name) as full_name, price from `LOL`;mysql> select concat_ws(',',hero_title,NULL,hero_name) as full_name, price from `LOL`; +----------------------------+-------+ | full_name | price | +----------------------------+-------+ | D刀锋之影,泰隆 | 6300 | | X迅捷斥候,提莫 | 6300 | | G光辉女郎,拉克丝 | 1350 | | F发条魔灵,奥莉安娜 | 6300 | | Z至高之拳,李青 | 6300 | | W无极剑圣,易 | 450 | | J疾风剑豪,亚索 | 450 | +----------------------------+-------+ 7 rows in set (0.00 sec)分隔符为NULL时,结果返回NULL,如下:select concat_ws(NULL,hero_title,hero_name,price) as full_name, price from `LOL`;mysql> select concat_ws(NULL,hero_title,hero_name,price) as full_name, price from `LOL`; +-----------+-------+ | full_name | price | +-----------+-------+ | NULL | 6300 | | NULL | 6300 | | NULL | 1350 | | NULL | 6300 | | NULL | 6300 | | NULL | 450 | | NULL | 450 | +-----------+-------+ 7 rows in set (0.00 sec)1-3、函数:group_concat(expr)group_concat ( [DISTINCT] 字段名 [order by 排序字段 ASC/DESC] [Separator ‘分隔符'] ) group_concat函数通常用于有group by的查询语句,group_concat一般包含在查询返回结果字段中。 是不是group_concat函数的公式看着还挺复杂的?我们一起看看,上方公式中 [] 括号是可选项,表示可用可不用;1.[DISTINCT]:对拼接的参数支持去重功能;2.[Order by]:拼接的参数支持排序功能;3.[Separator]:这个你很熟悉了,支持自定义'分隔符',如不设置默认为无分隔符;mysql> select * from `LOL`; +----+---------------+--------------+-------+ | id | hero_title | hero_name | price | +----+---------------+--------------+-------+ | 1 | D刀锋之影 | 泰隆 | 6300 | | 2 | X迅捷斥候 | 提莫 | 6300 | | 3 | G光辉女郎 | 拉克丝 | 1350 | | 4 | F发条魔灵 | 奥莉安娜 | 6300 | | 5 | Z至高之拳 | 李青 | 6300 | | 6 | W无极剑圣 | 易 | 450 | | 7 | J疾风剑豪 | 亚索 | 450 | +----+---------------+--------------+-------+ 7 rows in set (0.00 sec)但是这样很不直观啊,我想一行都看到,SELECT GROUP_CONCAT(hero_title,' - ',hero_name Separator ',' ) as full_name, price from `LOL` GROUP BY price ORDER BY price desc;mysql> SELECT GROUP_CONCAT(hero_title,' - ',hero_name Separator ',' ) as full_name, price from `LOL` GROUP BY price ORDER BY price desc; +------------------------------------------------------------------------+-------+ | full_name | price | +------------------------------------------------------------------------+-------+ | D刀锋之影 - 泰隆,X迅捷斥候 - 提莫,F发条魔灵 - 奥莉安娜,Z至高之拳 - 李青 | 6300 | | G光辉女郎 - 拉克丝 | 1350 | | W无极剑圣 - 易,J疾风剑豪 - 亚索 | 450 | +------------------------------------------------------------------------+-------+ 3 rows in set (0.00 sec)如果按价格(price)从小到大排序,只需控制外层ORDER BY即可,如下:SELECT GROUP_CONCAT(hero_title,' - ',hero_name Separator ',' ) as full_name, price from `LOL` GROUP BY price ORDER BY price asc;mysql> SELECT GROUP_CONCAT(hero_title,' - ',hero_name Separator ',' ) as full_name, price from `LOL` GROUP BY price ORDER BY price asc; +-------------------------------------------------------------------------+-------+ | full_name | price | +-------------------------------------------------------------------------+-------+ | W无极剑圣 - 易,J疾风剑豪 - 亚索 | 450 | | G光辉女郎 - 拉克丝 | 1350 | | D刀锋之影 - 泰隆,X迅捷斥候 - 提莫,F发条魔灵 - 奥莉安娜,Z至高之拳 - 李青 | 6300 | +-------------------------------------------------------------------------+-------+ 3 rows in set (0.00 sec)那么GROUP_CONCAT函数中的order by 排序怎么用?是用在了拼接字段的排序上,如根据hero_title进行排序拼接,如下:SELECT GROUP_CONCAT(hero_title,' - ',hero_name order by hero_title Separator ',' ) as full_name, price from `LOL` GROUP BY price ORDER BY price asc;mysql> SELECT GROUP_CONCAT(hero_title,' - ',hero_name order by hero_title Separator ',' ) as full_name, price from `LOL` GROUP BY price ORDER BY price asc; +-------------------------------------------------------------------------+-------+ | full_name | price | +-------------------------------------------------------------------------+-------+ | J疾风剑豪 - 亚索,W无极剑圣 - 易 | 450 | | G光辉女郎 - 拉克丝 | 1350 | | D刀锋之影 - 泰隆,F发条魔灵 - 奥莉安娜,X迅捷斥候 - 提莫,Z至高之拳 - 李青 | 6300 | +-------------------------------------------------------------------------+-------+ 3 rows in set (0.00 sec)
-
DevRun开发者沙龙-厦门站11.28-《华为云GaussDB(for MySQL)关系型数据库特性揭秘》材料下载数据库议题:华为云GaussDB(for MySQL)关系型数据库特性揭秘数据库实操:基于MySQL本地数据库迁移和python爬虫开发实操材料共享:见附件鹭江之畔,梦幻海岸,我用手中PC进行了一次高效开发实战 http://cloud.zhiding.cn/2020/1128/3130753.shtml 精彩回顾: http://www.zhiding.cn/special/huawei_devrun_xm
-
1 MySQL基本知识1.1 数据库分类关系型数据库:数据库中的数据一般具有隶属关系,通过表来完整描述一段信息,查询时涉及多个数据,导致查询效率较低,如Oracle,MySQL,SQLServer。非关系型数据库:这种数据库里的数据是独立的。查询时涉及的数据较少,所以查询速度较快。一般采用HashMap(key-value)来存储数据。1.2 DB DBMS SQL简介DB:database数据库,在硬盘上以文件形式存储,也就是说存放表文件的文件夹称为数据库。。DBMS:database managerment system 数据库管理系统,如Oracle MySQL DB2 Sybase SqlserverSQL:结构化查询语音,是一门通用语言,适用于所有数据库产品。SQL的编译由DBMS完成。也就是说DBMS执行SQL语句,完成对DB数据的操作。1.3 表表是数据库的基本组成单元,所有的数据库数据都是由表的形式组成,可读性强,包括行与列。行也被称为数据/记录,data列为字段。每个字段包括字段名,数据类型以及相关约束。字段类型:Int 整数型Bigint 长整型Float 浮点型Char 定长字符串 数据长度是固定不变的,如性别、生日等Varchar 可变长字符串Date 时间型BLOB 二进制大对象,存储图片视频等流媒体信息,比如海报 BINARY LARGE OBJECTCLOB 字符大对象 存储较大文本,比如varchar超过255,如4G字符串1.4 SQL语言用户不能直接操作数据库里的数据,需要借助SQL语句,对数据库里的 表文件进行操作管理。1.4.1 SQL语言分类DQL:数据查询语句,凡是select语句都是。DML:数据操作语言,对表数据增删改,insert update deleteDDL:数据定义语言,对表结构的增改,create drop alterTCL:事务控制语言,commit提交事务,rollback回滚事务,savepoint保存点。DCL:数据控制语言,grant授权,revoke撤销权限。1.4.2 SQL语句Select .. 5From … 1Where …2Group by …3Having …4Order by …6Asc/descLimit n,m….7 从第N行开始截取M行;1.5 MySQL命令如查看数据库show databases; , 不是SQL语句,是MySQL命令。创建数据库Create database test;使用数据库Use test;查看表Show tables;数据初始化:source查看表结构 :desc testable; 1.6 模糊查询模糊查询中有两个适配符:%:代表任意多个字符_:代表任意一个字符mysql> select user,host from mysql.user where user like '%o%';+---------------+-----------+| user | host |+---------------+-----------+| root | % || mysql.session | localhost || root | localhost |+---------------+-----------+3 rows in set (0.00 sec) mysql> select user,host from mysql.user where user like '_o%';+------+-----------+| user | host |+------+-----------+| root | % || root | localhost |+------+-----------+2 rows in set (0.00 sec)1.7 分组函数分组函数(count max min avg sum )一般与group by联合使用,如果没有group by则默认为一组。1.8 Limit函数 2 存储引擎MySQL支持很多存储引擎,每一个存储引擎对应不同的存储方式。在其他数据库中不叫存储引擎,如Oracle称为表的存储方式。mysql> show engines;+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+| Engine | Support | Comment | Transactions | XA | Savepoints |+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES || MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO || MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO || BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO || MyISAM | YES | MyISAM storage engine | NO | NO | NO || CSV | YES | CSV storage engine | NO | NO | NO || ARCHIVE | YES | Archive storage engine | NO | NO | NO || PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO || FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+9 rows in set (0.01 sec)2.1 MyISAM存储引擎 MyISAM是MySQL最常用的引擎。具有以下三个特征:l 使用三个文件表示表:Ø 格式文件-存储表结构的定义,如mytable.frmØ 数据文件-存储表行的内容,如mytable.MYDØ 索引文件-存储表上索引,如mytable.MYIl 灵活的AUTO_INCREMENT字段处理。l 可被转换为压缩、只读表来节省空间。优点:可被压缩,节省存储空间;并可转换为只读表,提高检索效率。缺点:不支持事务,2.2 InnoDB存储引擎InooDB存储引擎是MySQL缺省的存储引擎。l 每个表在数据库目录中都以.frm格式文件表示l InnoDB表空间tablespace被用于存储表的内容。l 提供一组用来记录事务性活动的日志文件l 用commit savepoint 以及rollback支持事务处理l 提供全ACID兼容l 在MySQL数据库奔溃后自动恢复l 多版本MVCC和行级锁定l 支持外键及引用的完整性,包括级联删除和更新。优点:支持事务,外键,行级锁;数据库奔溃后可自动恢复。这种引擎保障数据安全。缺点:存储数据无法压缩,无法转为只读表。读取效率不是最优。2.3 Memory存储引擎使用该存储引擎的表,数据存放在内存中,且行的长度固定。不支持事务,数据容易丢失。 3 事务3.1 事务概念一个事务是一个完整的业务逻辑单元,不可再分。 以上两条DML语句,要不同时成功,要不同时失败。不允许其中一条成功,一条失败。事务保证多个操作原子性,要不全成功,要不全失败。只有DML语句支持事务,事务存在的意思在于保证数据的完整性,安全性。3.2 事务特性事务包括四大特性ACID:1) 原子性:事务是最小的工作单元,不可再分。2) 一致性:事务必须保证多条DML语句同时成功,同时失败。3) 隔离性:事务A和事务B之间具有隔离性,保证事务安全。4) 持久性:数据必须持久化到硬盘后,事务才结束。3.3 隔离级别 理论上隔离有四个级别:第一级别读未提交:当前事务可读取到对方事务未提交的数据,此时为脏读现象,数据为脏数据。第二级别读已提交:当前事务可读取对方事务提交之后的数据,但是不可重复读。第三级别可重复读:这个级别解决了不可重复读问题,但是读取的数据不一定是最新的数据。第四级别序列化读/串行读,解决了以上问题,但是效率较低,事务需要排队处理。Oracle默认的隔离级别为第二级别,MySQL默认的隔离级别为第三级别。 3.4 事务演示3.4.1 事务自动提交MySQL默认事务自动提交,如下演示,执行一条DML,则提交事务。mysql> select * from item;Empty set (0.01 sec)mysql> insert into item values (1,2,'apple',7.23,'20201224');Query OK, 1 row affected (0.01 sec)mysql> select * from item;+------+---------+--------+---------+----------+| i_id | i_im_id | i_name | i_price | i_data |+------+---------+--------+---------+----------+| 1 | 2 | apple | 7.23 | 20201224 |+------+---------+--------+---------+----------+1 row in set (0.00 sec)mysql> rollback;Query OK, 0 rows affected (0.00 sec)mysql> select * from item;+------+---------+--------+---------+----------+| i_id | i_im_id | i_name | i_price | i_data |+------+---------+--------+---------+----------+| 1 | 2 | apple | 7.23 | 20201224 |+------+---------+--------+---------+----------+1 row in set (0.00 sec)3.4.2 关闭自动提交执行命令start transaction关闭事务自动提交,此时rollback可回滚到该事务开启时的数据状态。mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> insert into item values (2,3,'wine',217.23,'20201224');Query OK, 1 row affected (0.00 sec)mysql> select * from item;+------+---------+--------+---------+----------+| i_id | i_im_id | i_name | i_price | i_data |+------+---------+--------+---------+----------+| 1 | 2 | apple | 7.23 | 20201224 || 2 | 3 | wine | 217.23 | 20201224 |+------+---------+--------+---------+----------+2 rows in set (0.00 sec)mysql> rollback;Query OK, 0 rows affected (0.01 sec)mysql> select * from item;+------+---------+--------+---------+----------+| i_id | i_im_id | i_name | i_price | i_data |+------+---------+--------+---------+----------+| 1 | 2 | apple | 7.23 | 20201224 |+------+---------+--------+---------+----------+1 row in set (0.00 sec)3.4.3 隔离级别以下演示第一级别先设置当前事务(MySQL窗口)隔离级别为第一级别,执行命令set global transaction isolacion leverl read uncommited;mysql> select @@global.tx_isolation;+-----------------------+| @@global.tx_isolation |+-----------------------+| REPEATABLE-READ |+-----------------------+1 row in set, 1 warning (0.00 sec)mysql> set global transaction isolation level read uncommitted;Query OK, 0 rows affected (0.00 sec)mysql> select @@global.tx_isolation;+-----------------------+| @@global.tx_isolation |+-----------------------+| READ-UNCOMMITTED |测试结果如下:回退之后,结果如下: 4 索引4.1 索引概念简单比喻,索引相当于一本书的目录,通过索引,可快速找到对应的数据。实例:select * from emp where ename=’SMITH’;如果ename字段没有索引,以上语句会进行全表搜索,扫描ename字段里所有的值;如果ename字段上添加索引,以上语句会根据所有扫描,快速定位。通过索引,可缩小搜索范围,极大提高搜索效率。如果索引数据经常修改,可能会导致索引重新排序,提高维护成本。索引适用范围:l 数据量庞大。l 该字段很少DML操作。l 该字段经常出现在where子句中注意:主键和具有unique约束的字段会自动添加索引功能,所以要尽量通过主键来检索。索引的分类:l 单一索引:给单个字段添加索引l 复合索引:多个字段联合添加1个索引l 主键索引:主键自动添加索引l 唯一索引:unique约束的主键自动添加索引 4.2 索引结构索引底层数据结构为B+结构。添加索引mysql> explain select i_id,i_im_id from item where i_price< 20;+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+| 1 | SIMPLE | item | NULL | ALL | NULL | NULL | NULL | NULL | 6 | 33.33 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)mysql> create index item_i_price_index on item(i_price);Query OK, 0 rows affected (0.04 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> explain select i_id,i_im_id from item where i_price< 20;+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+-----------------------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+-----------------------+| 1 | SIMPLE | item | NULL | range | item_i_price_index | item_i_price_index | 4 | NULL | 2 | 100.00 | Using index condition |+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.00 sec)Range:Where不会对表文件数据进行遍历,而是直接从索引得到定位数的数据行数,大幅度提高检索的效率。但是当字段内容发生变化时,会导致索引失效。如果索引得到的行数达到或超过总行数的1/3时,此时考虑到运行成本时,查询时(explain)放弃使用索引。ref:Where不会对表文件数据进行遍历,而是直接从索引得到定位数的数据行数,同时一次只能得到一次数据行,属于稳定执行官效率,是DBA需要努力达到的效果。(索引对应字段的值是唯一)Const: 根据主键上索引进行检索,执行效率最高。但是实际使用中,很少会被使用。 4.3 索引原理通过B Tree缩小扫描范围,底层索引进行了排序、分区,索引会映射数据在原表中的物理地址。最终通过索引检索到数据之后,获取到关联的物理地址,定位到表中数据,提高检索效率。5 视图视图作用:1) 提高了查询语句复用性,避免了在多处地方重复进行查询语句开发行为。2) 隐藏业务中表的细节,保证了客户业务的安全性。 6 数据库三范式6.1 三范式概念第一范式:每一行都必须唯一,即每个表必须有主键,每个字段不可再分。这是数据库设计的最基本要求。第二范式:建立在第一范式基础上, 所有非主键字段依赖主键,不产生部分依赖。比如多对多,用一张表就违反了 第二范式,需要建立三张表,关系表两个外键。第三范式:建立在第二范式基础上, 所有非主键字段依赖主键,不产生传递依赖。三范式减少了数据冗余,但是数据查询效率可能会降低。
-
概述在实际的业务场景应用中,我们经常要根据业务条件获取并筛选出我们的目标数据。这个过程我们称之为数据查询的过滤。而过滤过程使用的各种条件(比如日期时间、用户、状态)是我们获取精准数据的必要步骤,关系运算关系运算就是where语句后跟上一个或者n个条件,满足where后面条件的数据会被返回,反之不满足的就会被过滤掉。operators指的是运算符 ,有如下几种情况:运算符说明=等于<> 或者 !=不等于>大于>=大于等于<小于<=小于等于关系运算基本的语法格式如下 select cname1,cname2,... from tname where cname operators cval等于=查询出 列和后面的值严格相等的数据,非值类型的需要对后面值加上引号,值类型的不需要。语法格式如下:select cname1,cname2,... from tname where cname = cval;mysql> select * from user2; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | +----+-------+-----+----------+-----+ 3 rows in set mysql> select * from user2 where name='helen'; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 2 | helen | 20 | quanzhou | 0 | +----+-------+-----+----------+-----+ 1 row in set mysql> select * from user2 where age=21; +----+-------+-----+---------+-----+ | id | name | age | address | sex | +----+-------+-----+---------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 3 | sol | 21 | xiamen | 0 | +----+-------+-----+---------+-----+ 2 rows in set不等于(<>、!=)不等于有两种写法,一种是<>,另一种是!=,意思一样,可随意切换使用,但是 <> 先于 != 出现,所以看很多以前的例子,<> 出现频率比较高,可移植性更强,推荐使用。不等于的目的是查询出与条件不符和结果,格式如下:select cname1,cname2,... from tname where cname <> cval; 或 select cname1,cname2,... from tname where cname != cval;mysql> select * from user2; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | +----+-------+-----+----------+-----+ 3 rows in set mysql> select * from user2 where age<>20; +----+-------+-----+---------+-----+ | id | name | age | address | sex | +----+-------+-----+---------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 3 | sol | 21 | xiamen | 0 | +----+-------+-----+---------+-----+ 2 rows in set大于小于(> <)一般用于数值或者日期、时间类型的比较,格式如下:select cname1,cname2,... from tname where cname > cval; select cname1,cname2,... from tname where cname < cval; select cname1,cname2,... from tname where cname >= cval; select cname1,cname2,... from tname where cname <= cval;mysql> select * from user2 where age>20; +----+-------+-----+---------+-----+ | id | name | age | address | sex | +----+-------+-----+---------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 3 | sol | 21 | xiamen | 0 | +----+-------+-----+---------+-----+ 2 rows in set mysql> select * from user2 where age>=20; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | +----+-------+-----+----------+-----+ 3 rows in set mysql> select * from user2 where age<21; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 2 | helen | 20 | quanzhou | 0 | +----+-------+-----+----------+-----+ 1 row in set mysql> select * from user2 where age<=21; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | +----+-------+-----+----------+-----+ 3 rows in set运算符说明AND多个条件都成立OR多个条件中满足一个NOT对条件进行取非操作AND(且)当需要多个条件进行数据过滤的时候,使用这种方式,and的每个表达式都是要成立,过滤出来的数据就是用户需要的。下面过滤出年龄和性别两个条件都成立的数据,语法格式如下:select cname1,cname2,... from tname where cname1 operators cval1 and cname2 operators cval2mysql> select * from user2; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | | 4 | weng | 33 | guizhou | 1 | +----+-------+-----+----------+-----+ 4 rows in set mysql> select * from user2 where age >20 and sex=1; +----+-------+-----+---------+-----+ | id | name | age | address | sex | +----+-------+-----+---------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 4 | weng | 33 | guizhou | 1 | +----+-------+-----+---------+-----+ 2 rows in setOR(或)当多个条件中只要满足一个条件即进行数据过滤。下面条件过滤出年龄大于21岁和小于21岁的数据,语法格式如下:select cname1,cname2,... from tname where cname1 operators cval1 or cname2 operators cval2mysql> select * from user2; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | | 4 | weng | 33 | guizhou | 1 | +----+-------+-----+----------+-----+ 4 rows in set mysql> select * from user2 where age>21 or age<21; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 2 | helen | 20 | quanzhou | 0 | | 4 | weng | 33 | guizhou | 1 | +----+-------+-----+----------+-----+ 2 rows in setNOT IN(对包含查询取反)我们上面已经学习过了not得用户,对not后面执行得表达式进行取反得操作,测试下:mysql> select * from user2; +----+--------+-----+----------+-----+ | id | name | age | address | sex | +----+--------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | | 4 | weng | 33 | guizhou | 1 | | 5 | selina | 25 | taiwang | 0 | +----+--------+-----+----------+-----+ 5 rows in set mysql> select * from user2 where address not in('fuzhou','quanzhou','xiamen'); +----+--------+-----+---------+-----+ | id | name | age | address | sex | +----+--------+-----+---------+-----+ | 4 | weng | 33 | guizhou | 1 | | 5 | selina | 25 | taiwang | 0 | +----+--------+-----+---------+-----+ 2 rows in set空值检查IS NULL/IS NOT NULL判断是否为空,语法格式如下,这边注意的是,对值为null的数据,各种比较运算符、like、between and、in、not in查询都不起作用,只有is null 能够过滤出来。 select cname1,cname2,... from tname where cname is null; 或者 select cname1,cname2,... from tname where cname is not null;mysql> select * from user2 where address is null; +----+--------+-----+---------+-----+ | id | name | age | address | sex | +----+--------+-----+---------+-----+ | 5 | selina | 25 | NULL | 0 | +----+--------+-----+---------+-----+ 1 row in set mysql> select * from user2 where address is not null; +----+-------+-----+----------+-----+ | id | name | age | address | sex | +----+-------+-----+----------+-----+ | 1 | brand | 21 | fuzhou | 1 | | 2 | helen | 20 | quanzhou | 0 | | 3 | sol | 21 | xiamen | 0 | | 4 | weng | 33 | guizhou | 1 | +----+-------+-----+----------+-----+ 4 rows in set总结1、like表达式中的%匹配一个到多个任意字符,_匹配一个任意字符2、空值查询需要使用IS NULL或者IS NOT NULL,其他查询运算符对NULL值无效。即使%通配符可以匹配任何东西,也不能匹配值NULL的数据。3、建议创建表的时候,表字段不设置空,给字段一个default 默认值。4、MySQL支持使用NOT对IN 、BETWEEN 和EXISTS子句取反 。
-
子查询如递归函数一样,有时侯能达到事半功倍的效果,但是其执行效率较低。与表连接相比,子查询比较灵活,方便,形式多样,适合作为查询的筛选条件,而表连接更适合查看多表的数据。一般情况下,子查询会产生笛卡儿积,表连接的效率要高于子查询。因此在编写 SQL 语句时应尽量使用连接查询。通过华为云Mysql的七天训练营基础课程,我们知道表连接(内连接和外连接等)都可以用子查询替换,但反过来却不一定,有的子查询不能用表连接来替换。下面我们介绍哪些子查询的查询命令可以改写为表连接。在检查那些倾向于编写成子查询的查询语句时,可以考虑将子查询替换为表连接,看看连接的效率是不是比子查询更好些。同样,如果某条使用子查询的 SELECT 语句需要花费很长时间才能执行完毕,那么可以尝试把它改写为表连接,看看执行效果是否有所改善。下面讨论具体该如何做。1. 改写用来查询匹配值的子查询下面这条示例语句包含一个子查询,它会把 score 表里的考试成绩查询出来:SELECT * FROM scoreWHERE grade_id IN (SELECT id FROM grade WHERE category = 'Java');在编写以上语句时,可以不使用子查询,而是把它转换为一个简单的连接:SELECT score.* FROM score INNER JOIN gradeON score.grade_id = grade.id WHERE grade.category = 'Java';再来看另一个示例。下面这条查询语句可以把所有女生的考试成绩查询出来:SELECT * from scoreWHERE student_id IN (SELECT student_id FROM student WHERE sex = 'F') ;这条语句可以转换为以下连接:SELECT score.* FROM score INNER JOIN studentON score.student_id = student.student_id WHERE student.sex = 'F' ;我们可以发现这些子查询语句都遵从这样一种形式:SELECT * FROM table1WHERE column1 IN (SELECT column2a FROM table2 WHERE column2b = value);其中,column1 代表 table1 中的字段,column2a 和 column2b 代表 table2 表中的字段。这类查询都可以被转换为下面这种形式的连接查询:SELECT table1. * FROM table1 INNER JOIN table2ON table1. column1 = table. column2a WHERE table2. column2b = value;在某些场合,子查询和关联查询可能会返回不同的结果。比如,当 table2 包含 column2a 的多个实例时,就会发生这种情况。这种形式的子查询只会为每个 column2a 值生成一个实例,而连接操作会为所有值生成实例,并且其输出会包含重复行。如果想要防止这种重复记录出现,就要在编写连接查询语句时使用 SELECT DISTINCT,而不能使用 SELECT。2. 改写用来查询非匹配(缺失)值的子查询另一种常见的子查询语句类型是:把存在于某个表里,但在另一个表里并不存在的那些值查找出来。“哪些值不存在”有关的问题通常都可以用 LEFT JOIN 来解决。如下语句用来测试哪些学生没有出现在 absence 表里(用于查找全勤学生):SELECT * FROM studentWHERE student_id NOT IN (SELECT student_id FROM absence) ;以上查询语句可以使用 LEFT JOIN 来改写:SELECT student.* FROM student LEFT JOIN absenceON student.student_id = absence.student_id WHERE absence.student_ id IS NULL;通常情况下,如果子查询语句符合如下所示的形式:SELECT * FROM table1WHERE column1 NOT IN ( SELECT column2 FROM table2) ;那么可以把它改写为下面这样的连接查询:SELECT table1.* FROM table1 LEFT JOIN table2ON table1.column1 = table2.column2 WHERE table2.column2 IS NULL;这里需要假设 table2.column2 被定义成了 NOT NULL 的。与 LEFT JOIN 相比,子查询更加直观。大部分人都可以毫无困难地理解“没被包含在...里面”的含义,因为它不是数据库编程技术带来的新概念。而“左连接”有所不同,很难用自然语言直观地描述出它的含义。
-
MySQL 中,可以通过两个方面来优化服务器,即硬件和配置参数的优化。通过这些优化方式,可以提高 MySQL 的运行速度。本节内容需要较全面的知识,可能很难理解,一般只有专业的数据库管理员才能进行这一类的优化。下面为读者介绍优化 MySQL 服务器的方法。优化服务器硬件服务器的硬件直接决定着 MySQL 数据库的性能。例如,增加内存和提高硬盘的读写速度,可以提高 MySQL 数据库的查询、更新的速度。优化服务器硬件的方法主要有以下几种:配置较大的内存配置高速磁盘系统,以减少读盘的等待时间,提高响应速度合理分布磁盘 I/O,把磁盘 I/O 分散在多个设备上,以减少资源竞争,提高并行操作能力配置多处理器,MySQL 是多线程的数据库,多处理器可同时执行多个线程随着硬件技术的成熟,硬件的价格也随之降低。现在普通的个人电脑都已经配置了 8GB 内存,甚至一些个人电脑配置 16GB 内存。因为内存的读写速度比硬盘的读写速度快。可以在内存中为 MySQL 设置更多的缓冲区,这样可以提高 MySQL 的访问的速度。如果将查询频率很高的记录存储在内存中,那么查询速度就会很快。如果条件允许,可以将内存提高到 16GB。并且选择 my-innodb-heavy-4G.ini 作为 MySQL 数据库的配置文件。但是,这个配置文件主要支持 InnoDB 存储引擎的表。如果使用 8GB 内存,可以选择 my-huge.ini 作为配置文件。MySQL 所在的计算机最好是专用数据库服务器,这样数据库就可以完全利用该机器的资源。服务器类型分为 Developer Machine、Server Machine 和 Dedicate MySQL Server Machine。其中 Developer Machine 用来做软件开发的时候使用,数据库占用的资源比较少。后面两者占用的资源比较多,尤其是 Dedicate MySQL Server Machine,其几乎要占用所有的资源。还可以使用多块磁盘来存储数据。这样可以从多个磁盘上并行读取数据,提高数据库读取数据的速度。通过镜像机制可以将不同计算机上的 MySQL 服务器进行同步,这些 MySQL 服务器中的数据都是一样的。通过不同的 MySQL 服务器来提供数据库服务,这样可以降低单个 MySQL 服务器的压力,从而提高 MySQL 的性能。优化MySQL参数和大多数数据库一样,MySQL 提供了很多参数来进行服务器的优化设置。数据库服务器第一次启动时,很多参数都是默认设置的,这在实际应用中并不能完全满足需求,为此数据库管理员要进行必要的设置。1. 查看性能参数的方法MySQL 服务器启动之后,可以使用 SHOW VARIABLES;命令查看系统参数,也可称为静态参数。这些参数是系统默认或者 DBA 调整优化后的参数,可以通过 SET 命令或在配置文件中修改。使用 SHOW STATUS; 命令查询服务器运行的实时状态信息,也就是动态参数。便于 DBA 查看当前 MySQL 运行的状态,做出相应优化,不能手动修改。例 1下面为使用 SHOW VARIABLES 和 SHOW STATUS 命令的实例。mysql> SHOW VARIABLES LIKE 'key_buffer_size'; +-----------------+----------+ | Variable_name | Value | +-----------------+----------+ | key_buffer_size | 33554432 | +-----------------+----------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW STATUS LIKE 'key_read_requests'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Key_read_requests | 149 | +-------------------+-------+ 1 row in set (0.01 sec)2. 设置优化性能参数在 MySQL 中,有些参数直接影响到系统的性能。我们可以通过优化 MySQL 的参数提高资源利用率,从而达到提高 MySQL 服务器性能的目的。以下配置参数都在 my.cnf 或者 my.ini 文件的 [mysqld] 组中。下面对几个重要参数进行详细介绍。1)key_buffer_size(针对MyISAM存储引擎)表示索引缓存的大小,这个参数是对 MyISAM 表性能影响最大的一个参数。值越大,索引进行查询的速度越快。通过检查状态值 key_read_requests 和 key_reads,可以知道 key_buffer_size 的值是否合理。正常情况下,key_reads / key_read_requests 的比例值需小于 0.01。2)table_cache(针对MyISAM存储引擎)表示数据库用户同时打开的表的个数。值越大,能够同时打开的表的个数越多。需要注意的是,这个值不是越大越好,因为同时打开的表太多会影响操作系统的性能。在设置该参数的时候,可以通过 open_tables 和 opened_tables 变量的值来确定该参数的值。open_tables 参数表示当前打开的表缓存数,opened_tables 参数表示曾经打开的表缓存数。如果 open_tables 的值已经接近 table_cache 的值,且 opened_tables 还在不断变大,则说明 MySQL 正在将缓存的表释放以容纳新的表,此时可能需要加大table_cache 的值。对于大多数情况,比较适合的值如下:open_tables / opened_tables >= 0.85open_tables / table_cache <= 0.95执行 FLUSH TABLE 操作后,系统会关闭一些当前没有使用的表缓存,因此 FLUSH TABLE 后,open_tables 参数的值会变小,opened_tables 参数的值不会变。3)query_cache_size表示查询缓存区的大小。使用查询缓存区可以提高查询的速度。内存中会为 MySQL 保留部分的缓存区,这些缓存区可以提高 MySQL 的处理速度。可以从以下几个方面考虑如何设置该参数的大小:查询缓存对 DDL 和 DML 语句的性能的影响查询缓存的内部维护成本查询缓存的命中率以及内存使用率等因素4)query_cache_type表示查询缓冲区的开启状态,用于控制查询结果是否放到查询缓存中。这种方式只适用于修改操作少且经常执行相同的查询操作的情况,其默认值为 0。值为 0 表示关闭;值为 1 表示开启;值为 2 表示按要求使用查询缓存区,只有 SELECT 语句中使用了 SQL_CACHE 关键字,查询缓存区才会使用。例如,SELECT SQL_CACHE * FROM student。5)max_connections表示数据库的最大连接数,默认值为 100。参数最大值不能超过 16384,即使超过也以 16384 为准。该参数设置过小的最明显特征是出现“Too many connections”错误。当然连接数也不是越大越好,因为这些连接会浪费内存的资源。6)sort_buffer_size表示排序缓存区的大小。值越大,排序的速度越快。7)read_buffer_size表示为每个线程保留的缓冲区的大小。当线程需要从表中连续读取记录时需要用到这个缓冲区。8)read_rnd_buffer_size表示为每个线程保留的缓冲区的大小,与 read_buffer_size 相似。但主要用于存储按特定顺序读取出来的记录。9)innodb_buffer_pool_size表示 InnoDB 类型的表和索引的最大缓存。值越大,查询的速度越快。但是这个值太大了也会影响操作系统的性能。调优参考计算方法:val = Innodb_buffer_pool_pages_data / Innodb_buffer_pool_pages_total * 100%val > 95% 则考虑增大 innodb_buffer_pool_size, 建议使用物理内存的 75%val < 95% 则考虑减小 innodb_buffer_pool_size, 建议设置为:Innodb_buffer_pool_pages_data * Innodb_page_size * 1.05 / (1024*1024*1024)10)innodb_log_file_size该参数的作用是设置日志组中每个日志文件的大小。该参数在高写入负载尤其是大数据集的情况下很重要,这个值越大则性能相对较高。最好不要超过 innodb_log_files_in_group * innodb_log_file_size 的 0.75。11)innodb_log_files_in_group该参数用于指定数据库中有几个日志组,默认为2个,因为有可能出现跨日志的大事务,所以一般来讲,建议使用 3~4 个日志组。12)innodb_log_buffer_size该参数的作用是设置日志缓存的大小,一旦提交事务,则将该缓存池中的内容写到磁盘的日志文件上。该参数的设置在中等强度写入负载以及较短事务情况下,一般都可以满足服务器的性能要求。如果服务器负载较大,可以考虑加大该参数的值。一般缓存池中的内存每秒钟写到磁盘一次,所以设置较大会浪费内存空间,一般设置为 8MB~16MB 就足够了。可以参考 Innodb_os_log_written 的值,如果该值增加过快,可以适当的增加该参数的值。13)innodb_flush_log_at_trx_commit表示何时将缓冲区的数据写入日志文件,并且将日志文件写入磁盘中。该参数有 3 个值,分别为 0、1 和 2。值为 0 时,表示每隔 1 秒将数据写入日志文件并将日志文件写入磁盘;值为 1 时,表示每次提交事务时将数据写入日志文件并将日志文件写入磁盘;值为 2 时,表示每次提交事务时将数据写入日志文件,每隔 1 秒将日志文件写入磁盘。该参数的默认值为 1,是最安全最合理的值。为了保证事务的持久性和一致性,建议将该参数设置为 1。参数设置的值要根据自己的实际情况来设置,并不是值越大越好,可能设置的数值太大体现不出优化效果,反而造成系统空间被占用,导致操作系统变慢。合理的配置参数可以提高 MySQL 服务器的性能。需要注意的是,配置完参数以后,需要重新启动 MySQL 服务配置才会生效。
-
一、什么是表?但凡是用过MySQL都知道,直观上看,MySQL的数据都存在数据表中。比如一条Update SQL:update user set username = '白日梦' where id = 999;它将user这张数据表中id为1的记录的username列修改成了‘白日梦'这里的user其实就是数据表。当然这不是重点,重点是我想表达:数据表其实是逻辑上的概念。而下面要说的表空间是物理层面的概念。二、什么是表空间?不知道你有没有看到过这句话:“在innodb存储引擎中数据是按照表空间来组织存储的”。其实有个潜台词是:表空间是表空间文件是实际存在的物理文件。大家不用纠结为啥它叫表空间、为啥表空间会对应着磁盘上的物理文件,因为MySQL就是这样设计、设定的。直接接受这个概念就好了。MySQL有很多种表空间,下面一起来了解一下。三、sys表空间你可以像下面这样查看你的MySQL的系统表空间alue部分的的组成是:name:size:attributes默认情况下,MySQL会初始化一个大小为12MB,名为ibdata1文件,并且随着数据的增多,它会自动扩容。这个ibdata1文件是系统表空间,也是默认的表空间,也是默认的表空间物理文件,也是传说中的共享表空间。四、配置sys表空间系统表空间的数量和大小可以通过启动参数:innodb_data_file_path# my.cnf [mysqld] innodb_data_file_path=/dir1/ibdata1:2000M;/dir2/ibdata2:2000M:autoextend五、file per table 表空间如果你想让每一个数据库表都有一个单独的表空间文件的话,可以通过参数innodb_file_per_table设置可以通过配置文件[mysqld] innodb_file_per_table=ON也可以通过命令mysql> SET GLOBAL innodb_file_per_table=ON; 让你将其设置为ON,那之后InnoDB存储引擎产生的表都会自己独立的表空间文件。独立的表空间文件命名规则:表名.ibd注意独立表空间文件中仅存放该表对应数据、索引、insert buffer bitmap。 其余的诸如:undo信息、insert buffer 索引页、double write buffer 等信息依然放在默认表空间,也就是共享表空间中。 这里的undo、insert buffer、double write buffer 如果你不了解他们是啥也没关系。 ,这里只需要先了解即使你设置了innodb_file_per_table=ON 共享表空间的体量依然会不断的增长, 并且你即使你不断的使用undo进行rollback,共享表空间大小也不会缩减就好了。查看我的表空间文件:优点:提升容错率,表A的表空间损坏后,其他表空间不会收到影响。s使用MySQL Enterprise Backup快速备份或还原在每表文件表空间中创建的表,不会中断其他InnoDB 表的使用缺点:对fsync系统调用来说不友好,如果使用一个表空间文件的话单次系统调用可以完成数据的落盘,但是如果你将表空间文件拆分成多个。原来的一次fsync可能会就变成针对涉及到的所有表空间文件分别执行一次fsync,增加fsync的次数。六、临时表空间临时表空间用于存放用户创建的临时表和磁盘内部临时表。参数innodb_temp_data_file_path定义了临时表空间的一些名称、大小、规格属性如下图:查看临时表空间文件存放的目录七、undo表空间相信你肯定听过说undolog,常见的当你的程序想要将事物rollback时,底层MySQL其实就是通过这些undo信息帮你回滚的。在MySQL的设定中,有一个表空间可以专门用来存放undolog的日志文件。然而,在MySQL的设定中,默认的会将undolog放置到系统表空间中。如果你的MySQL是新安装的,那你可以通过下面的命令看看你的MySQL undo表空间的使用情况:大家可以看到,我的MySQL的undo log 表空间有两个。也就是我的undo从默认的系统表空间中转移到了undo log专属表空间中了。那undo log到底是该使用默认的配置放在系统表空间呢?还是该放在undo表空间呢?这其实取决服务器使用的存储卷的类型。
-
今天的话题要从一个朋友的咨询开始 所以准备写一篇短文谈谈我对“存算分离”架构的理解,不一定全面,欢迎在评论区探讨。 其实这个朋友是误解了“存算分离”这个概念。他认为普通MySQL云数据库用evs做存储,计算资源和存储资源是分开的,比如可以单独扩容计算资源或单独扩容存储资源,所以就是存算分离的架构,其实这么理解是片面的。要理解“存算分离”架构,还得追根溯源,从传统MySQL主备架构说起。 这张图熟悉MySQL的人应该都见过,我们知道,MySQL的master端有数据变更时,备机是通过读取和回放binlog,涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在备节点,三个线程配合完成数据复制的工作。但是,不难发现,这个架构在某些场景会有明显的缺陷:主库写入压力大时。当主库的写入压力比较大的时候,主备复制的时延会变大,因为需要回放完所有binlog的事务才会完全达到数据同步。增加只读节点时。增加备机/只读节点的速度很慢,因为我们需要将数据全量的复制到从节点,如果主节点此时存量的数据已经很多,那么扩展一个备机节点速度就会很慢高。使用多个只读节点时。存储的成本线性增长,如果数据库磁盘空间比较大,那么相应的所有只读节点挂载的磁盘空间都需要和主节点一样大,成本将会随着只读库数量增加进行线性增加。 这些问题通过存算分离架构就能得到很好的解决,以华为云GaussDB(for MySQL)为例,作为华为自研的最新一代高性能企业级分布式数据库,基于华为最新一代DFV分布式存储,采用计算存储分离架构,最高支持128TB的海量存储,可实现超百万级QPS吞吐。 首先,GaussDB(for MySQL)采用计算与存储解耦的技术架构,让所有的节点都共享一个存储,也就是说,增加计算节点时,无需调整存储资源,真正做到计算与存储分离,并且可支持 15 个只读节点的扩展,主节点和只读节点之间是 Active-Active 的 Failover 方式,计算节点资源得到充分利用,由于使用共享存储,降低了用户使用成本。完美契合了企业级数据库系统对高可用性、性能和扩展性、云服务托管的需求。GaussDB(for MySQL)将MySQL存储层变为独立的存储节点,在GaussDB(for MySQL)中认为日志即数据,将日志彻底从MySQL计算节点中抽离出来,都由存储节点进行保存,与传统 RDS for MySQL 相比,不再需要刷 page,所有更新操作都记录日志,不再需要 double write,从而大大减少了网络通信。 小结一下,以“存算分离”架构来答复一下上面的3个问题: 1. 当主库的写入压力比较大的时候,由于不再有double write入,主节点和只读节点之间的复制时延基本得以消除。 2. 增加只读节点的速度非常快,因为不再需要将数据全量的复制到只读节点,无论多大数据量,只需 5 分钟左右即可完成增加只读节点。 3. 使用多个只读节点时,因为只有一份存储,所以存储的成本不会有变化,存储空间越大,只读节点越多,节省成本越明显。
-
MySQL 数据库中的表结构确立后,表中的数据代表的意义就已经确定。而通过 MySQL 运算符进行运算,就可以获取到表结构以外的另一种数据。例如,学生表中存在一个 birth 字段,这个字段表示学生的出生年份。而运用 MySQL 的算术运算符用当前的年份减学生出生的年份,那么得到的就是这个学生的实际年龄数据。MySQL 支持 4 种运算符,分别是:1) 算术运算符执行算术运算,例如:加、减、乘、除等。2) 比较运算符包括大于、小于、等于或者不等于,等等。主要用于数值的比较、字符串的匹配等方面。例如:LIKE、IN、BETWEEN AND 和 IS NULL 等都是比较运算符,还包括正则表达式的 REGEXP 也是比较运算符。3) 逻辑运算符包括与、或、非和异或等逻辑运算符。其返回值为布尔型,真值(1 或 true)和假值(0 或 false)。4) 位运算符包括按位与、按位或、按位取反、按位异或、按位左移和按位右移等位运算符。位运算必须先将数据转换为二进制,然后在二进制格式下进行操作,运算完成后,将二进制的值转换为原来的类型,返回给用户。算术运算符算术运算符是 SQL 中最基本的运算符,MySQL 中的算术运算符如下表所示。算术运算符说明+加法运算-减法运算*乘法运算/除法运算,返回商%求余运算,返回余数比较运算符比较运算符的语法格式为:<表达式1> {= | < | <= | > | >= | <=> | < > | !=} <表达式2>MySQL 支持的比较运算符如下表所示。比较运算符说明=等于<小于<=小于等于>大于>=大于等于<=>安全的等于,不会返回 UNKNOWN<> 或!=不等于IS NULL 或 ISNULL判断一个值是否为 NULLIS NOT NULL判断一个值是否不为 NULLLEAST当有两个或多个参数时,返回最小值GREATEST当有两个或多个参数时,返回最大值BETWEEN AND判断一个值是否落在两个值之间IN判断一个值是IN列表中的任意一个值NOT IN判断一个值不是IN列表中的任意一个值LIKE通配符匹配REGEXP正则表达式匹配下面分别介绍不同的比较运算符的使用方法。1) 等于运算符“=”等号“=”用来判断数字、字符串和表达式是否相等。如果相等,返回值为 1,否则返回值为 0。数据进行比较时,有如下规则:若有一个或两个参数为 NULL,则比较运算的结果为 NULL。若同一个比较运算中的两个参数都是字符串,则按照字符串进行比较。若两个参数均为正数,则按照整数进行比较。若一个字符串和数字进行相等判断,则 MySQL 可以自动将字符串转换成数字。2) 安全等于运算符“<=>”用于比较两个表达式的值。当两个表达式的值中有一个为空值或者都为空值时,将返回 UNKNOWN。对于运算符“<=>”,当两个表达式彼此相等或都等于空值时,比较结果为 TRUE;若其中一个是空值或者都是非空值但不相等时,则为 FALSE,不会出现 UNKNOWN 的情况。3) 不等于运算符“<>”或者“!=”“<>”或者“!=”用于数字、字符串、表达式不相等的判断。如果不相等,返回值为 1;否则返回值为 0。这两个运算符不能用于判断空值(NULL)。4) 小于或等于运算符“<=”“<=”用来判断左边的操作数是否小于或等于右边的操作数。如果小于或等于,返回值为 1;否则返回值为 0。“<=”不能用于判断空值。5) 小于运算符“<”“<”用来判断左边的操作数是否小于右边的操作数。如果小于,返回值为 1;否则返回值为 0。“<”不能用于判断空值。6) 大于或等于运算符“>=”“>=”用来判断左边的操作数是否大于或等于右边的操作数。如果大于或等于,返回值为 1;否则返回值为 0。“>=”不能用于判断空值。7) 大于运算符“>”“>”用来判断左边的操作数是否大于右边的操作数。如果大于,返回值为 1;否则返回值为 0。“>”不能用于判断空值。8) IS NULL(或者 ISNULL)IS NULL 和 ISNULL 用于检验一个值是否为 NULL,如果为 NULL,返回值为 1;否则返回值为 0。9) IS NOT NULLIS NOT NULL 用于检验一个值是否为非 NULL,如果为非 NULL,返回值为 1;否则返回值为 0。10) BETWWEN AND语法格式为:<表达式> BETWEEN <最小值> AND <最大值>若<表达式>大于或等于<最小值>,且小于或等于<最大值>,则 BETWEEN 的返回值为 1;否则返回值为 0。11) LEAST语法格式为:LEAST(<值1>,<值2>,…,<值n>)其中,值 n 表示参数列表中有 n 个值。存在两个或多个参数的情况下,返回最小值。若任意一个自变量为 NULL,则 LEAST() 的返回值为 NULL。12) GREATEST语法格式为:GREATEST (<值1>,<值2>,…,<值n>)其中,值 n 表示参数列表中有 n 个值。存在两个或多个参数的情况下,返回最大值。若任意一个自变量为 NULL,则 GREATEST() 的返回值为 NULL。13) ININ 运算符用来判断操作数是否为 IN 列表中的一个值。如果是,返回值为 1;否则返回值为 0。14) NOT INNOT IN 运算符用来判断表达式是否为 IN 列表中的一个值。如果不是,返回值为 1;否则返回值为 0。逻辑运算符在 SQL 语言中,所有逻辑运算符求值所得的结果均为 TRUE、FALSE 或 NULL。在 MySQL 中分别体现为 1(TRUE)、0(FALSE)和 NULL。MySQL 中的逻辑运算符如下表所示。逻辑运算符说明NOT 或者 !逻辑非AND 或者 &&逻辑与OR 或者 ||逻辑或XOR逻辑异或下面分别介绍不同的逻辑运算符的使用方法。1) NOT 或者 !逻辑非运算符 NOT 或者 !,表示当操作数为 0 时,返回值为 1;当操作数为非零值时,返回值为 0;当操作数为 NULL 时,返回值为 NULL。2) AND 或者 &&逻辑与运算符 AND 或者 &&,表示当所有操作数均为非零值并且不为 NULL 时,返回值为 1;当一个或多个操作数为 0 时,返回值为 0;其余情况返回值为 NULL。3) OR 或者 ||逻辑或运算符 OR 或者 ||,表示当两个操作数均为非 NULL 值且任意一个操作数为非零值时,结果为 1,否则结果为 0;当有一个操作数为 NULL 且另一个操作数为非零值时,结果为 1,否则结果为 NULL;当两个操作数均为 NULL 时,所得结果为 NULL。4) XOR逻辑异或运算符 XOR。当任意一个操作数为 NULL 时,返回值为 NULL;对于非 NULL 的操作数,若两个操作数都不是 0 或者都是 0 值,则返回结果为 0;若一个为 0,另一个不为非 0,则返回结果为 1。位运算符位运算符是用来对二进制字节中的位进行移位或者测试处理的。MySQL 中提供的位运算符如下表所示。位运算符说明|按位或&按位与^按位异或<<按位左移>>按位右移~按位取反,反转所有比特下面分别介绍不同的位运算符的使用方法。1) 位或运算符“|”位或运算的实质是将参与运算的两个数据按对应的二进制数逐位进行逻辑或运算。若对应的二进制位有一个或两个为 1,则该位的运算结果为 1,否则为 0。2) 位与运算符“&”位与运算的实质是将参与运算的两个数据按对应的二进制数逐位进行逻辑与运算。若对应的二进制位都为 1,则该位的运算结果为 1,否则为 0。3) 位异或运算符“^”位异或运算的实质是将参与运算的两个数据按对应的二进制数逐位进行逻辑异或运算。对应的二进制位不同时,对应位的结果才为 1。如果两个对应位都为 0 或者都为 1,则对应位的结果为 0。4) 位左移运算符“<<”位左移运算符“<<”使指定的二进制值的所有位都左移指定的位数。左移指定位数之后,左边高位的数值将被移出并丢弃,右边低位空出的位置用 0 补齐。语法格式为表达式<<n,这里 n 指定值要移位的位数。5) 位右移运算符“>>”位右移运算符“>>”使指定的二进制值的所有位都右移指定的位数。右移指定位数之后,右边高位的数值将被移出并丢弃,左边低位空出的位置用 0 补齐。语法格式为表达式>>n,这里 n 指定值要移位的位数。6) 位取反运算符“~”位取反运算符的实质是将参与运算的数据按对应的二进制数逐位反转,即 1 取反后变 0,0 取反后变为 1。运算符的优先级决定了不同的运算符在表达式中计算的先后顺序,下表列出了 MySQL 中的各类运算符及其优先级。优先级由低到高排列运算符1=(赋值运算)、:=2II、OR3XOR4&&、AND5NOT6BETWEEN、CASE、WHEN、THEN、ELSE7=(比较运算)、<=>、>=、>、<=、<、<>、!=、 IS、LIKE、REGEXP、IN8|9&10<<、>>11-(减号)、+12*、/、%13^14-(负号)、〜(位反转)15!可以看出,不同运算符的优先级是不同的。一般情况下,级别高的运算符优先进行计算,如果级别相同,MySQL 按表达式的顺序从左到右依次计算。另外,在无法确定优先级的情况下,可以使用圆括号“()”来改变优先级,并且这样会使计算过程更加清晰。
-
在日常工作中,很多数据一旦录入,轻易不会修改,但却常常会被调用。在对数据库有少量写请求,但有大量读请求的应用场景下,单个实例可能无法抵抗读取压力,甚至对主业务产生影响。遇到这种问题该怎么办?别担心,云数据库 TaurusDB只读节点帮您完美解决这个问题,让您轻松应对各种应用场景。为了实现读取能力的弹性扩展,分担数据库压力,您可以在某个区域中创建一个或多个只读节点,利用只读节点满足大量的数据库读取需求,以此增加应用的吞吐量。云数据库 TaurusDB是华为自研的最新一代企业级高扩展海量存储分布式数据库,完全兼容MySQL。基于华为最新一代DFV存储,采用计算存储分离架构,128TB的海量存储,无需分库分表,数据0丢失,既拥有商业数据库的高可用和性能,又具备开源低成本效益。 创建只读节点:只读节点用于增强实例主节点的读能力,减轻主节点负载。一个实例中,最多支持15个只读节点。操作步骤:登录管理控制台。单击管理控制台左上角的,选择区域和项目。选择“数据库 > 云数据库 TaurusDB”。进入云数据库TaurusDB信息页面。在“实例管理”页面,选择指定的实例,单击操作列的“更多 > 创建只读”,进入“创建只读”页面。您也可在实例的“基本信息”页面,单击拓扑图中的,创建只读节点。在“创建只读”页面,选择“故障倒换优先级”和“购买数量”,包周期单击“立即购买”,按需计费单击“立即创建”。 只读节点升主节点TaurusDB是一个多节点的实例,其中一个节点是主节点(Master),其他节点为只读节点。除了因系统故障自动切换主备外,对于用于高可用演练,或者需指定某个节点为主节点的场景,您也可以手动切换主备,指定一个只读节点为新的主节点。手动切换:登录管理控制台。单击管理控制台左上角的,选择区域和项目。选择“数据库 > 云数据库 TaurusDB”。进入云数据库TaurusDB信息页面。在“实例管理”页面的实例列表中,选择对应实例,单击实例名称进入“基本信息”页面。在“基本信息”页面底部,选择目标只读节点,在“操作”列单击“只读升主”。 在弹出框中单击“是”下发请求。a) 切换时可能会出现30秒左右的闪断,请确保应用具备重连机制。b) 切换过程中节点运行状态为“只读升主中”,此过程大概需要几秒或几分钟。c) 切换完成后,节点运行状态变为“正常”,您可查看到原先的只读节点和主节点的角色已经互换。 自动切换:TaurusDB采用双活(Active-Active)的高可用实例架构,可读写的主节点和只读节点之间自动进行故障倒换(Failover),系统自动选取新的主节点。TaurusDB每个节点都有一个故障倒换优先级,决定了故障倒换时被选取为主节点的概率高低。故障倒换优先级的取值范围为1~16,数字越小,优先级越高,即故障倒换时,主节点会优先倒换到优先级高的只读节点上。当多个节点的优先级相同时,这些节点具有相同的概率被选取为主节点。TaurusDB按以下步骤自动选取主节点:系统找出当前可以被选取的所有只读节点。选择优先级最高的一个或多个只读节点。如果由于网络原因、复制状态异常等,第一个节点切换失败,则会尝试切换下一个,直至成功。 删除只读节点对于“按需计费”模式的只读节点,您可根据业务需要,在TaurusDB数据库“基本信息”页面手动删除来释放资源。只读节点删除后,不可恢复,请谨慎操作。操作步骤:登录管理控制台。单击管理控制台左上角的,选择区域和项目。选择“数据库 > 云数据库 TaurusDB”。进入云数据库TaurusDB信息页面。在“实例管理”页面的实例列表中,选择对应实例,单击实例名称进入“基本信息”页面。在“基本信息”页面底部,选择目标只读节点,在“操作”列单击“删除”。为保证高可用,系统会保留一个正常只读节点不可被单独删除,只有删除实例时,才会被删除。在弹出框中单击“是”下发请求,稍后刷新“实例管理”页面,查看删除结果。 赶紧戳这里,了解详情吧~~
-
MySQL 默认开启事务自动提交模式,即除非显式的开启事务(BEGIN 或 START TRANSACTION),否则每条 SOL 语句都会被当做一个单独的事务自动执行。但有些情况下,我们需要关闭事务自动提交来保证数据的一致性。下面主要介绍如何设置事务自动提交模式。在 MySQL 中,可以通过 SHOW VARIABLES 语句查看当前事务自动提交模式,如下所示:mysql> SHOW VARIABLES LIKE 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 1 row in set, 1 warning (0.04 sec)结果显示,autocommit 的值是 ON,表示系统开启自动提交模式。在 MySQL 中,可以使用 SET autocommit 语句设置事务的自动提交模式,语法格式如下:SET autocommit = 0|1|ON|OFF;对取值的说明:值为 0 和值为 OFF:关闭事务自动提交。如果关闭自动提交,用户将会一直处于某个事务中,只有提交或回滚后才会结束当前事务,重新开始一个新事务。值为 1 和值为 ON:开启事务自动提交。如果开启自动提交,则每执行一条 SQL 语句,事务都会提交一次。示例下面我们关闭事务自动提交,模拟银行转账。使用 SET autocommit 语句关闭事务自动提交,且张三转给李四 500 元,SQL 语句和运行结果如下:mysql> SET autocommit = 0; ; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM mybank.bank; +--------------+--------------+ | customerName | currentMoney | +--------------+--------------+ | 张三 | 1000.00 | | 李四 | 1.00 | +--------------+--------------+ 2 rows in set (0.00 sec) mysql> UPDATE bank SET currentMoney = currentMoney-500 WHERE customerName='张三' ; Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> UPDATE bank SET currentMoney = currentMoney+500 WHERE customerName='李四'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0这时重新打开一个 cmd 窗口,查看 bank 数据表中张三和李四的余额,SQL 语句和运行结果如下所示:mysql> SELECT * FROM mybank.bank; +--------------+--------------+ | customerName | currentMoney | +--------------+--------------+ | 张三 | 1000.00 | | 李四 | 1.00 | +--------------+--------------+ 2 rows in set (0.00 sec)结果显示,张三和李四的余额是事务执行前的数据。下面在之前的窗口中使用 COMMIT 语句提交事务,并查询 bank 数据表的数据,如下所示:mysql> COMMIT; Query OK, 0 rows affected (0.07 sec) mysql> SELECT * FROM mybank.bank; +--------------+--------------+ | customerName | currentMoney | +--------------+--------------+ | 张三 | 500.00 | | 李四 | 501.00 | +--------------+--------------+ 2 rows in set (0.00 sec)结果显示,bank 数据表的数据更新成功。在本例中,关闭自动提交后,该位置会作为一个事务起点,直到执行 COMMIT 语句和 ROLLBACK 语句后,该事务才结束。结束之后,这就是下一个事务的起点。关闭自动提交功能后,只用当执行 COMMIT 命令后,MySQL 才将数据表中的资料提交到数据库中。如果执行 ROLLBACK 命令,数据将会被回滚。如果不提交事务,而终止 MySQL 会话,数据库将会自动执行回滚操作。使用 BEGIN 或 START TRANSACTION 开启一个事务之后,自动提交将保持禁用状态,直到使用 COMMIT 或 ROLLBACK 结束事务。之后,自动提交模式会恢复到之前的状态,即如果 BEGIN 前 autocommit = 1,则完成本次事务后 autocommit 还是 1。如果 BEGIN 前 autocommit = 0,则完成本次事务后 autocommit 还是 0。
-
日志文件类型MySQL有几个不同的日志文件,可以帮助你找出mysqld内部发生的事情日志文件记入文件中的信息类型错误日志记录启动、运行或停止mysqld时出现的问题。查询日志记录建立的客户端连接和执行的语句。更新日志记录更改数据的语句。不赞成使用该日志。二进制日志记录所有更改数据的语句。还用于复制。慢日志记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询。默认情况下,所有日志创建于mysqld数据目录中。通过刷新日志,你可以强制 mysqld来关闭和重新打开日志文件(或者在某些情况下切换到一个新的日志)。当你执行一个FLUSH LOGS语句或执行mysqladmin flush-logs或mysqladmin refresh时,出现日志刷新。错误日志错误日志文件包含了当mysqld启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。如果mysqld莫名其妙地死掉并且mysqld_safe需要重新启动它,mysqld_safe在错误日志中写入一条restarted mysqld消息。如果mysqld注意到需要自动检查或着修复一个表,则错误日志中写入一条消息。在一些操作系统中,如果mysqld死掉,错误日志包含堆栈跟踪信息。跟踪信息可以用来确定mysqld死掉的地方。可以用--log-error[=file_name]选项来指定mysqld保存错误日志文件的位置。如果没有给定file_name值,mysqld使用错误日志名host_name.err 并在数据目录中写入日志文件。如果你执行FLUSH LOGS,错误日志用-old重新命名后缀并且mysqld创建一个新的空日志文件。(如果未给出--log-error选项,则不会重新命名)。如果不指定--log-error,或者(在Windows中)如果你使用--console选项,错误被写入标准错误输出stderr。通常标准输出为你的终端。通用查询日志如果你想要知道mysqld内部发生了什么,你应该用--log[=file_name]或-l [file_name]选项启动它。如果没有给定file_name的值, 默认名是host_name.log。所有连接和语句被记录到日志文件。当你怀疑在客户端发生了错误并想确切地知道该客户端发送给mysqld的语句时,该日志可能非常有用。mysqld按照它接收的顺序记录语句到查询日志。这可能与执行的顺序不同。这与更新日志和二进制日志不同,它们在查询执行后,但是任何一个锁释放之前记录日志。(查询日志还包含所有语句,而二进制日志不包含只查询数据的语句)。服务器重新启动和日志刷新不会产生新的一般查询日志文件(尽管刷新关闭并重新打开一般查询日志文件)。在Unix中,你可以通过下面的命令重新命名文件并创建一个新文件: shell> mv hostname.log hostname-old.log shell> mysqladmin flush-logs shell> cp hostname-old.log to-backup-directory shell> rm hostname-old.log慢速查询日志用--log-slow-queries[=file_name]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。获得初使表锁定的时间不算作执行时间。如果没有给出file_name值, 默认未主机名,后缀为-slow.log。如果给出了文件名,但不是绝对路径名,文件则写入数据目录。语句执行完并且所有锁释放后记入慢查询日志。记录顺序可以与执行顺序不相同。慢查询日志可以用来找到执行时间长的查询,可以用于优化。但是,检查又长又慢的查询日志会很困难。要想容易些,你可以使用mysqldumpslow命令获得日志中显示的查询摘要来处理慢查询日志。在MySQL 5.1的慢查询日志中,不使用索引的慢查询同使用索引的查询一样记录。要想防止不使用索引的慢查询记入慢查询日志,使用--log-short-format选项。在MySQL 5.1中,通过--log-slow-admin-statements服务器选项,你可以请求将慢管理语句,例如OPTIMIZE TABLE、ANALYZE TABLE和 ALTER TABLE写入慢查询日志。用查询缓存处理的查询不加到慢查询日志中,因为表有零行或一行而不能从索引中受益的查询也不写入慢查询日志二进制日志二进制文件介绍二进制日志以一种更有效的格式,并且是事务安全的方式包含更新日志中可用的所有信息。二进制日志包含了所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的所有语句。语句以“事件”的形式保存,它描述数据更改。备注:二进制日志已经代替了老的更新日志,更新日志在MySQL 5.1中不再使用。二进制文件的行为二进制日志还包含关于每个更新数据库的语句的执行时间信息。它不包含没有修改任何数据的语句。如果你想要记录所有语句(例如,为了识别有问题的查询),你应使用一般查询日志。二进制日志的主要目的是在恢复使能够最大可能地更新数据库,因为二进制日志包含备份后进行的所有更新。二进制日志还用于在主复制服务器上记录所有将发送给从服务器的语句。运行服务器时若启用二进制日志则性能大约慢1%。但是,二进制日志的好处,即用于恢复并允许设置复制超过了这个小小的性能损失。二进制文件的文件路径当用--log-bin[=file_name]选项启动时,mysqld写入包含所有更新数据的SQL命令的日志文件。如果未给出file_name值, 默认名为-bin后面所跟的主机名。如果给出了文件名,但没有包含路径,则文件被写入数据目录。建议指定一个文件名.如果你在日志名中提供了扩展名(例如,--log-bin=file_name.extension),则扩展名被悄悄除掉并忽略。mysqld在每个二进制日志名后面添加一个数字扩展名。每次你启动服务器或刷新日志时该数字则增加。如果当前的日志大小达到max_binlog_size,还会自动创建新的二进制日志。如果你正使用大的事务,二进制日志还会超过max_binlog_size:事务全写入一个二进制日志中,绝对不要写入不同的二进制日志中。为了能够知道还使用了哪个不同的二进制日志文件,mysqld还创建一个二进制日志索引文件,包含所有使用的二进制日志文件的文件名。默认情况下与二进制日志文件的文件名相同,扩展名为'.index'。你可以用--log-bin-index[=file_name]选项更改二进制日志索引文件的文件名。当mysqld在运行时,不应手动编辑该文件;如果这样做将会使mysqld变得混乱。二进制日志选项 可以使用下面的mysqld选项来影响记录到二进制日志知的内容。又见选项后面的讨论。--binlog-do-db=db_name告诉主服务器,如果当前的数据库(即USE选定的数据库)是db_name,应将更新记录到二进制日志中。其它所有没有明显指定的数据库 被忽略。如果使用该选项,你应确保只对当前的数据库进行更新。对于CREATE DATABASE、ALTER DATABASE和DROP DATABASE语句,有一个例外,即通过操作的数据库来决定是否应记录语句,而不是用当前的数据库。一个不能按照期望执行的例子:如果用binlog-do-db=sales启动服务器,并且执行USE prices; UPDATE sales.january SET amount=amount+1000;,该语句不写入二进制日志。--binlog-ignore-db=db_name告诉主服务器,如果当前的数据库(即USE选定的数据库)是db_name,不应将更新保存到二进制日志中。如果你使用该选项,你应确保只对当前的数据库进行更新。一个不能按照你期望的执行的例子:如果服务器用binlog-ignore-db=sales启动,并且执行USE prices; UPDATE sales.january SET amount=amount+1000;,该语句不写入二进制日志。类似于--binlog-do-db,对于CREATE DATABASE、ALTER DATABASE和DROP DATABASE语句,有一个例外,即通过操作的数据库来决定是否应记录语句,而不是用当前的数据库。要想记录或忽视多个数据库,使用多个选项,为每个数据库指定相应的选项。服务器根据下面的规则对选项进行评估,以便将更新记录到二进制日志中或忽视。请注意对于CREATE/ALTER/DROP DATABASE语句有一个例外。在这些情况下,根据以下规则,所创建、修改或删除的数据库将代替当前的数据库。1. 是否有binlog-do-db或binlog-ignore-db规则?·没有:将语句写入二进制日志并退出。·有:执行下一步。2.有一些规则(binlog-do-db或binlog-ignore-db或二者都有)。当前有一个数据库(USE是否选择了数据库?)?·没有:不要写入语句,并退出。·有:执行下一步。3.有当前的数据库。是否有binlog-do-db规则?· 有:当前的数据库是否匹配binlog-do-db规则?o有:写入语句并退出。o没有:不要写入语句,退出。· No:执行下一步。4.有一些binlog-ignore-db规则。当前的数据库是否匹配binlog-ignore-db规则?·有:不要写入语句,并退出。·没有:写入查询并退出。例如,只用binlog-do-db=sales运行的服务器不将当前数据库不为sales的语句写入二进制日志(换句话说,binlog-do-db有时可以表示“忽视其它数据库”)。如果你正进行复制,应确保没有从服务器在使用旧的二进制日志文件,方可删除它们。
-
日志是所有应用的重要数据,MySQL 也有错误日志、查询日志、慢查询日志、事务日志等。当笔记的查看:二进制日志 binlog二进制日志 binlog 用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。使用任何存储引擎的 mysql 数据库都会记录 binlog 日志。在 binlog 中记录的是逻辑日志,也就是 SQL 语句。SQL 语句执行后,binlog 追加到日志文件中。可以设置 binlog 文件大小,超过大小后,自动创建新的文件。binlog 有三种格式,分别为 STATMENT、ROW 和 MIXED。STATMENT:把会修改数据的 sql 语句记录到 binlog 中;是 MySQL 5.7.7 之前的默认格式;ROW:不记录每条 sql 语句的上下文信息,仅记录哪条数据被修改了;是 MySQL 5.7.7之后的默认格式;MIXED:基于 STATMENT 和 ROW 两种模式的混合复制,一般使用 STATEMENT 模式,对于无法复制的操作使用 ROW 模式;在实际应用中,binlog 主要用于主从复制和数据恢复。主从复制是指在 master 机器开启 binlog,通过某种方式把 binlog 发送给 slave 机器,slave 机器根据 binlog 内容进行数据操作,从而保证主从数据一致性。另外,通过使用 mysqlbinlog 工具可以从 binlog 恢复数据。在 MySQL 5.7 之后,内置默认引擎已经变更为 InnoDB 引擎。 InnoDB 引擎在处理事务时,可以设置日志写入磁盘的时机,默认情况下是每次 commit 时写入磁盘。也可以通过 sync_binlog 参数设置成系统自动判断或每 N 个事务写入一次。查询日志查询日志记录了所有数据库请求的信息。无论这些请求是否得到了正确的执行。开启之后对性能有比较大的影响,因此使用不多。慢查询日志慢查询日志用来记录执行时间超过某个阈值的语句。执行时间阈值可以通过 long_query_time 来设置,默认是 10 秒。慢查询日志需要手动开启,对性能有一些影响,一般不建议开启。慢查询日志支持将记录写入文件,也支持写入数据库表事务日志 redo log事务的四大特性之一是持久性。因此事务成功后,数据库的修改永久保存,不能因为任何原因而回到原来的状态。redo log 是 InnoDB 引擎层实现的日志,并不是所有引擎都有,用来记录事务对数据页的修改,可以在崩溃时用于恢复数据。redo log 包括内存中的日志缓冲和磁盘上的日志文件。执行 SQL 语句后,先写入日志缓冲,后续再一次性把多条缓冲写入文件。在 InnoDB 中,数据页也会刷盘,redo log 存在的意义主要就是降低对数据页刷盘的要求。数据页的变更,redo log 没有必要全部保存。如果数据页刷盘比 redo log 快,则 redo log 的记录对于数据恢复意义不大;如果数据页刷盘比 redo log 慢,则 redo log 中比数据页快的部分可以用来快速恢复数据。因此 redo log 日志文件大小是固定的,当写到结尾时,会回到开头循环写日志事务日志 undo log事务的四大特性之一是原子性。对数据库的一系列操作,要么全部成功,要么全部失败,不允许部分成功部分失败。因此,需要记录数据的逻辑变化。原子性通过 undo log 来实现,比如事务中执行一条 insert 语句,undo log 就会记录一条 delete 语句;事务中执行一条 update 语句,undo log 就会记录一条相反的 update 语句。这样在事务失败时,就可以通过 undo log 来回滚到事务之前的状态。
-
一、Elasticsearch单独使用1、Elasticsearch安装(建议Linux系统):步骤一:安装较新版本的Java,确保环境变量配置正确,JDK版本不能低于1.7_55。步骤二:安装Elasticsearch:https://www.elastic.co/cn/downloads/elasticsearch Linux版本$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.0-linux-x86_64.tar.gz $ tar -xzf elasticsearch-7.10.0-linux-x86_64.tar.gz windows版本:官网下载windows版本安装包,解压。2、Elasticsearch启动$ cd elasticsearch-7.10.0/$ ./bin/elasticsearch (Linux版本) $ .\bin\elasticsearch.bat (windows版本)运行成功后,浏览器访问http://localhost:9200/?pretty页面出现如下信息意味着启动成功了!!!或者打开另一个终端 执行:curl 'http://localhost:9200/?pretty' ,与上一种方式启动成功信息显示一致。(windows可以安装cURL)。可以搭配图形用户界面一起使用,安装kibana(https://www.elastic.co/guide/en/kibana/4.6/index.html), 与 elasticsearch 版本对应即可。二、Node连接MySQL1、安装ES模块$ npm install elasticsearch --save2、安装MySQL驱动$ npm install mysql --save3、这里的框架使用的是koa,先写配置文件,代码如下:4、插入数据,测试数据使用 [Faker-zh-cn.js](https://github.com/layerssss/Faker-zh-cn.js) 生成。5、使用ES全文高亮搜索,代码如下:
-
MySQL 的查询日志支持写入到文件或写入数据表两种输出形式。启用了普通查询日志或慢查询日志功能后,可以选择让服务器把日志写入到日志文件、mysql 数据库中的日志表、或者同时写到这两个地方。可以通过以下命令查看日志输出类型:mysql> SHOW VARIABLES LIKE '%log_out%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_output | FILE | +---------------+-------+ 1 row in set, 1 warning (0.08 sec)结果显示,日志输出类型为 FILE。要想在运行时更改日志输出目标,可以在启动服务器时,设置全局系统变量 log_output 的值,格式如下:SET GLOBAL log_output='value';value 的值可以是:FILE:表示把日志写入到文件。如果未指定 log_output 的值,默认为 FILE。TABLE:表示把日志写入到 mysql 数据库的 slow_log 或 general_log 表中。MySQL 可以同时支持 2 种日志存储方式,配置的时候以逗号隔开,即 log_output='FILE,TABLE'。需要注意的是,系统变量 log_output 只确定了日志使用什么输出目标,并不会启用日志功能。相对于写入到文件,日志写入到数据表中要耗费更多的系统资源。因此,对于需要启用查询日志,又需要获得更高的系统性能,建议优先选择将日志写入到文件。日志表(slow_log 或 general_log)中的内容只允许查看,不允许修改,除非服务器自己进行更改。因此,你只能对日志表使用 SELECT 语句,不能使用 INSERT、DELETE 或 UPDATE 语句。不过,可以使用 TRUNCATE TABLE 语句来清空日志表。例 首先设置日志写入到日志表,然后查询 test 数据库中 tb_student 数据表的记录,并查看 mysql 数据库中的 slow_log 表中的记录。SQL 语句和运行结果如下:mysql> SET GLOBAL log_output='TABLE'; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE '%log_out%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_output | TABLE | +---------------+-------+ 1 row in set, 1 warning (0.01 sec) mysql> use test; Database changed mysql> SELECT * FROM tb_student; +----+--------+ | id | name | +----+--------+ | 1 | Java | | 2 | MySQL | | 3 | Python | +----+--------+ 3 rows in set (0.00 sec) mysql> SELECT * FROM mysql.slow_log \G *************************** 1. row *************************** start_time: 2020-06-04 15:25:40.030420 user_host: root[root] @ localhost [::1] query_time: 00:00:00.058887 lock_time: 00:00:00.000000 rows_sent: 0 rows_examined: 0 db: test last_insert_id: 0 insert_id: 0 server_id: 1 sql_text: TRUNCATE TABLE mysql.slow_log thread_id: 11 *************************** 2. row *************************** start_time: 2020-06-04 15:25:52.229014 user_host: root[root] @ localhost [::1] query_time: 00:00:00.000339 lock_time: 00:00:00.000000 rows_sent: 1 rows_examined: 0 db: test last_insert_id: 0 insert_id: 0 server_id: 1 sql_text: Init DB thread_id: 11 *************************** 3. row *************************** start_time: 2020-06-04 15:26:00.867649 user_host: root[root] @ localhost [::1] query_time: 00:00:00.000379 lock_time: 00:00:00.000115 rows_sent: 7 rows_examined: 7 db: test last_insert_id: 0 insert_id: 0 server_id: 1 sql_text: SELECT * FROM tb_student thread_id: 11 3 rows in set (0.00 sec)结果显示,超过慢查询日志指定时间的 SQL 语句都写入到了 mysql 数据库的 slow_log 表中。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签