A-mysql(锁、引擎、范式)

1.表与表之间的对应关系:
一对一、一对多、多对一、多对多
2.约束
约束作用:约束是一种限制,用于限制表内的数据,为了保证数据的准确性以及可靠性。
not null、default、primary key、foreign key、unique
约束分类:
列级约束:定义列的同时指定的约束
表级约束:列定义之后指定的约束
外键:对应一对多的关系。一为主表,多为从表。
3.锁🔒
只允许拿到锁的事务访问数据
(1)根据锁的粒度分类:行锁与表锁
表级锁:只有当前用户可以操作整张表,其他排队等候,等待当前sql操作执行完毕
特点:开销小(内存),加锁快,不会出现死锁(一锁就锁整张表,不会争用数据行),锁定颗粒大(一锁锁整张表,锁定范围大),发生锁冲突的概率高(争用锁),并行性差(一锁锁整张表,不能同时处理多行数据),一致性极好
行级锁:只有当前用户可以操作该行记录,其他对该行的操作排队等候,等待当前sql操作执行完毕。
特点:开销大,枷锁满,会出现死锁,锁定颗粒小,发生锁冲突的概率低,并发性高。
(2)根据数据库系统分:读锁与写锁
读锁:其他请求可读不可写(共享),用于不更新数据的操作(只读操作),例如 select语句
select加共享锁示例:

  select * from table lock in share mode;

写锁:其他请求不可读不可写(排他),用于数据修改操作。insert、update,delete默认自带写锁,确保不会同时对同一资源多重更新。
select 加排他锁示例:

  select * from table for update;//该条语句在执行时,所有扫描过的行都会被加锁 

由于使用悲观锁时,扫描到的数据都会被锁定。所以在使用悲观锁时,务必确定使用索引,而不是全表扫描,否则会把整个表都锁住。

(3)根据程序员的角度分类:悲观锁与乐观锁

定义:
悲观锁:指对数据被外界(包括当前系统、外部系统的事务)修改保持保守态度。即在数据操作整个期间,对所有扫描到的数据进行加锁。
悲观锁是大多数依靠数据库提供的锁机制(数据库提供的锁机制才能实现数据访问的排他性)
缺点:如果加锁的时间太长,其他用户会长时间无法访问数据,影响程序的并行性,对数据库性能影响很大。

乐观锁:乐观锁认为数据一般情况下不会造成冲突,所以只有在数据提交更新操作时,才会正式对数据的冲突与否进行检测。如果检测到冲突,会返回错误信息,让用户决定如何去做。
实现乐观锁方法:时间戳、版本号
先查询,记录当前数据的版本号(version)或时间戳(timestamp);进行更新操作,提交更新数据前先查询版本号或时间戳是否改变,没有改变则提交数据并更新版本号或时间戳。
示例:
通过版本号:

set @version = 1;
select * from stu_info;//查到当前版本号为1
update set grade = 80,version = version + 1 from stu_info where version = 1 and id = 3;//当版本号是前面查到的版本号时,说明前面查询到的语句没有被改变,没有发生数据冲突

通过时间戳:
类似于版本号,设置一个时间变量

set @time = '2022-01-10-15:08';
update set grade = 80,time = now() from stu_info where id = 3 and time = '2022-01-10-15:08';

示例:如下是一种数据冲突,v1通过事务1修改,通过事务2修改,事务1应该再从v2继续修改。这里事务1与2就产生了数据冲突。
一种数据冲突
4.引擎
(1)innodb:自动给更新操作涉及的数据集加排他锁。innodb的行锁是通过给索引上的索引项加锁来实现。而oracle是通过在数据块中相应数据行加锁实现的。所以,innodb只有在使用索引条件检索数据时才会使用行级锁,否则innodb将使用表锁。
(2)myisam:自动加锁,一般不需要用户干预。在查询时,myisam自动给表加读锁;在更新操作时,默认给表加写锁。

5.范式
设计关系数据库的规范要求。各种范式成递次规范。越高的范式数据库冗余越小
目的:使数据库结构更合理,消除存储异常,使数据冗余尽量小,便于插入删除更新。
(1)第一范式(1NF):每一列都是不可分割的原子数据项。
一个字段只能有一个确定的值,不能是集合。
1NF是关系数据库的基本要求
(2)第二范式是建立在第一范式的基础上的。一个表必须有一个主键;没有包含在主键中的列必须完全依赖于主键,而不能只依赖主键的一部分。
完全依赖:X–>Y,唯一确定
(3)第三范式:属性不依赖其他非主键属性
在这里插入图片描述
在学生表里,主键是学生id,但是班级姓名依赖于班级id,科目名称依赖科目id,成绩也依赖于科目id。
(4)BCNF(巴斯科德范式)
(5)第四范式

6.函数依赖:X–>Y,函数Y依赖于X,唯一确定
传递函数依赖:
码:当K确定的情况下,该表除K之外的所有属性的值也就随之确定,那么K就是码。一个表中可以有超过一个码。(实际应用中,通过选择其中一个码为主码)

7.补充:
1)当不知道查询条件中的字段个数时,可以用sql语句拼接:

//占位符拼接
		String sql = "select * from staff_infor where 1=1";
		//标签的name属性就是id、staffName、phone、depart
		//对应的可以直接用req.getParameter("")获取value值
		String id = req.getParameter("id");
		String name = req.getParameter("staffName");
		String phone = req.getParameter("phone");
		String d = req.getParameter("depart");
		System.out.println(id+","+name+","+phone+","+d);
		if(id != "" && id != null) {
			sql +=" and staff_id = ?";
			str[ans++] = id;
		}
		if(name != "" && name != null) {
		
			sql += " and staff_name = ?";
			str[ans++] = name;
		}
		if(d != "" && d != null) {
			
			sql += " and staff_depart = ?";
			str[ans++] = d;
		}
		if(phone != "" && phone != null) {
			
			sql += " and phone = ?";
			str[ans++] = phone;
		}
		sql += ";";
		String[] b = new String[ans];
		System.arraycopy(str, 0, b,0, ans);
		List<Staff> list = DBHelper.queryAll(sql, Staff.class,b);

2)直接拼接查询字段

		StringBuffer sql = new StringBuffer("select * from staff_infor where 1 = 1");
		if(!StrUtil.isEmpty(id)) {//sql语句中字符串用""引起来;StringBuffer的isEmpty方法,如果id为null,会判错。
			               //现在重写了一个isEmpty方法,如果id为空,直接略过,不会判错。
			sql.append(" and staff_id = '" + id + "'");
			System.out.println(sql);
		}
		if(!StrUtil.isEmpty(name)) {
			sql.append(" and staff_name = '" + name + "'");
			System.out.println(sql);
		}
		if(!StrUtil.isEmpty(d)) {
			sql.append(" and staff_depart = '" + d +"'");
			System.out.println(sql);
		}
		if(!StrUtil.isEmpty(phone)) {
			sql.append(" and phone = '" + phone + "'");
			System.out.println(sql);
		}
		sql.append(";");
		//基本数据类型用(int)x强转
		List<Staff> list = DBHelper.queryAll(sql.toString(), Staff.class,null);

	//StrUtil.java
	package util;
	public class StrUtil {
	public static boolean isEmpty(Object obj) {
		if (obj == null) {
			return true;
		}
		if (obj.toString() == "" || obj.toString().length() == 0) {
			return true;
		}
		return false;
	}

	public static void main(String[] args) {
		String a = null;
		a.isEmpty();
		System.out.println(a);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值