数据库-Mysql使用学习笔记(命令行及图形化界面)(4)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 数据库-Mysql使用学习笔记(命令行及图形化界面)(4)

约束

创建表时,添加相应约束

非空约束

不能为null

create table t_user( id int, username varchar(255) not null, password varchar(255));

2020062310470442.png

唯一约束

关键字:unique

单字段,列级约束

不能重复,但可以为NULL。可以认NULL和NULL不一样。

drop table if exists t_user;
create table t_user( id int, username varchar(255) unique);

2020062310470442.png

多字段唯一,表级约束

drop table if exists t_user;
create table t_user( id int, username varchar(255), phonenum int,unique(username,phonenum));

2020062310470442.png

可以看成将两个字段合并为一个组,组不能重复。

主键约束

关键字:primary key

不能为null,也不能重复

单一主键

drop table if exists t_user;
create table t_user( id int primary key, username varchar(255),email varchar(255));

2020062310470442.png

第二行由于主键约束,运行失败。

insert into t_user values(1,'zs','zs@126.com'),(2,'ls','ls126.com');
insert into t_user values(2,'ww','ww@126.com');

2020062310470442.png

你可以尝试一下,id 为 null 是不是不能插入。

复合主键、业务主键

和unique表级约束语法差不多,primary key(字段1,字段 2)

不推荐,可能产生依赖或业务改变造成影响

自然主键

推荐,使用自然数1、2、3。。。,使用关键字auto_increment

id int primary key auto_increment

外键约束

为解决数据冗余问题,将一张表的主键作为另一张表的外键,用于select时的表连接。

建一个学生表和班级表,学生表有一个外键班号,来自班级表

drop table if exists t_student;
drop table if exists t_class;
create table t_class( cno int, cname varchar(255), primary key(cno) );
create table t_student( sno int, sname varchar(255), classno int, foreign key(classno) references t_class(cno));

2020062310470442.png

insert into t_class values(101,'xxxxxxxxxxxxxxx');
insert into t_class values(102,'yyyyyyyyyyyyyyy');
insert into t_student values(1,'zs1',101);
insert into t_student values(2,'zs21',101);
insert into t_student values(3,'zs4',102);
insert into t_student(sno,sname) values(4,'zs5');
insert into t_student values(5,'zs6',103);

最后一句无法运行,因为103不在表t_class中。

2020062310470442.png

外键可以为NULL,可以理解为,学校来了个转学的学生,先添加进来,再分配班级。

2020062310470442.png

下一节使用Navicat,有一些提示,一些函数名字过长,总是手打,浪费时间。

常见函数

语法

select 函数名() [from 表名]

mysql相关

database()

返回当前使用数据库

version()

返回mysql版本

2020062310470442.png

user()、system_user()、session_user()

返回当前用户

2020062310470442.png

单行处理函数

字符函数

长度相关

返回字符串字节长度

length(s)

s:字符串

一个汉字是算三个字节,一个数字或字母算一个字节。这是在utf-8字符集下。

char_length(s)

s:字符串

不管汉字还是数字或者是字母都算是一个字节。

2020062310470442.png

字符串拼接

CONCAT(s1,s2...sn)  字符串 s1,s2 等多个字符串合并为一个字符串

CONCAT_WS(x, s1,s2...sn)  同 CONCAT(s1,s2,...) 函数,但是每个字符串之间要加上 x,x 可以是分隔符

2020062310470442.png

大小写

UPPER(s)     将字符串转换为大写

LOWER(s)     将字符串 s 的所有字母变成小写字母

2020062310470442.png

查询员工表员工名,小写展示

SELECT LOWER(ename) 员工名 from emp;

2020062310470442.png

子串

SUBSTR(s, start [,length])     从字符串 s 的 start 位置截取长度为 length 的子字符串,位置从1开始

SUBSTRING、MID 一样

2020062310470442.png

SUBSTRING_INDEX(s, delimiter, number)     返回从字符串 s 的第 number 个出现的分隔符 delimiter 之后的子串。

如果 number 是正数,返回第 number 个字符左边的字符串。

如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串。

例如,查询'lady_killer9'中'_'左面的子串,'lady_killer9'中第二个'l'右边的子串

SELECT SUBSTRING_INDEX('lady_killer9','_',1),SUBSTRING_INDEX('lady_killer9','l',-2);


2020062310470442.png

去空格

LTRIM(s)     去掉字符串 s 开始处的空格

RTRIM(s)     去掉字符串 s 结尾处的空格

TRIM(s)     去掉字符串 s 开始和结尾处的空格

2020062310470442.png

填充

LPAD(s1,len,s2)     在字符串 s1 的开始处填充字符串 s2,使字符串长度达到 len

RPAD(s1,len,s2)     在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len

