MySQL学习笔记

序言

这是很久以前刚开始学习MySql的笔记 ,所以会有些内容未完善,BBy过段时间复习数据库时在进行完善

终端开启数据库
  • 开启服务器: net start MySQL80 #一定要在管理员权限下执行
  • 关闭服务器: net stop MySQL80
  • 登录MySQL: mysql -h 127.0.0.1 -uroot -pPassword
  • 退出登录: exit
数据库基础知识
  • 关系数据库是建立在关系模型上的,而关系模型本质上就是若干个存储数据的二维表,可以把它们看作很多Excel表。
  • 表中的数据(除字段外每一行)称为记录。
  • 表中的列称为字段,即属性。
  • 数据中的NULL与C/C++语言中NULL不同,NULL表示字段数据不存在,即:一个整型字段如果为NULL不表示它的值为0,同样的,一个字符串型字段为NULL也不表示它的值为空串""。
  • 通常情况下,字段应该避免允许为NULL。不允许为NULL可以简化查询条件,加快查询速度,也利于应用程序读取数据后无需判断是否为NULL。
命名规则
  • MySQL 的命名规则同C/C++ 相似,是由字母、数字、下划线组成。但不同的是MySQL中不区分大小写(数据库名、表名、字段名均不区分大小写)。举个例子:数据库 time 和数据库 TIME 是同一个数据库。
创建数据库
create database db_name;	# db_name 为数据库名

# 使用(进入)数据库
use db_name;
创建数据表
创建数据表单的格式:
CREATE TABLE <表名> ([表定义选项])[表选项][分区选项];
其中,[表定义选项]的格式为:
<列名1> <类型1> [,] <列名n> <类型n>

CREATE TABLE<表名>:指定要创建表的名称,表名称可以被指定为 db_name.tbl_name,以便在特定的数据库中创建表。无论是否有当前数据库,都可以通过这种方式创建。在当前数据库中创建表时,可以省略 db-name。有些数据库可以使用加引号的识别名,例如,'mydb'.'mytbl' 是合法的,但 mysql 是不合法。

<表定义选项>:表创建定义,由列名(col_name)、列的定义(column_definition, 或者叫类型定义)以及可能的空值说明、完整性约束或表索引组成


# 方式一:  先使用表 ,然后在创建具体表单	table_name为表名
 use database_name;
 create table table_name( ... );	
 
# 方式二 使用 数据库名.表名 不进入具体数据表,直接创建,也可以通过这中方式直接操作数据表
 create table database_name.table_name( ... );   
 
 # 两种效果一样,都是在数据库database_name下创建一个为table_name的数据表
字符串类型 – varchar 和 char
  • CHAR类型的长度是固定的,在创建表时就指定了。其长度可以是0~255的任意值。例如,CHAR(100)就是指定CHAR类型的长度为100。CHAR 存储值时,它们会用空格右填充到指定的长度。

  • VARCHAR类型的长度是可变的,在创建表时指定了最大长度。定义时,其最大值可以取0~65535之间的任意值。指定VARCHAR类型的最大值以后,其长度可以在0到最大长度之间。例如,VARCHAR(100)的最大长度是100,但是不是每条记录都要占用100个字节,而是在这个最大值范围内使用多少就分配多少。VARCHAR类型实际占用的空间为字符串的实际长度加1或2,这样即可有效节约系统的空间。至于为什么为字符串实际长度加1或2,是因为在存储varchar类型的变量的时候,要在存储变量的前面将字符串的实际长度存储下来

  • 实战建议

    · 1、 char一定会使用指定的空间,varchar是根据数据来定空间

    · 2、 char的数据查询效率比varchar高:varchar是需要通过后面的记录数来计算

    · 3、 如果确定数据一定是占指定长度,那么使用char类型;

    · 4、 如果不确定数据到底有多少,那么使用varchar类型;

    · 5、 如果数据长度超过255个字符而在65535之内,直接使用varchar

    · 6、 如果字符串尾部要保留空格,必须选择varchar

显示
  • 显示所有数据库: show databases
  • 显示所有数据表: show tables
  • 显示数据表的创建结构: show create table table_name
  • 显示数据表单结构: describe table_name (或则desc table_name)
  • 查看数据表单中的记录: select * from table_name
