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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 数据库-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 官方手册

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决
|
6天前
|
缓存 关系型数据库 MySQL
【深入了解MySQL】优化查询性能与数据库设计的深度总结
本文详细介绍了MySQL查询优化和数据库设计技巧,涵盖基础优化、高级技巧及性能监控。
74 0
|
1月前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
63 3
|
1月前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
97 2
|
1月前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
82 3
|
1月前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
278 15
|
1月前
|
SQL 关系型数据库 MySQL
数据库数据恢复—Mysql数据库表记录丢失的数据恢复方案
Mysql数据库故障: Mysql数据库表记录丢失。 Mysql数据库故障表现: 1、Mysql数据库表中无任何数据或只有部分数据。 2、客户端无法查询到完整的信息。
|
1月前
|
关系型数据库 MySQL 数据库
数据库数据恢复—MYSQL数据库文件损坏的数据恢复案例
mysql数据库文件ibdata1、MYI、MYD损坏。 故障表现:1、数据库无法进行查询等操作;2、使用mysqlcheck和myisamchk无法修复数据库。
|
1月前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
2月前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据

热门文章

最新文章

推荐镜像

更多