注:最终长度必为len,不够填充,多了截断

2020062310470442.png

替换

REPLACE(s,s1,s2)     将字符串 s2 替代字符串 s 中的字符串 s1

前面去空格的时候,“Hello World”中间的空格没有去掉,可以使用replace进行替换

2020062310470442.png

索引/位置

LOCATE(s1,s)     从字符串 s 中获取 s1 的开始位置

POSITION(s1 IN s)     从字符串 s 中获取 s1 的开始位置

2020062310470442.png

比较字符串

STRCMP(s1,s2)     比较字符串 s1 和 s2,如果 s1 与 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1<s2 返回 -1

2020062310470442.png

数学函数

取整

最近取整(四舍五入)

ROUND(x[,d])     返回离 x 最近的整数,d为小数点后保留的位数,若有d,则结果为小数

2020062310470442.png

向上取整

CEIL(x)     返回大于或等于 x 的最小整数

2020062310470442.png

向下取整

FLOOR(x)     返回小于或等于 x 的最大整数

2020062310470442.png

截断

TRUNCATE(x,y)     返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入

2020062310470442.png

取余

MOD(x,y)     返回 x 除以 y 以后的余数,和%作用一样

2020062310470442.png

日期函数

NOW()     返回当前日期和时间

2020062310470442.png

CURDATE()     返回当前日期,CURRENT_DATE()一样

想想之前的内容,我们可以通过NOW函数和截断来得到结果,先不要看下方截图,自己想一下。

2020062310470442.png

再使用一下函数

2020062310470442.png

CURTIME(),CURRENT_TIME     返回当前时间

2020062310470442.png

还可以获取年、月、日、时、分、秒,分别是YEAR、MONTH、DAY、HOUR、MINUTE、SECOND

2020062310470442.png

STR_TO_DATE(string, format_mask)     将字符串转变为日期

注意:格式需要对应,可以使用数字,英文,英文简写

2020062310470442.png

时分秒分别使用%H(24小时制)/%h(12小时制)、%i、%s

DATE_FORMAT(d,f)     按表达式f的要求显示日期 d

2020062310470442.png

流程控制函数

IF(expr,v1,v2)     如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。类似三目运算符。

2020062310470442.png

IFNULL(v1,v2)     如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。

查询的员工名及本月可以得到的所有钱(基本工资+奖金),并备注有无奖金

SELECT ename,(sal+ifnull(comm,0)) 'money', IF(comm is NULL,'没奖金,呵呵','有奖金,哈哈') 备注 from emp;


2020062310470442.png

CASE expression
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    WHEN conditionN THEN resultN
    ELSE result
END

CASE 表示函数开始,END 表示函数结束。如果 condition1 成立,则返回 result1, 如果 condition2 成立,则返回 result2,当全部不成立则返回ELSE后的result,而当有一个成立之后,后面的就不执行了。

查询员工名,部门号,工资

如果部门号为10,工资显示1.1倍

如果部门号为20,工资显示1.2倍

其他部门编号,工资显示1.3倍

SELECT ENAME,DEPTNO,SAL,
CASE DEPTNO
    WHEN 10 THEN
        SAL*1.1
    WHEN 20 THEN
      SAL*1.2
    ELSE
        SAL*1.3
END 新工资
FROM emp ORDER BY DEPTNO;

2020062310470442.png

多行处理函数

分组查询的时候讲过了分组函数,总结一下

  • sum、avg 一般用于处理数值型
  • max、min、count可以处理任何类型
  • 分组函数都忽略null值
  • MYISAM 存储引擎下,COUNT(*)的效率高,INNODB存储引擎下,COUNT(*)和COUNT(1)的效率差不多

还有标准差STD这些,用的不多。

存储引擎

我们之前见过存储引擎的

2020062310470442.png

建表时的存储引擎

2020062310470442.png

所有存储引擎

MyISAM

灵活的AUTO_INCREMENT 字段处理

可被转换为压缩、只读表来节省空间

缺点:不支持事务

使用三个文件表示每个表:

  • 格式文件-存储表结构的定义(xxx.frm)
  • 数据文件-存储表行的内容(xxx.MYD)
  • 索引文件-存储表上索引(xxx.MYI)

在安装目录下的data文件夹下有根据数据库分类的文件夹,进入mysql目录可以看到自带的mysql数据库的一些表。

2020062310470442.png

mysql安装路径\data\mysql

InnoDB

优点:支持事务、行级锁等,数据安全得到保证。


InmoDB存储引擎是MySQL的缺省引擎。

它管理的表具有下列主要特征:


每个lnnoDB表在数据库目录中以.frm格式文件表示

InnoDB表空间 tablespace 被用于存储表的内容,无法压缩

提供一组用来记录事务性活动的日志文件