数据的插入
  • # 插入完整的成员,无需在插入时指定字段
    insert into table_name values('...','...',...);
    
    # 只指定插入成员的一部分属性   未指定的字段要求有默认值(未设置一班默认为NULL)
    insert into table_name (table_property1,table_property2...) values (property_value1,property_value2...);   
    
删除
# 删除数据库:  (删除数据库时 MySQL 不会确认,所以千万要 小心)
 drop database database_name    

# 删除数据表中的某一个条记录: 
 delete from table_name where table_property='value '

# 删除数据表单中的所有记录
 delete from table_name where 1=1
enum 和 set
  • enum 枚举类型, 只取属性值集中的一个 若加了 NOT NULL 属性,则列表中的第一个将成为默认值

    # 格式
     属性名 enum('值1','值2',...,'值n') 
     
    # 创建表单示例
     create table Info(enum('男','女','选择保密')); # 下标从 1 开始:男 --> 1 ; 女 --> 2 ; 选择保密 --> 3  MySQL中实际存储的是编号,而不是列表中的值
    # 数据插入示例
     insert into Info values('男');    #方式一 插入一条性别为 "男" 的记录	
     insert into Info values(2);       #方式二 插入一天性别为 "女" 的记录
    
  • set set类型, 可插入属性 值集合中的一个或多个 取多个值的时候,不同元素之间用 ‘逗号’ 隔开

    # 格式
     属性名 enum('值1','值2',...,'值n')
     
    # 创建表单示例
     create table hobbies(sex('电竞','健身','影视','文学')); # 采用二进制方案,类似于Linux权限 这里采用4个二进制位 分别和属性值一一对应. 0001 --> 文学 ; 0010 --> 影视 ; 0011 --> 影视+文学 ... 依次类推 1111 --> 电竞+健身+影视+文学
    # 数据插入示例
     insert into hobbies values('电竞,文学');  # 插入爱好为 电竞+文学 的记录 注意在一个引号类
     insert into hobbies values(1001);       # 等同于上面一条语句 插入爱好为 电竞+文学 的记录
    
