【MySQL】笔记(1)— MySQL 数据库概述;常用 DOS命令,SQL命令(初步);

数据库104
  1. sql、DB、DBMS分别是什么,他们之间的关系?
    DB:
    DataBase(数据库,数据库实际上在硬盘上以文件的形式存在)

DBMS:
DataBase Management System(数据库管理系统,常见的有:MySQL Oracle ...)

SQL:
结构化查询语言,是一门标准通用的语言。标准的sql适合于所有的数据库产品。
SQL属于高级语言。只要能看懂英语单词的,写出来的sql语句,可以读懂什么意思。
SQL语句在执行的时候,实际上内部也会先进行编译,然后再执行sql(sql语句的编译由DBMS完成);

DBMS -(执行)-> SQL -(操作)-> DB(DBMS负责执行sql语句,通过执行sql语句来操作DB当中的数据)

  1. 什么是表?

表:table是数据库的基本组成单元,所有的数据都以表格的形式组织,目的是可读性强。

一个表包括行和列:
行:被称为数据/记录(data)
列:被称为字段(column)

学号(int) 姓名(varchar) 年龄(int)

Original: https://www.cnblogs.com/Burning-youth/p/15675990.html
Author: 猿头猿脑的王狗蛋
Title: 【MySQL】笔记(1)--- MySQL 数据库概述;常用 DOS命令,SQL命令(初步);



相关阅读1

Title: 排序规则

一、什么是排序规则

mysql官网的说法

The collation is a set of rules (only one rule in this case): "compare the encodings." We call this simplest of all possible collations a binary collation.

排序规则是一套规则(在这种情况下,只有一个规则):"比较编码。"我们把这种简单的所有可能的归类的二进制 排序规则。
https://dev.mysql.com/doc/refman/8.0/en/charset-general.html

《高性能mysql》中的说法

【MySQL】笔记(1)— MySQL 数据库概述;常用 DOS命令,SQL命令(初步);

《mysql是怎样运行的》中的说法

没找到电子版,只能拍照了
【MySQL】笔记(1)— MySQL 数据库概述;常用 DOS命令,SQL命令(初步);

二、我的理解

排序规则是针对字符串而言的,当有两个字符串想要比较大小时,排序规则才有意义。

类型对数据比较的影响

非字符串类型

要么天然就有排序规则(如:int,值的大小比较,就是他的排序规则;日期,日期及时间的早晚就是排序规则)
要么天然就没有办法比较(如二进制存储的图片,虽然二进制本身可以比较,但比较的结果对于图片而言没有意义)

字符串类型

也有一种天然的比较方式,类似于Java中字符串String类型的compareTo方法,即使用字符串中的字符的对应编码的大小来比较。

特殊情况

然而,有一些字符串比较的需求就很有意思了
如中文'一二三四'对应的unicode字符编码是19968,20108,19977,22235,【这里使用unicode编码仅仅是用来举例,就算是其他编码也可能会出现类似情况】
使用Java代码计算编码

System.out.println((int)'一');
System.out.println((int)'二');
System.out.println((int)'三');
System.out.println((int)'四');

中文

比较
如果想比较'一百二十'与'一百三十'两个中文字符串

结果
显而易见,正常人期待的结果都是:'一百二十'小于'一百三十'。
然而以字符串对比来说,
先比较第一个字符'一',相等;
再比较第二个字符'百',也相等;
再比较第三个字符'二'与'三',结果二比三大;
那么'一百二十'大于'一百三十',
这个结果是反人类的,至少是反中国人的。
可以使用Java代码计算比较结果

System.out.println("一百三十".compareTo("一百二十"));

执行结果是-131,
结果是负的,说明"一百三十"小于"一百二十",这确实不是正常人期待的结果。

英语特殊情况举例

同理对比Apple和apple,正常人期待的结果是相等
使用Java代码

System.out.println("Apple".compareTo("apple"));

执行结果是-32
负的,说明"Apple"小于"apple",这也不是正常人期待的结果。

他拉丁语系的特殊情况举例

希望大小写不敏感,雷同英语

日语的特殊情况

期待:平假名和片假名被视为相等,下面的链接是日语的情况。
https://www.it1352.com/1898650.html

三、实现方式

类似的在一个语言中,期望在文本比较时,针对某些大小写或者简繁体对应字符相等,我们需要专门制作一种规则
这种规则在文本比较时使用,就叫做校对规则,而大部分情况只有排序时才会比较字符的大小,所以也叫排序规则。

Java实现

当Java想排序时,要么你的泛型实现了接口Comparable,要么你实现一个Comparator接口的类。
类似的整数类型Integer天然的实现了接口Comparable,下面是类Integer的定义

public final class Integer extends Number implements Comparable

查看实现接口的方法compareTo,其实该方法就是实现一下当两个Integer类型比较时,返回值及表达怎么比较。
而比较器Comparator是描述两个泛型类的实例怎么比较。
那么实现接口Comparable代表着类的实例本身就可以比较,比较器Comparator代表着两个实例使用比较器来比较。

