数据库的种类
目前市面上主流的数据库有关系型数据库和面向对象的数据库。随着时间的推移,现在数据库的种类也越来月多样性,其中我们熟知的Redis就是典型的键值型数据库,还有基于文档检索的ES。
今天要介绍MySQL作为主流的关系数据库,其热度仅次于Oracle。
MySql安装(docker)
下载docker镜像
docker pull mysql
# 或者
docker pull mysql:latest
启动MySQL
docker run --name=mysql-container -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql
进入docker环境
docker exec -it xxxx(contain id) /bin/bash
登录MySQL
mysql -uroot -proot
数据库的基本操作
创建数据库
create database 数据库名
,示例:
-- 创建数据库world
create database world;
-- 使用数据库world
use world;
创建表
create table 数据表名
(字段名
字段类型
, 字段名1
字段类型2
);
示例:
CREATE TABLE `city` (
`ID` int NOT NULL AUTO_INCREMENT,
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `CountryCode` (`CountryCode`),
CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`Code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
增删改查
插入数据
insert into 表明
(字段名(可选)
) values (字段值
);
示例:
INSERT INTO `city` VALUES (1,'Kabul','AFG','Kabol',1780000);
更新数据
update 表名
set 字段名
=值
,字段名1
=值1
where 字段
=值
;
示例:
update city set population=1780000 where id='1';
删除数据
delete from 表明
where 字段
=值
;
示例:
delete from city where id='1';
查询数据
查询用的数据来源于MySQL提供的world库,建表脚本和数据导入脚本下载地址:Other MySQL Documentation。
单表查询
-- 无条件查询
select * from city;
-- 带条件查询
select * from city where id = 1;
-- 模糊查询
select * from city where name like 'Chin%';
-- in 查询
select * from city where id in (1, 2, 3);
-- 范围查询
-- 大于1小于10
select * from city where id > 1 and id < 10;
-- 大于等于2小于等于9
select * from city where id >= 2 and id <= 9;
-- 2(包含)到9(包含)
select * from city where id between 2 and 9;
-- 小于等于9,不等于5
select * from city where id <= 9 and id <> 5;
-- 精确字段
select id,name from city where id=1;
关联查询
-- 关联单个值
select * from city where countrycode=(select code from country where name ='China');
-- 关联多个值
select * from city where countrycode in (select code from country where name like 'Chi%');
连接查询
常见的连接查询有左连接、右连接和全连接。下面做一个左连接查询的例子:
select co.name,ci.name from city ci left join country co on co.code=ci.countrycode where co.code='CHN' and ci.name like 'Su%';
关系型数据库的三范式
数据库三范式(3NF)是关于关系数据库设计的重要原则,旨在提高数据的一致性和减少冗余。以下是关于三范式的详细信息:
第一范式(1NF)。确保数据库表的每个列都是原子性的,即不可再分的数据项,不能是集合、数组或其他非原子类型。
第二范式(2NF)。在满足第一范式的基础上,要求非主键列完全依赖于主键,而不是依赖于主键的一部分。这意味着表中的每个非主键字段都应直接与主键相关联,不存在部分依赖。
第三范式(3NF)。在满足第二范式的基础上,进一步消除非主键字段之间的传递依赖。传递依赖指的是非主键字段依赖于其他非主键字段,而不是通过主键建立联系。
通俗来说,第一范式的意思就是说字段应当为数据库构成的最小单元,一个字段中不能即保存多个信息(也就是说,后面的json类型不符合这一范式)。
第二范式的简单理解就是,表在建立时必须存在一个唯一标识,也就是我们说的主键。第二范式建立在第一范式的基础上,必须先满足第一范式。
第三范式的意思是表和表之间可以建立一定的联系来体现数据间的关系,通常表现为外键。上面world数据库的结构来说,city.countrycode是和country.code关联的,一个国家下面有多个城市。
事务的隔离级别
事务的隔离级别定义了并发控制的不同层次,以确保数据的一致性和完整性。以下是常见的几种事务隔离级别:
读未提交(Read Uncommitted):允许脏读取,即一个事务可以读取另一个事务未提交的数据。但是,它不保证更新丢失,因为如果一个事务已经开始写数据,另一个事务仍然可以读取到这些数据。
读提交(Read Committed):允许不可重复读取,但不允许脏读取。这意味着事务A在读取数据后,事务B更新了数据并提交,事务A再次读取该数据时,将得到更新后的数据。
可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但可能会出现幻读。这意味着事务A在同一数据上进行多次读取时,可以得到相同的结果,但如果在事务A读取期间有其他事务插入数据,事务A将无法看到这些新插入的数据。
串行化(Serializable):这是最高的隔离级别,所有事务串行执行,保证数据的一致性和完整性,但并发性较差。
事务的隔离级别还涉及原子性、一致性、隔离性和持久性等概念。原子性确保事务要么全部执行,要么全部不执行;一致性确保事务的执行使得数据库从一个正确状态转换到另一个正确状态;隔离性在事务正确提交之前,不允许将事务对数据的任何改变提供给其他事务;持久性则指事务正确提交后,其结果将永久保存在数据库中,即使出现故障也不会丢失。
在数据库系统中,如Oracle和MySQL,都支持这些隔离级别。Oracle默认的隔离级别是Read Committed,而MySQL的InnoDB引擎也支持这些级别。
隔离级别通常是为了解决不可重复读、幻读和脏读的问题。以下是事务的隔离级别分别解决
问题:
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | ✓ | ✓ | ✓ |
读提交 | ✗ | ✓ | ✓ |
可重复读取 | ✗ | ✗ | ✓ |
串行化 | ✗ | ✗ | ✗ |
✓的意思代表这一级别会出现该问题,从上面的情况看,串行化能解决所有的问题,但串行化锁定的内容是最多的,这样在并发情况下,效率会明显降低,所以实际应用中,我们都只使用可重复读取(Repeatable Read)这一隔离级别。