MySQL建表约束
  • 主键约束

    • 它能够唯一确定一张表中的一条记录,也就是我们通过给某个字段添加约束,就可以使得该字段不重复且不为空

    • create table table_name (
      	id int primary key,     # id为属性名,可以修改,在表中不能插入相同id的成员且id不能为空
      	name varchar(20)
      	)
      
    • 联合主键

      create table table_name (
      	id int,
      	name varchar(20),
      	primary key(id,name)       # 只要求 id 和 name 有一个不重复就可以添加
      	);
      
    • 添加主键约束

      # 注意: 如果在创建数据表的时候,忘记创建主键约束了,可以通过如下语句添加
        方法一: alter table table_name add primary key(id); # id 为想要添加主键约束的字段
        方法二: alter table table_name modify id int primary key;
      
      # 删除主键约束
        alter table table_name drop primary key;
      
  • 自增约束

    • AUTO_INCREMENT : 在需要产生唯一标识符或顺序值时,可利用此属性,这个属性只用于整数类型。AUTO_INCREMENT 值一般从 1 开始,每行增加 1。 一个表中最多只能有一个 AUTO_INCREMENT列 。对于任何想要使用 AUTO_INCREMENT 的列,应该定义为 NOT NULL,并定义为 PRIMARY KEY 或定义为 UNIQUE 键。(auto_increment 与primary key 或则 unique 没有先后顺序之分),当指定为 unique (唯一约束)时,插入 id 的值可以为NULL,但实则和不指定一样,id 会按照前面的数字递增.

    • auto_increment是MySQL唯一扩展的完整性约束

    • auto_increment是在曾经存在过的最大值的基础上加一(哪怕最大值的记录删除了,也是在该值上加一)

    • MySQL8中,AUTO_INCREMENT必须设置为键(主键、外键和唯一键均可),否则会报错!(在使用外键的时候,也只是简单的在原来的基础上加一,并不是说会根据父表的值来增加)

    • create table table_name (
      	id int primary key auto_increment,    # id 自增,可以不指定 id ,假如指定了 id
          name varchar(20)                      # 数据表就会按照 id 大小来排序
      	);									       
      	
      
  • 外键约束

    • 涉及到两个表: 父表(主表) 子表(副表) 子表中某个字段的取值范围由父表决定, 即子表该字段依赖于父表中相应的字段 允许外键为空

    • # 举例
      # 班级表
      create table classes (
      	class_id int primary key,
      	name varchar(20)
      	);
      # 学生表
      create table students (
      	StuNO int primary key,
      	name varchar(20),
      	class_id int,
      	foreign key(class_id) references classes(class_id)    # class_id 绑定 班级表的 class_id
      	);
      # 解析:班级表是父表,学生表是子表,在学生表(子表)中添加成员时,要参考父表中的成员,要求与父表一致
      #  1.主表中没有的数据值,在子表中是不可以使用的
      #  2.主表中的记录被副表引用,那么解除联系之前,主表是不可以被删除的
      
  • 唯一约束

    • 约束修饰的字段的值不可以重复,和主键约束的区别是字段可以为空.

    • unique允许受约束的字段出现多个空值,NULL不算重复

    • # 方式一:
      create table user (
      	id int,
      	name varchar(20),
      	unique(name)       # 唯一约束 UNI
      	);
      	
      # 方式二:
      create table user(
      	id int,
      	name varchar(20) unique
      	);
      	
      # 方式三 多个唯一约束
      create table user (
      	id int,
      	name varchar(20),
      	unique(id,name)     # 添加的成员 id 和 name 至少有一个不一样   MUL
      	);
      
    • # 添加唯一约束
        方式一: alter table table_name add unique(table_property);
        方式二: alter table table_name modify name varchar(20) unique; 
      # 删除唯一约束
        alter table table_name drop index table_property;
      
  • 非空约束

    • 修饰的字段不能为空 NULL

    • create table table_name (
      	id int,
      	name varchar(20) not null    # NULL --->no
      	);
      
  • 默认约束

    • 在插入字段的时候,如果没有指定默认约束属性的值,就会使用默认的值

    • create table table_name (
      	name varchar(20),
      	id int default 10     # 当插入时,若 id 的值没有指定,则 id 为默认值 10,如果传递了值,就是								用传递的值
      	);
      
  • 约束的删除

    • 主键

      alter table table_name drop primary key
      
    • 外键或唯一键

      alter table table_name drop index 约束的字段名
      
    • 修改默认值、自增长和非空

      # 增加或删除默认约束、自增长和非空约束的时候直接使用下列语句重定义即可
      alter table table_name modify 列名 类定义
      # 示例 (为class表添加默认约束和非空约束)
       alter table class modify name varchar(20) DEFAULT 'Tom' NOT NULL;
      
更新数据
update table_name set table_property =' new_value' where another_property = ' the value '
                      要更改的数据表属性  更改后的值        另一个属性          数据表中对应的值
                      
# 更新所有的数据 两种方式
update table_name set table_property ='new_value';
update table_name set table_property ='new_value' where 1=1;

数据增删改
  • 删除一个表单中所有的数据记录

    • delete from table_name where 1=1;
      
      # 删除表单 StudInfo 中所有的数据记录
       delete from StudInfo where 1=1;
      