用COMMIT(提交)、SAVEPOINT(保存点)及ROLLBACK(回滚)支持事务处理

提供全ACID兼容

在MySQL 服务器崩溃后提供自动恢复

多版本(MVCC)和行级锁定

支持外键及引用的完整性,包括级联删除和更新

Memory

原来叫HEPA

缺点:不支持事务。数据容易丢失。查询速度最快

MEMORY存储引擎管理的表具有下列特征:

  • 在数据库目录内,每个表均以.frm格式的文件表示。
  • 表数据及索引被存储在内存中。
  • 表级锁机制。
  • 不能包含TEXT 或BLOB字段。

未完待续...

事务

事务:不可再分的业务逻辑单元,例如,银行转账,A用户给B用户转1000元,需要 update A用户的余额-1000,同时 update B用户的余额+1000,两个语句必须同时成功或失败。


开启事务->执行记录到操作历史->提交或回滚(事务结束)


TCL语句,


commit;  提交

rollback;  回滚

四大特性

A(atomicity): 原子性:事务是最小的工作单元,不可再分。

C(consistency):一致性:事务必须保证多条DML语句同时成功或者同时失败。

I(isolation):隔离性:事务A与事务B之间具有隔离。

D(durability):持久性:持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。

隔离性

第一级别:读未提交(read uncommitted)

对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。

读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。

查看全局事务级别


select @@global.tx_isolation;

2020062310470442.png

设置全局事务级别为 读未提交

set global transaction isolation level read uncommitted;

开启事务

start transaction;

2020062310470442.png

插入id为3的记录的事务还未提交,但是却可以读到数据。

第二级别:读已提交(read committed)

对方事务提交之后的数据我方可以读取到。oracle数据库默认。

这种隔离级别解决了:脏读现象没有了。

读已提交存在的问题是:不可重复读

设置全局事务级别为 读已提交

set global transaction isolation level read committed;

2020062310470442.png

注意,要开两个控制台,不然未提交的还会显示。

id为3的数据提交之后才可以读。

第三级别:可重复读(repeatable read)

这种隔离级别解决了:不可重复读问题。mysql数据库默认。

这种隔离级别存在的问题是:读取到的数据是幻象

设置全局事务级别为 可重复读

set global transaction isolation level repeatable read;

2020062310470442.png

id为3的数据删除,且已提交。 但是仍可读取已删除了的id为3的数据。

第四级别:序列化读/串行化读(serializable)

解决了所有问题,但效率低。因为需要事务排队,必须一个事务commit之后,其他事务才能继续。

资源

lady_killer.sql以及参考手册等资源

百度网盘

提取码: xbkm

参考

mysql 5.7 官方手册

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
关系型数据库 MySQL 数据库
docker MySQL删除数据库时的错误(errno: 39)
docker MySQL删除数据库时的错误(errno: 39)
|
1天前
|
关系型数据库 MySQL 数据库连接
用Navicat备份Mysql演示系统数据库的时候出:Too Many Connections
用Navicat备份Mysql演示系统数据库的时候出:Too Many Connections
|
3天前
|
存储 Oracle 关系型数据库
oracle 数据库 迁移 mysql数据库
将 Oracle 数据库迁移到 MySQL 是一项复杂的任务,因为这两种数据库管理系统具有不同的架构、语法和功能。
15 0
|
10天前
|
关系型数据库 MySQL Linux
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
|
10天前
|
SQL 关系型数据库 MySQL
【MySQL-5】DDL的数据库操作:查询&创建&删除&使用(可cv代码+演示图)
【MySQL-5】DDL的数据库操作:查询&创建&删除&使用(可cv代码+演示图)
|
10天前
|
SQL 关系型数据库 MySQL
【MySQL-1】理解关系型数据库&数据的数据模型
【MySQL-1】理解关系型数据库&数据的数据模型
|
11天前
|
关系型数据库 MySQL 数据库
Docker数据库Mysql
Docker数据库Mysql
|
12天前
|
存储 SQL 关系型数据库
mysql查询数据库表大小怎么操作
mysql查询数据库表大小怎么操作
|
12天前
|
关系型数据库 MySQL PHP
【PHP 开发专栏】PHP 连接 MySQL 数据库的方法
【4月更文挑战第30天】本文介绍了 PHP 连接 MySQL 的两种主要方法:mysqli 和 PDO 扩展,包括连接、查询和处理结果的基本步骤。还讨论了连接参数设置、常见问题及解决方法,如连接失败、权限和字符集问题。此外,提到了高级技巧如使用连接池和缓存连接信息以优化性能。最后,通过实际案例分析了在用户登录系统和数据管理中的应用。
|
12天前
|
关系型数据库 MySQL 数据库
【MySQL】:数据库事务管理
【MySQL】:数据库事务管理
24 0