方法compareTo的理解

compareTo就是一个比较的方式,比如class是人,那么身高是一种比较方式,体重也是,财产也是,都可以比较。只是实现compareTo的方式不同,比较的结果就不同。

数据库实现

数据库搞出来个排序规则,其实就是类似Java的String类的compareTo方法怎么实现的,即是排序规则

public final class String
    implements java.io.Serializable, Comparable, CharSequence

即,建表时字符串列必须指定个排序规则,否则没有办法order by 该列,如果不指定即默认逻辑上级的排序规则。
上下级关系是:库,表,列
所以建库时一定要指定排序规则,不能只指定编码。

四、用途

索引使用必须在排序规则相同的字段间
查看博客中:2020-08-02的文章《一次MySQL索引失效引发的思考》
https://www.cnblogs.com/klarck/p/13418706.html
排序规则不同索引会失效

select table_name,column_name,character_set_name,collation_name
from information_schema.columns where table_schema = '库名' and data_type = 'varchar'

字符串本身带排序规则

测试代码如下

CREATE TABLE test1 (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(45) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4  COLLATE utf8mb4_general_ci ;

SET @app_name  = "test-text"  COLLATE utf8mb4_unicode_ci  ;
SELECT * FROM test1 WHERE name = @app_name

报错信息 Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_unicode_ci,IMPLICIT) for operation '='
google翻译:操作'='的排序规则(utf8mb4_general_ci,IMPLICIT)和(utf8mb4_unicode_ci,IMPLICIT)的非法混合
可见,变量@app_name携带了排序规则utf8mb4_unicode_ci。

mysql字符串可以比较大小

那么max可以计算字符串字段
例如以之前的表为例

SELECT MAX(name) FROM test1;

Original: https://www.cnblogs.com/klarck/p/15784148.html
Author: 一剑破万法
Title: 排序规则

相关阅读2

Title: MySql Explain字段解析

MySql Explain字段解析

【MySQL】笔记(1)— MySQL 数据库概述;常用 DOS命令,SQL命令(初步);

id

id列表示select的序号,查询Sql中有几个select就会有几个id。

id的值越大,该查询的优先级超高。

select_type

查询类型,Mysql的查询类型有:简单查询、复杂查询

  1. SIMPLE(简单查询)
  2. PRIMARY(复杂查询的最外层查询)
  3. SUBQUERY(复杂查询的子查询,出现在select或者where的子句中),
  4. DERIVED(复杂查询的FROM子句中的查询标记为DERIVED,MySql会将结果放在一个临时表中、也称为派生表)
  5. UNION(复杂查询中出现在UNION后面的查询标记为UNION)

table:

表示该查询的访问的是哪个表,可以是具体的表名,也可以是派生表 其中数字3表示该表是丛id为3的查询中派生出来的

partitions:

分区表会用上,使用极少,具体用法自行百度

type:

查询的类型,查询效率从高到低为

  1. NULL:表示在优化阶段就可以分解语句,此时在执行分段都不需要扫描表和索引,直接就可以拿到结果。如:查询主键id的最小值(select min(id) from table ),这里不需要扫描就可以从索引中直接拿到第一个id就是最小id
  2. system/const: 表示在优化阶段可以直接优化为常量,比如:select * from table where id =3 这个查询可以优化为 select 3 as id , name,... from table where id =3 ,这时id列的值其实已经确定了
  3. eq_ref:表示使用了唯一索引或者主键索引时,如:select * from table where id =1 ,因为id是主键索引,已经可以确定结果就只可能最多为一个数据。
  4. ref:表示使用了某个索引与一个具体的值比较,如:select * from table where name='tom' 这时不能确定结果的数量,但是这种查询可以扫描索引来得到结果,且结果在索引中一定是连续的
  5. rang:表示使用索引时是一个范围扫描,select * from table where id > 100 or id

possible_keys:可能使用上的索引列,或者说可以使用上的索引

key:查询实际使用的索引列,当key中出现了一个索引,但是没有在possible_keys中出现,这可能是因为使用了聚簇索引

key_len:

使用索引长度,比如有个联合索引时,可能不会使用到联合索引的全部字段,只有上了前几个,这时就可以根据key_len字段来计算出到底使用了几个字段。

【MySQL】笔记(1)— MySQL 数据库概述;常用 DOS命令,SQL命令(初步);

ref:

表示在查询中与key列索引作比较所使用的值是什么类型

  1. const: 表示使用的是常量
  2. table.id: 表示使用的是表的id字段

rows:

查询所需要读取数据的行数

filtered:

Mysql5.1加入,表示的是针对 表里符合某个条件的记录数百分比(悲观计算),如果你把rows列和这个百分比相乘,就可以大概计算出这个查询的结果行数

Extra:

额外信息

  1. using index : 表示使用了覆盖索引
  2. using where:表示储存引擎会把结果返回的Mysql查询服务器,然后使用where条件进行过滤
  3. using temporary: 表示对查询结果进行排序或者去重等操作时使用了临时表
  4. using filesort:表示对查询结果排序时使用了外部文件