数据据索引
  • 唯一索引

    • 限制该索引的字段必须唯一

    • 创建的格式 — 在创建普通索引的基础上,INDEX 前面加上 unique 限制即可.

      • 创建表时创建索引

        # [] --> 可选部分    
        create table table_name (
        	property1 type1,
        	property2 type2,
        	......
        	propertyn typen,
        	UNIQUE INDEX | KEY 
        	[indexname](property[length] [ASC | DESC]))  # 不指明升降序则默认是升序
        	
        
      • 在已经存在的表上创建索引

        # 方法一: 执行create语句
        create UNIQUE INDEX indexname ON table_name(property [(length)] [ASC |DESC]);
        #方法二: 执行alter table语句
        alter table table_name add UNIQUE INDEX | KEY indexname(property [(length)] [ASC |DESC]);
        
  • 全文索引(英文)

    • 全文索引主要对字符串类型建立基于分词的索引,所谓分词,所有非字母和数字的特数符号都是分词

    • 全文索引才用关键字 FULLTEXT,创建格式和前面如出一辙

    • create table table_name (
      	property1 type1,
      	property2 type2,
      	......
      	propertyn typen,
      	FULLTEXT INDEX | KEY 
      	[indexname](property[length] [ASC | DESC]))  # 不指明升降序则默认是升序
      	
      
    • 全文索引的查询

      # 格式  table_name --> 表名   property_index --> 全文索引字段  contents --> 查找的内容 
      select * from table_name where match(property_index) AGINST('contents') 
      
      # 示例 插入之中的内容所以分开,是形成多个分词
      create table class(name varchar(64),FULLTEXT INDEX index_name(name));
      insert into class values('我们 是一个 大家族');
      # 查询 "我们"、"是一个"、"大家族" 均可查询到. 但是查询 "我们是一个大家族" 就无法查询到
      select * from class where match(name) AGAINST('大家族');
      
      
    • 查询时有意思的地方

    • # INDEX 全文索引 英文	在MySQL中使用全文索引的时候,默认要求单个单词中字母的个数大于2个才能查询到
        create table class(id  int,comment varchar(64),FULLTEXT INDEX index_full(comment));
        insert into class values(1,'Hi,My name is Tom');
        insert into class values(2,'hello,are you ok');
      # 在MySQL中使用全文索引的时候,默认要求单个单词中字母的个数大于2个才能查询到 请看下面的示例
        select * from class where match(comment) AGAINST('is')  # 因为字母的数量小于3,所以查询失败
        select * from class where match(comment) AGAINST('Tom'); # 因为这个单词字母的额数量大2,且在comment字段中拥有,则封装成功 
      
  • 全文索引(中文)

    • 如何配置:在MySQL的配置文件my.ini(Windows 10 默认路径是:C:\ProgramData\MySQL\MySQL Server 8.0)文件中增加如下配置项,配置完成后需要重启MySQL80。
    • 中文索引也是按照分词的方式来建立索引的,比如
  • 单列索引

  • 多列索引

    • 多列索引,是指在创建索引时所关联的字段不是一个字段,而是多个字段,虽然可以通过所关联的字段进行查询,但是只有查询条件中使用了所关联字段中的第一个字段,多列索引才会被使用。

    • # 多列索引 
        create table class(id int,name varchar(20) UNIQUE,teacher varchar(64),index index_mult_col(id,teacher));
        insert into class values(1,'一班','Rock');
        insert into class values(2,'二班','Martian');
        explain select * from class where id > 0;   # 使用多列索引 因为使用了id字段,所以使用到了index_mult_col索引
        +----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
      | id | select_type | table | partitions | type  | possible_keys  | key            | key_len | ref  | rows | filtered | Extra                 |
      +----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
      |  1 | SIMPLE      | class | NULL       | range | index_mult_col | index_mult_col | 5       | NULL |    2 |   100.00 | Using index condition |
      +----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
      1 row in set, 1 warning (0.00 sec)
      
        explain select * from class where teacher='Rock'; # 因为没有使用到id字段,所以没有使用到index_mult_col索引
      +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
      | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
      +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
      |  1 | SIMPLE      | class | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |    50.00 | Using where |
      +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
      1 row in set, 1 warning (0.00 sec)
      
  • 全文索引

  • 空间索引

  • 使用建议

  • 当索引存在的时候,每次插入数据的时候数据库系统会按照索引进行排序,再插入,在很大的程度上降低了数据插入的效率,所以在已经建有索引的数据库中插入大量的数据的时候,建议先将索引删除,之后子啊插入数据,数据插入完毕之后在恢复索引

  • 普通索引

    • 创建索引的时候,不需要附加任何限制条件,可以创建在任何数据类型的字段上

    • 创建的格式

      • 创建表时创建索引
      # [] --> 可选部分    
      create table table_name (
      	property1 type1,
      	property2 type2,
      	......
      	propertyn typen,
      	INDEX | KEY 
      	[indexname](property[length] [ASC | DESC]))  # 不指明升降序则默认是升序
      	
      # 用中文描述格式即:
      create table table_name (
      	字段1 类型1,
      	字段2 类型2,
      	.....
      	字段n 类型n,
      	INDEX | KEY
      	[自定义索引名字](索引字段[索引字段长度][ASC | DESC]))
      
      • 在已存在的表上创建索引

        # 方法一: 执行create语句
        create INDEX indexname ON table_name(property [(length)] [ASC |DESC]);
        #方法二: 执行alter table语句
        alter table table_name add INDEX | KEY indexname(property [(length)] [ASC |DESC]);
        
      • 查看索引使用的情况 —> EXPLAIN

        EXPLAIN select * from table_name where id = 1;
        
        # 查询结果部分参数意义: 
        key:   实际使用的索引。如果为NULL,则没有使用索引
        possible_keys:显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引					将被列出,但不一定被查询实际使用
        key_len: 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。此值越短越好!
        
  • 隐藏索引

    • MySQL 8开始支持隐藏索引。隐藏索引提供了更人性化的数据库操作。隐藏索引,顾名思义,让索引暂时不可见,不会被优化器使用。默认情况下索引是可见的。隐藏索引可以用来测试索引的性能。验证索引的必要性时不需要删除索引,可以先将索引隐藏,如果优化器性能无影响就可以真正地删除索引。

    • ALTER TABLE tablename ALTER  INDEX  index_name INVISIBLE;  #隐藏索引  成功隐藏索引之后,使用show create table table_name查看表的结构时会发现在你所隐藏的索引后面会有一句  /*!80000 INVISIBLE */ .并且使用explain解释查询的时候发现,没有使用该字段作为索引
      
      ALTER TABLE tablename ALTER  INDEX  index_name VISIBLE;    #取消隐藏 恢复隐藏索引之前的样式
      
  • 删除索引

    • 所谓删除索引,就是删除表中已经创建的索引。之所以要删除索引,是因为这些索引会降低表的更新速度,影响数据库的性能。在MySQL中删除索引通过SQL语句DROP INDEX来实现,其语法形式如下:

    • DROP INDEX indexname ON tablename;  
      
