第二十天,数据库的一些概念性知识
一、数据库设计范式
1.1 原子性
保证每个字段都是最小单位。 这样可以避免使用 like 查询,效率更高。 但是在实际操作中使用起来十分麻烦。
1.2 主键
每一行数据都需要有唯一标识。 现代开发中不能违反的范式。
1.3 外键
表中如果需要有外表的信息,则必须用一个外键指向那个表的主键。 尽量避免重复字段。 但是在实际操作中可能会增加冗余字段以便查询。
二、主键和外键
一个表便于定位信息的唯一标识,便是这个表的主键。 一个表有一个字段指向另一个表的主键,这个字段便是外键。
2.1 强制关联
1° 严格模式-restrict
主表不能随意删除数据,从表不能随意新增数据。
2° 级联模式-cascade
主表删除数据,数据库会自动删除与之关联的从表数据。
2.2 主外键关联的劣势
灵活性降低。 不适应现代分布式微服务类系统。
三、事务
3.1 事务的格式
try{ connect.setAutoCommit(false); … connect.commit(); }catch (Exception e){ connect.rollack; }
3.2 事务的特性
1° 原子性
指一系列动作不可拆分或打断,会同时成功或失败。
2° 一致性
开发的终极目标。 保证事务完成后,数据仍然正确。
3° 持久性
事务对数据的改变会永久写入数据库。
4° 隔离性
原子性的基础上加上最高级别的隔离性,一定能保证一致性。
3.3 隔离级别
1° 读未提交
一个事务中未提交的数据,也会被其他事务读到。 不能防脏读。
2° 读已提交-RC级别
一个事务中的数据在提交以后才能被其他事务读到。 不能防不可重复读和幻影读。
3° 可重复读-RR级别
4° 串行化
所有事务排队执行,不并发。 为最高级别隔离。 但是此级别性能太差,卡顿,易锁死,一般不用。 强竞争性场景的数据一致问题,用 java 中的 synchronized 解决。
5° MVCC机制
多版本控制机制。
四、代理模式
4.1 什么是代理
- 代理就是由代理对象代替原对象执行一系列操作。
- 可以优雅的植入逻辑。
- 代理对象必须忠实的执行原对象的功能,但在执行过程中会加入自己的逻辑。
- 动态代理的解耦性,做到了老逻辑与新植入逻辑的分离。
4.2 概念
- 切点:原有的方法。
- 切面:新植入的逻辑。
- 分类
前置逻辑:before 后置逻辑:after 环绕逻辑:around
4.3 格式
public interface A {
public void methodA();
public void methodB();
}
public class Aimpl implements A {
@Override
public void methodA() {
System.out.println("run-A-methodA");
}
@Override
public void methodB() {
System.out.println("run-A-methodB");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler {
private Object o;
public MyHandler(Object o) {
this.o = o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("植入逻辑:before");
Object result = method.invoke(o, args);
System.out.println("植入逻辑:after");
return result;
}
}
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
A a = new Aimpl();
A aProxy = (A) Proxy.newProxyInstance(Test.class.getClassLoader(), a.getClass().getInterfaces(),
new MyHandler(a));
System.out.println("------");
a.methodA();
System.out.println("------");
a.methodB();
System.out.println("------");
aProxy.methodA();
System.out.println("------");
aProxy.methodB();
System.out.println("------");
}
}
运行结果:
|