Original: https://www.cnblogs.com/xysgo/p/16061182.html
Author: 菜阿
Title: MySql Explain字段解析

相关阅读3

Title: Mysql 索引

索引的目的在于提高查询效率

一 索引分类

1、普通索引 index

加速查询

2、唯一索引

2.1、主键索引 primary key

加速查询+约束(不为空且唯一)

2.2、唯一索引 unique

加速查询+约束(唯一)

3、联合索引

-- index(id,name) 联合普通索引

-- primary key(id,name) 联合主键索引

-- unique(id,name) 联合唯一索引

4、全文索引 fulltext

用于搜索很长文章的时候效果最好。

5、空间索引 spatial

二 索引类型

我们可以在创建索引的时候,为其指定索引类型,分两类

1、hash类型

查询单条快,范围查询慢

2、btree类型 B+树

b+树,层级越多,数据量指数级增长

不同的存储引擎支持的索引类型也不一样

InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;

MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;

Memory 不支持事务,支持表级别锁定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;

NDB 支持事务,支持行级别锁定,支持 Hash 索引,不支持 B-tree、Full-text 等索引;

Archive 不支持事务,支持表级别锁定,不支持 B-tree、Hash、Full-text 等索引;

三 创建\删除索引的语法

1、创建索引

在创建表时就添加索引 及 注意事项

create table TABLE_NAME(

id int, # 可以添加primary key

id int index, # 不可以这么添加索引,因为index是普通索引,没有约束一说,所以不能像主键索引和唯一索引那样在定义字段的时候加索引

name char(20),

age int,

email varchar(30)

primary key(id) # 也可以为主键这样添加索引

index(id) # 虽然不能在定义字段的同时添加普通索引,但是通过这种方式为字段添加普通索引

在创建表之后添加索引

create index name on TABLE_NAME(name); # 添加普通索引

create unique age on TABLE_NAME(age); # 添加唯一索引

alter table TABLE_NAME add primary key(id); # 添加主键索引,也就是给id字段增减一个主键约束

create index name on TABLE_NAME(id,name); # 添加普通联合索引

2、删除索引

drop index name on TABLE_NAME; # 删除普通索引

drop index age on TABLE_NAME; # 删除唯一索引,就和普通索引一样,不用在index前加unique就可以删除

alter table TABLE_NAME drop promary key; # 删除主键(因为它添加的时候是按照alter来增加的,那么我们也用alter来删)

四 测试索引

1、准备表
create table TABLE_NAME(
id int,
name varchar(20),
gender char(6),
email varchar(50)
);

2、创建存储过程,实现批量插入记录
delimiter $$ #声明存储过程的结束符号为$$
create procedure auto_insert1()
BEGIN
declare i int default 1;
while(i

3、查看存储过程
show create procedure auto_insert1\G

4、调用存储过程
call auto_insert1();

五 正确使用索引

1、覆盖索引

分析

select * from TABLE_NAME where id=123;

该sql命中了索引,但未覆盖索引。

利用id=123到索引的数据结构中定位到该id在硬盘中的位置,或者说再数据表中的位置。

但是我们select的字段为*,除了id以外还需要其他字段,这就意味着,我们通过索引结构取到id还不够,

还需要利用该id再去找到该id所在行的其他字段值,这是需要时间的,很明显,如果我们只select id,

就减去了这份苦恼,如下

select id from TABLE_NAME where id=123;

这条就是覆盖索引了,命中索引,且从索引的数据结构直接就取到了id在硬盘的地址,速度很快

2、联合索引

create index ne on s1(name,email);#组合索引

3、索引合并

索引合并:把多个单列索引合并使用

分析:

组合索引能做到的事情,我们都可以用索引合并去解决,比如

create index ne on s1(name,email);#组合索引

我们完全可以单独为name和email创建索引

组合索引可以命中:

select * from s1 where name='egon' ;

select * from s1 where name='egon' and email='adf';

索引合并可以命中:

select * from s1 where name='egon' ;

select * from s1 where email='adf';

select * from s1 where name='egon' and email='adf';

乍一看好像索引合并更好了:可以命中更多的情况,但其实要分情况去看,如果是name='egon' and email='adf',

那么组合索引的效率要高于索引合并,如果是单条件查,那么还是用索引合并比较合理

4、添加索引遵循原则

1、最左前缀匹配原则,非常重要的原则,

create index ix_name_email on s1(name,email,)

  • 最左前缀匹配:必须按照从左到右的顺序匹配

select * from s1 where name='egon'; #可以

select * from s1 where name='egon' and email='asdf'; #可以

select * from s1 where email='alex@oldboy.com'; #不可以

mysql会一直向右匹配直到遇到范围查询(>、

Original: https://www.cnblogs.com/ganguixu/p/15798198.html
Author: 干桂旭
Title: Mysql 索引