数据查询
  • 查询数据表的所有记录

    • select * from table_name;    # * 表示所有字段记录
      
  • 查询数据表 table_name 中所有记录的 table_property1,table_property2属性字段(列)的值

    •  # * 表示所有字段
      select table_property1,table_property2 from table_name;
      # EG
      select StuNO,StuName from StudInfo;  # 查询StuInfo表中学号(StuNO)和姓名(StuName)信息
      
  • 查询数据表中所有的table_property属性不重复的字段(列) —>即假如有相同的属性值只列出一个即可,

    •  # distinct    排除重复    
        select distinct table_property from table_name;
      
  • 查询数据表 score 中分数在 60 - 80 之间中的所有记录 score 为分数表 degree 为成绩

    •  # 方式一:查询区间 between .... and ...... (闭区间,包含两端)
        select * from score where degree between 60 and 80;
        
       # 方式二:直接使用运算符比较
        select * from score where degree > 60 and degree < 80;
      
  • 查询数据表 score 中分数为 85 , 86 , 88 的记录 score 为分数表 degree 为成绩

    •  # in 表示或者关系的查询
      select * from score where degree in (85,86,88);
      
  • 查询数据表 student 中班级为 ‘95031’ 或者性别为 ‘女’ 的同学的记录

    •  # or 表示或者
         select * from student where class='95031' or sex='女';
      
  • 以 class 升降序查询 student 表所有记录

    • # 升序排列查看    ascend 上升   一般默认是升序
         select * from student order by class asc;
      # 降序排列查看    descend 下降
         select * from student order by class desc;
      
  • 以 cno升序, degree 降序排序查询表 score 的所有记录

    • # 在表中先以 cno 升序排列,然后对于 cno 相同的记录,按照 degree 降序排列 
       select * from score order by cno asc,degree desc;
      
  • 查询 ‘95031’ 班的学生人数

    • # 统计  count
        select count(*) from student where class='95031';
      
  • 查询表 score 中的最高分的学生学号和课程号. (子查询或者排序)

    • # 方式一. 子查询 步骤
      # 1.找到最高分   ---> select max(degree) from score
      # 2.找到最高分的 sno 和 cno 
      # 最终代码:
        select sno,cno from score where degree=(select max(degree) from score);
      
      # 方式二. 排序的做法   ---> 先降序排列,然后拿到第一个数据  但是有缺陷,计入有两个及以上最高分//时,只会输出其中一个  不得不说,想法还挺多QAQ
      # limit 第一个数字表示从多少开始, 第二个数字表示查多少条
        select sno,cno,degree from score order by degree desc limit 0,1;   
      
  • 查询每门课的平均成绩

    • # 计算指定一门课的平均成绩   --- 下面计算课程编号为 3-105 的课程的成绩
        select avg(degree) from score where cno='3-105';
        
      # 计算每门课的平均成绩   --- cno 课程编号   
      # group by 分组     group by cno  -->就是按照课程编号分组
      # 1.只打印打印平均成绩和课程编号
        select cno,avg(degree) from score group by cno;
      # 2.打印平均成绩和所有 score 表的其他属性信息   --- * 后面要跟一个 ',',否则会失败
        selec * ,avg(degree) from score group by cno;
        
      
  • 查询 score 表中至少有两名学生选修的并以3开头的课程的平均成绩

    • # 1.找到至少有两名学生选修的课程   cno --- 课程编号
      # having 表示分组后的条件
        select cno from score group by cno having count(cno) >=2;
        
      # 2.在上面的基础上在添加课程编号以 3 的要求
      # like 模糊查询
      # % --- >通配符
          select cno from score group by cno 
       -->having count(cno)>=2 and cno like '3%'
       
      # 3.在上面的基础上计算平均成绩
          select cno,avg(degree) from score group by cno 
       -->having count(cno)>=2 and cno like '3%'
      
  • 查询所有学生的 sname, cno 和 degree 列. ----> 多表查询

    • # 查询 student 表中的 sname
       select sname from student;
      # 查询 score 表中的 cno,degree
       select cno,degree from score;
      # 最终代码
       select sname,cno,degree from student,score where    student.sno=score.sno;
      # 解释 当 student 中的 sno 等于 score 中的 sno 时候,就用student 表中的 sname 代替 score 表中的 cno,从而达到查询目的 
      
  • 查询 “95031” 班学生每门课的平均分

  • # 1.查询 student 表中班级为 95031 的学生的编号
    select sno from student where class='95031';
    # 2.按照上面的 sno (即班级为 95031 学生的 sno) 查询 score 表中相应地学生 ----> score 表中有 sno 没有班级字段,所以按照上面两个步骤就可以 找出 score 表中班级为 95031 的学生了
    
    # 最终代码 (计算平均成绩是要按分组计算的哟)
     select cno,avg(degree) 
     from score 
     where sno in (select sno from student where class='95031') 
     group by cno;
    
  • 查询和学号为108,101的同学同年出生的所有学生的sno,sname和sbirthday列

    • # 1.查询学号为108,101的同学是谁
       select * from student where sno in(108,101);
      # 2.查询这两个学生的出生年 
       select year(sbirthday) from student where sno in(108,101);
       
      # 最终代码
      select * from student where year(sbirthday) in (select year(sbirthday) from student where sno in(108,101));
      
  • 查询"计算机系"与"电子工程系"不同职称的教师的 tname 和 prof

    • # 1.电子工程系的职称
       select Prof from teacher where depart='电子工程系';
      # 2.查询计算机系中没有与电子工程系教师职称相同的记录   not in 不包含
       select * from teacher where depart='计算机系' and prof not in(select prof from teacher where depart='电子工程系');
       
      # 最终代码 union ----> 求并集
       select * from teacher where depart='计算机系' and prof not in(select prof from teacher where depart='电子工程系') union select * from teacher where depart='电子工程系' and prof not in(select prof from teacher where depart='计算机系');
      
      
  • 查询选修编号为“3-105”课程且成绩至少高于选修编号为“3-245”的同学的Cno,Sno和Degree,并按Degree从高到低次序排列

    • # 1.选修课程编号 “3-105” 的同学
      select * from score where cno='3-105';
      # 2.选修课程编号为 “3-245” 的同学
      select * from score where cno='3-245'# 至少? 大于其中至少一个, any
      select * from score where cno='3-105' and degree > any(select degree from score where cno='3-245');
      
      # 最终代码
      select * from score where cno='3-105' and degree > any(select degree from score where cno='3-245') order by degree desc;
      
  • 查询选修编号为“3-105”课程且成绩高于选修编号为“3-245”所有同学的Cno,Sno和Degree,并按Degree从高到低次序排列

    • # all 表示所有
      select * from score where cno='3-105' and degree > all(select degree from score where cno='3-245');
      
SQL 的四种连接查询
  • 内连接 ----> inner join 或者 join
    • 内联查询 : 其实就是两张表中的数据,通过某个字段相等,查询出相关记录数据.
  • 外连接
    • 左连接 ----> left join 或者 left outer join
      • 左外连接,会把左边表里面的所有的数据取出来,而右边表中的数据,如果有相等的,就显示出来,如果没有,就会补 NULL
    • 右连接 ----> right join 或者 right outer join
      • 右外连接,会把右边表里面的所有数据取出来,而左边表中的数据,如果有相等的,就会显示出来,如果没有相等的,就会补 NULL
    • 完全外连接 ----> full join 或者 full outer join
数据库的三大设计范式
  • 第一范式 -----> 1NF
    • 数据表中所有的字段都是不可分割的原子值
    • 字段值还可以继续拆分的就不满足第一范式
  • 第二范式 ------>2NF
    • 必须满足第一范式的前提下,第二范式要求,除主键外的每一列都必须完全依赖于主键
    • 如果出现不完全依赖,只有可能发生在联合主键的情况下
    • 百度百科详解及举例
  • 第三范式 ------->3NF
    • 必须先满足第二范式,除开主键列外的其他列之间不能有传递依赖关系
    • 百度百科
MySQL事务
  • mysql 中,事务其实是一个最小的不可分割的工作单元。事务能够保证一个业务的完整性。

    # 比如我们的银行转账
    a  --> -100
     update user set money=money-100 where name='a';
    b --> +100
     update user set money=money+100 where name='b';
    # 实际的程序中,如果只有一条语句执行成功了,而另一条没有执行成功,就会出现数据前后不一致
    # 多条 SQL 语句,可能会有同时成功的要求,要么就同时失败.
    
  • mysql 中如何控制事务

  1. MySQL 默认是开启事务的(自动提交).

    select @@autocommit;
    
    # 作用 : 当我们去执行一个 SQL 语句时候,效果就会立即体现出来,且不能回滚.
    
    # 事务回滚 : 撤销 SQL 语句执行效果
    rollback;
    
    # 设置 mysql 自动提交为 false (关闭自动提交)
    set autocommit=0;
    
    # 手动提交数据
     commit;
     
    # begin 或者 start transaction 都可以 帮我们手动开启一个事务
    
  • 事务的四大特征

    • A : 原子性 : 事务是最小的单位,不可以再分割
    • C : 一致性 : 事务要求,同一事务中的 SQL 语句,必须保证同时成功或者同时失败.
    • I : 隔离性 : 事务1 和事务2 之间是具有隔离性的.
    • D : 持久性 : 事务一旦结束 (commit ,rollback),就不可以返回.
  • 事务的隔离性

    • read uncommitted ----> 读未提交的

      # 如果有事务a,和事务b.
      # a 事务对数据进行操作,在操作过程中,事务没有被提交,但是b 可以看见 a 操作的结果.
      
      # 如何查看数据库的隔离级别 8.0版本
      1. 系统级别
      select @@global.transaction_isolation
      +--------------------------------+
      | @@global.transaction_isolation |
      +--------------------------------+
      | REPEATABLE-READ                |
      +--------------------------------+
      
      2.会话级别
      select @@transaction_isolation
      +-------------------------+
      | @@transaction_isolation |
      +-------------------------+
      | REPEATABLE-READ         |
      +-------------------------+
      
      # 如何修改隔离级别
      set global transaction isolation level read uncommitted;
       
      # 脏读 一个事务读取到了另一个事务没有提交的数据,就叫做脏读
      
      
    • read committed ----> 读已经提交的

      # 虽然只读到另外一个事务提交的数据,但还是会出现问题,就是读取同一个表的数据,发现前后不一致.即不可重复读现象
      
    • repeatable read ----> 可以重复读

      # 幻读
      -- 事务 a 和事务 b 同时操作一张表,事务 a 提交的数据,也不能被事务 b 读到,就可以造成幻读
      
    • serializable ----> 串行话化

      # 当一个表被另一个事务操作时候,其他事务里面的写操作,是不可以进行的.进入排队 状态(串行化),直到该事务结束之后,其他事务的写操作才会执行.
      # 串行化的问题是,性能特差
      
      -- 性能:
       READ-UNCOMMITTED > READ-COMMITTED > REPEATABLE-READ > SERIALIZABLE
      -- 隔离级别越高,性能越差
      -- mysql 默认隔离级别是 REPEATABLE-READ
      

MySQL 浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值