数据库基础知识
=============================================================================================
数据库(既是保管数据的仓库,也是数据管理的方法与技术的集合)
定义:
长期存储在计算机内,有组织的,可共享的,统一管理的数据集合。
特点:
1. 数据共享,减少数据冗余
2. 采用特定的数据类型
3. 具有较高的数据独立性
4. 具有统一的数据控制功能
表:
1. 记录:数据的一行,是组织数据的单位。
2. 字段:数据的列,记录一个属性
数据类型:
整数、浮点数、精确小数、二进制数据、日期/时间、字符串数据等。
创建数据表
主码,候选码:
唯一标识每一行记录。
主键:
ALTER TABLE table_name
ADD CONSTRAINTS constraint_name PRIMARY KEY (filed_names);
ALTER TABLE table_name
DROP CONSTRAINTS constraint_name;
外键:为空或者另一个表的主键值,保持参照完整性,保持数据的一致性、完整性。
CONSTRAINT <constraint_name> FOREIGN KEY (filed_names)
REFERENCES table_name (key_names);
E.g
CREATE TABLE tb_dept1
(
id NUMBER(11) PRIMARY KEY,
name VARCHAR2(22)NOT NULL,
location VARCHAR2(50)
);
CREATE TABLE tb_emp
(
id NUMBER(11) PRIMARY KEY,
name VARCHAR2(25),
deptId NUMBER(11),
salary NUMBER(9,2),
CONSTRAINT fk_emp_deptFOREIGN KEY(deptId)
REFERENCES tb_dept1 (id)
);
修改已有表:
ALTER TABLE table_name
ADD CONSTRAINTS constraint_name FOREIGN KEY (filed_names)
REFERENCES table_name (key_names)
ON DELETE CASCADE;
ALTER TABLE table_name
DROP CONSTRAINTS constraint_name;
非空约束: NOT NULL
ALTER TABLE table_name
MODIFY field_name <NOT> NULL;
唯一约束: UNIQUE
可以有多个字段被声明为唯一,并且允许空值存在。
CREATE TABLE tb_dept1
(
id NUMBER(11) PRIMARY KEY,
name VARCHAR2(22)NOT NULL,
location VARCHAR2(50),
CONSTRANIT sth UNIQUE (name)
);
修改已有表:
ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE (field_name);
ALTER TABLE table_name
DROP CONSTRAINTS constraint_name;
默认值: DEFAULT value
检查约束:
CONSTRAINT chk_gender CHECK (gender = '男' or gender = '女')
ALTER TABLE table_name
ADD CONSTRAINT constraint_name CHECK (condition);
ALTER TABLE table_name
DROP CONSTRAINTS constraint_name;
设置表的属性自动递增: GENERATED BY DEFAULT AS IDENTITY
Oracle 中 初始值为1,且使用自增属性的字段只有一个,必须为主键的一部分。
查看数据表结构
DESCRIBE / DESC table_name;
修改数据表
修改表名:
ALTER TABLE old_name RENAME TO new_name;
修改字段的数据类型:
ALTER TABLE table_name
MODIFY filed_name data_type;
修改字段名:
ALTER TABLE table_name
RENAME COLUMN column_name TO new_name;
添加/删除字段:
ALTER TABLE table_name
ADD field_name data_type <NOT NULL> <UNIQUE>;
ALTER TABLE table_name
DROP COLUMN field_name;
删除数据表
DROP TABLE table_name;
当存在外键约束时,先删除constraints,然后再删除表。
DBS:
包括了DB(存储数据的容器,可以有多个), DBMS(能定义数据存储结构,操作数据,维护安全性、完整性和可靠性), 以及人和相关应用程序(与DBMS通信,提供更直观的界面)等等。
SQL: Structured Query Language
1. DDL: drop, create, alter
2. DML: insert, update, delete
3. DQL: select
4. DCL: grant, revoke, commit, rollback
数据库访问技术:
1. ODBC: open db connectivity
使用SQL作为访问数据库的标准,不依赖DBMS,所有操作由DBMS的ODBC驱动完成,能以统一的方式处理所有数据库。
2. JDBC
JAVA api, 为多种关系数据库通过统一访问。
3. ADO.NET
微软的用于与数据源进行交互的面向对象类库,提供了对关系数据和应用程序数据的访问,允许和不同的数据源及数据库进行交互。
4. PDO: PHP data object
提供了一个数据访问抽象层。
=============================================================================================
Oracle简介
大型关系数据库管理系统,企业级开发。
运行速度快,稳定性好,共享SQL和多线索服务器体系结构(更少资源),可移植性,安全性强,支持类型多,方便管理数据。
管理工具: Qracle SQL developer, SQL PLUS
数据类型
1.数值类型
number(m, n)
m: 1~38 有效数字的位数, n: -84 ~ 127 小数点之后的位数
多余部分会被截取。
2. 日期与时间
DATE: 存储时间与日期,取值 公元前4712年1月1日到9999年12月31日
TIMESTAMP: 更精确,到小数秒,还可以显示上午、下午和时区。
数据库默认时间格式:
select sysdate from dual;
修改时间的默认格式:
alter session set nls_date_format = 'yyyy-mm-dd';
INSERT INTO table_name values (SYSDATE);
INSERT INTO table_name values (to_date ('2014-02-01 12:12:12' , 'yyyy-MM-dd HH24:mi:ss') );
显示时仍只有日期。
改为timestamp 后,to_timestamp 插入数据,可以显示出时间。
3. 字符串类型
CHAR:
描述定长的字符型数据,0~2000 byte
NCHAR:
存储Unicode字符集的定长字符,0~1000byte
VARCHAR2:
存储可变长的字符,0~4000byte
NVARCHAR2:
存储Unicode的可变字符,0~1000byte
LONG:
存储变长的字符串,0~2GB
变长类型:存储需求取决于实际存储长度。
如何选择数据类型
对速度有要求或者列的长度几乎不变时,选择CHAR,否则考虑到存储应该选择变长的。
注意如果某列经常发生长度大小改变,应该使用CHAR,需要避免不必要的I/O。
4. 常见运算符
算术: +,-,*, /
比较: >, <, =, IN, BETWEEN AND, IS NULL, LIKE等
逻辑: TRUE, FALSE, NOT, AND, OR, XOR
位操作: &, |, ~, ^, <<, >>
E.g
SELECT name FROM Student
WHERE birth >= '1980' AND birth <= '1990';
SELECT name FROM Student
WHERE age IN (25,26);
LIKE: % 匹配0或者多个字符, _ 匹配一个字符。
blob, clob, nclob 大型对象:
可以保存图形文件或者文本文件,比如word,音频等,最大长度4GB.
查询数据
1. 单表查询
一般不要使用通配符查询,不必要的数据查询浪费时间。
一般关键字大写,表名和数据列名使用小写。
在多列进行排序时,第一列必须有相同的值才会对第二列排序,如果第一列唯一,那么不再排序。
默认排序是升序,可以显示 DESC 关键字表示降序排列。
HAVING 用于分组之后,组内进行过滤。
ROLLUP: 用在GROUP BY 之后
在所有查询的分组记录之后增加一条记录,计算查询出的所有记录的总和,即统计记录数量。
与ORDER BY 是互斥的。
ROWNUM:
限制查询结果的行数,只支持 < <= 和 !=
聚合函数:
AVG, COUNT(指定列的值的空行会被忽略,如果是* 则都不忽略), MAX, MIN(也适用于字符串), SUM
2. 连接查询
内连接:
SELECT tb_1.id, name, location FROM tb_1 INNER JOIN tb_2
ON tb_1.id = tb_2.id;
这种方式比 WHERE更好。
如果连接查询中,两个表为同一个,则是自连接查询。
外连接: LEFT JOIN 包含所有左表的数据,没有的右表数据默认为NULL, RIGHT JOIN
复合条件连接查询: 可以添加排序等过滤条件
3. 子查询
常用操作符: ANY/SOME, ALL, IN, EXISTS,
可以使用 UNION 合并子查询结果,会去除重复; UNION ALL 保留重复,效率更高一点。
AS:为表和字段取别名,注意不要冲突。
4. 使用正则表达式
REGEXP_LIKE()
^ 匹配文本开头字符
$ 匹配文本结束字符
. 匹配任何单个字符
* 匹配0或者多个在它前面的字符
+ 匹配1或者多次前面的字符
<字符串> 指定包含字符串
[字符集和] 匹配任意一个字符
[^ ] 匹配不在里面的任何字符
字符串{n, } 至少出现n次
字符串{n,m} 至多m次
REGEXP_LIKE 会在文本内进行匹配,而LIKE是无法找到中间出现的字符串的,注意保存字符串时可能会有多余空格,可以用TRIM去除。
插入、更新与删除数据
DB是用来管理data的存储访问和维护数据的完整性。
1. 插入
如果忽略插入数据的列名称,在表结构修改或者列进行增删时,这种方式插入的数据也要受到影响而改变;
如果指定列名称,则不会受影响。对于其他未指定的列,使用默认值。
在插入多条数据时,最好使用单条INSERT语句。
INSERT INTO person (id, name)
SELECT 8, 'AMY' FROM dual
UNION ALL
SELECT 9, 'hally' FROM dual;
INSERT INTO table_1 (column_list1)
SELECT (column_list2) FROM table_2 WHERE (condition);
不关心列名是否相同,只需要类型和数量一致。
2. 更新
UPDATE table_name
SET column_name = value , ...,
WHERE (condition);
如果忽略WHERE的话,那么更新所有的行。
3. 删除
DELETE FROM table_name WHERE condition;
如果不指定 WHERE条件,那么删除表所有记录。
使用 TRUNCATE TABLE table_name; 直接删除表比DELETE 更快。
视图
视图是虚拟表,是从数据库中的表导出来的,基本表发生变化时,视图也会自动改变,使用户操作方便,保障数据库系统的安全。
优点:
1. 简单化
2. 安全性:用户被限制在不同的数据子集上,不会有数据库行列的权限。
3. 逻辑数据独立性:帮助用户屏蔽真实表结构变化带来的影响。
1. 创建
可以在单个或多个表上,或者视图上建立视图。
CREATE [OR REPLACE] [[NO] FORCE] VIEW
[schema.] view
[(alias, ...) inline_constraint(s)]
[out_of_line_constraint(s)]
AS sub_query
[
WITH { READ ONLY CHECK OPTION [CONSTRAINT constraint]}
];
创建的视图的字段名称也可以改变,用户对底层表不必了解。
CREATE VIEW view(qty, pri)
AS SELECT quantity, price FROM table;
CREATE OR REPLACE VIEW stu_glass
AS
SELECT view.id, view.name
FROM view;
强制创建没有源图的视图: 成功,但是会有编译错误。
CREATE OR REPLACE FORCE VIEW gl_glass
AS
SELECT stu.id, stu.name
FROM glass;
2. 查看视图
DESCRIBE view;
3. 修改
CREATE OR REPLACE VIEW view...
ALTER VIEW view
ADD CONSTRAINT t_unq UNIQUE (qty)
DISABLE NOVALIDATE; // 此前数据和以后数据都不检查
ALTER VIEW view
DROP CONSTRAINT t_unq;
4. 更新
进行视图更新的时候,转到了基本表上进行。
UPDATE view SET ...;
DROP VIEW (IF EXISTS) view;
5. 限制操作
WITH READ ONLY;
WITH CHECK OPTION;
6. 视图与表
1. 是编译好的SQL,是基于SQL的结果集的可视化的表。
2. 没有实际物理记录。
3. 是一种窗口,而表是内容。
4. 表占有物理空间,可以及时进行修改;视图只能用 创建的方式进行修改,且是逻辑概念。
5. 表是属于全局模式的表,是实表;视图是属于局部模式的表,是虚表。
6. 视图的建立和删除不影响对应的基本表。
7. 何时不能进行更新视图
视图中不包含基表中定义为非空的列;
定义视图的SELECT 语句后的字段列表使用了数学表达式或者聚合函数, DISTINCT,UNION,TOP,GROUP BY, HAVING 等语句。
游标
游标是一种数据访问机制,允许用户访问单独的数据行,可以对每一行进行单独处理,降低系统开销和潜在的阻隔情况。
游标可以提供在结果集中向前或者向后浏览数据的功能。默认情况下,可以返回当前执行的行记录,只能返回一行。
优点:
1. 允许程序对结果集中的每一行执行操作,而不是整个集合。
2. 提供对基于游标位置的表中的行进行删除和更新的能力。
3. 把DBMS和应用程序设计的处理方式连接起来。
分类:
静态游标:
1. 显式游标: 使用前明确声明和定义,由用户控制,可以打开关闭游标,对结果集操作。
2. 隐式游标: 被数据库自动管理,用户只能得到属性信息。
1. 显式游标:
声明,打开,读取数据,关闭
DECLARE CURSOR cursor_name
IS SELECT name, price FROM fruit;
OPEN cursor_name;
FENTCH cursor_name INTO record_name;
//需要读取多个记录时,和循环语句一起使用,使用FENTCH时游标的属性%ROWCOUNT会累加。
CLOSE cursor_name;
set serveroutput on; %打开Oracle自带的输出方法 dbms_output
DECLARE
CURSOR frt_cur
IS SELECT id,name FROM fruits;
cur_fruit frt_cur%ROWTYPE; %定义一个游标变量,变量类型同frt_cur对应的类型一致
BEGIN
OPEN frt_cur;
FENTCH frt_cur INTO cur_fruit;%提取当前行记录
dbms_output.put_line(cur_fruit.id || '.' || cur_fruit.name); %输出结果并换行
CLOSE frt_cur;
END;
set serveroutput on; %打开Oracle自带的输出方法 dbms_output
DECLARE
CURSOR frt_loop_cur
IS SELECT id,name,price FROM fruits
WHERE price > 10;
cur_id fruits.id%TYPE; %变量类型同id对应的类型一致
cur_name fruits.name%TYPE;
cur_price fruits.price%TYPE;
BEGIN
OPEN frt_loop_cur;
LOOP
FENTCH frt_loop_cur INTO cur_id, cur_name, cur_price;%提取当前行记录
EXIT WHEN frt_loop_cur%NOTFOUND; %没有记录时退出循环
dbms_output.put_line(cur_id || '.' || cur_name || '.' || cur_price); %输出结果并换行
END LOOP;
CLOSE frt_loop_cur;
END;
set serveroutput on; %打开Oracle自带的输出方法 dbms_output
DECLARE
CURSOR frt_collect_cur
IS SELECT * FROM fruits
WHERE price > 10;
TYPE FRT_TAB IS TABLE OF FRUITS%ROWTYPE;
frt_rd FRT_TAB; %定义和表行对象一致的集合类型,该变量用于存放批量得到的数据
BEGIN
OPEN frt_collect_cur;
LOOP
FENTCH frt_collect_cur BULK COLLECT INTO frt_rd LIMIT 2;%提取两条行记录
FOR i IN 1 .. frt_rd.count LOOP
dbms_output.put_line(frt_rd(i).id || '.' || frt_rd(i).name || '.' || frt_rd(i).price); %输出结果并换行
END LOOP;
EXIT WHEN frt_collect_cur%NOTFOUND;
END LOOP;
CLOSE frt_collect_cur;
END;
set serveroutput on;
DECLARE
CURSOR frt1 IS SELECT * FROM fruits
WHERE price > 10;
BEGIN
FOR curfrt1 IN frt1
LOOP
dbms_output.put_line(curfrt1.id || '.' || curfrt1.name || '.' || curfrt1.price );
END LOOP;
CLOSE frt1; ??? %使用完游标记得关闭
END;
显式游标的属性:
%ISOPEN
%FOUND: 行数据是否有效
%NOTFOUND
%ROWCOUNT: 累计到目前为止使用FENTCH 提取数据的行数。
2. 隐式游标:
每当运行SELECT语句时,由数据库自动创建和管理,默认名称为SQL。
其属性 %ISOPEN 永远返回 FALSE; %FOUND 表示操作是否影响了数据; %ROWCOUNT 反映操作对数据的影响数量。
SELECT INTO 只能返回一行数据,超过时会报错。
set serveroutput on;
DECLARE
cur_id fruits.id;
cur_name fruits_name;
cur_price fruits_price;
cur_count varchar2(8);
BEGIN
SELECT id, name , price INTO cur_id, cur_name, cur_price
FROM fruits;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('SQL%ROWCOUNT'|| '没有数据');
WHEN TOO_MANY_ROWS THEN
cur_count := SQL%ROWCOUNT;
dbms_output.put_line('SQL%ROWCOUNT 值为:' || cur_count);
END;
存储过程
存储过程是一组SQL语句,存储在数据库中经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数来执行它,
优点:
1. 减少网络通信量: 大量SQL语句时,存储过程性能优
2. 执行速度快: 创建时,数据库已经进行解析和优化; 内存中保留,直接调用。
3. 更强的适应性
4. 分布式工作
创建:
CREATE [OR REPLACE ] PROCEDURE
[schema.] procedure_name
[parameter_name [[IN] datatype [{:= DEFAULT} expression]]]
{IS | AS}
BODY:
调用: 也可以在BEGIN END中调用
execute/ exec procedure_name;
查看: 在视图 USER_SOURCE 或者 ALL_SOURCE 中查看,需要大写存储过程名称
SELECT * FROM USER_SOURCE WHERE NAME = 'HELLO' ORDER BY LINE;
参数:
1. 无参
CREATE PROCEDURE FRUIT_PRC
AS
BEGIN
UPDATE fruits SET name = '打折水果'
WHERE id IN
(
SELECT id IN
( SELECT * FROM fruits ORDER BY price ASC)
WHERE ROWNUM < 3
);
COMMIT;
END;
2. 有参数: 可以是常量、变量或表达式
CREATE PROCEDURE FRUITS_PRCC(parm_sid IN NUMBER(6))
AS
cur_id fruits.id%TYPE;
cur_prtifo fruits%ROWTYPE;
BEGIN
SELECT fruits.id INTO cur_id
FROM fruits
WHERE id = parm_sid;
IF SQL%FOUND THEN
dbms_output.put_line(parn_sid || ':');
END IF;
FOR cur_prtifo IN
(SELECT * FROM fruits WHERE CATEGORY = cur_id)
LOOP
dbms_output.put_line('水果名称' || cur_prtifo.name || ' 水果价格' || cur_prtifo.price);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('没有数据');
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('数据过度');
END;
修改:
CREATE OR REPLACE ...
DROP PROCEDURE procedure_name;
SHOW ERRORS PROCEDURE procedure_name; % 查看存储过程的错误
存储过程的代码不可以改变,只能覆盖或者重建。
删除存储过程时,注意调用关系。
触发器
特殊的存储过程,不需要EXEC执行,当一个预定义的事件发生的时候,就会被Oracle自动调用。主要用于满足复杂的业务规则或要求。
CREATE TRIGGER trigger_name BEFORE/AFTER trigger_event (UPDATE, INSERT, DELETE)
ON table_name FOR EACH ROW trigger_stmt
CREATE TRIGGER test_tri
BEFORE INSERT
ON table1
BEGIN
IF INSERT THEN
DBMS_OUTPUT.PUT_LINE('下面开始插入数据');
END IF;
END;
查看触发器:
SELECT OBJECT_NAME FROM USER_OBJECT
WHERE OBJECT_TYPE = 'TRIGGER';
SELECT * FROM USER_SOURCE WHERE NAME = 'TEST_TRI' ORDER BY LINE;
CREATE OR REPLACE TRIGGER trigger_name ...
DROP TRIGGER trigger_name;
注意:
1. 对于相同的表,相同的事件只能创建一个触发器
2. 应该及时把不用的触发器删除。
管理表空间
表空间是数据库的逻辑划分,一个表空间只属于一个数据库。所有数据库对象都存放在指定的表空间中。
一个数据库可以有多个表空间,一个表空间内存放多个物理的数据库文件,是数据库恢复的最小单位,容纳着许多数据库实体,如表,视图,索引,聚簇等。
Oracle 至少有一个表空间,SYSTEM表空间是自动创建的,必须保持联机,其中包含数据库运行需要的信息,包括数据字典,回退段,临时段等。
能帮助DBA:
1. 决定数据库实体的空间分配。
2. 设置数据库用户的空间份额。
3. 控制数据库部分数据的可用性。
4. 数据分布改善性能
5. 备份和恢复数据
用户至少需要权限:
1. 关于一个或多个表空间的RESOURCE特权
2. 被指定默认表空间
3. 被分配指定表空间的使用份额
4. 被指定默认临时段表空间,建立不同的表空间,设置最大存储容量
Oracle 12c 中默认的表空间有:
SYSTEM:存储SYS用户的表,视图和存储过程等对象
SYSAUX:安装数据库使用的实力数据库
UNDOTBS1:用于存储撤销消息
TEMP:用户存储SQL语句处理的表和索引信息
USERS:存储数据库用户创建的数据库对象
查询当前登录用户默认的表空间:
SELECT TABLESPACE_NAME FROM DBA_TABLESPACES;
查看某个用户的默认表空间:
SELECT DEFAULT_TABLESPACE , USERNAME FROM DBA_USERS WHERE USERNAME LIKE 'SYS%';
查询表空间使用情况:
SELECT * FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME = 'SYSTEM';
创建表空间: 最好本地管理方式,减少数据字典竞争现象,也不需要对表空间进行回收。
CREATE TABLESPACE mytem
DATAFILE 'MYTEM.DBF' SIZE 30M
AUTOEXTEND ON NEXT 256KB
MAXSIZE 2048M
[PERMANENT | TEMPORARY]
[EXTEND MANAGEMENT LOCAL | DICTIONARY];
表空间为联机状态时可以操作:
ALTER TABLESPACE tablespce { ONLINE | OFFLINE [NORMAL | TEMPARORY | IMMEDIATE ]};
ALTER TABLESPACE tablespace READ {ONLY | WRITE};
ALTER TABLESPACE tablespace RENAME TO newname;
同时删除表空间文件或者完整性也删除。
DROP TABLESPACE tablespace INCLUDING CONTENTS | CASCADE CONSTRAINTS;
CREATE BIGFILE TABLESPACE tablespace
DATAFILE filename SIZE size;
管理临时表空间:
存放临时数据,当数据库中执行存储操作时,如果内存不够可以写入临时表空间,执行完操作后,自动清空。
CREATE TEMPORARY TABLESPACE mytmp
TEMPFILE 'MYTMP.DBF' SIZE 30M;
SELECT TABLESPACE_NAME FROM DBA_TEMP_FILES;
创建临时表空间组:
CREATE TEMPORARY TABLESPACE name
TEMPFILE 'NAME.DBF' SIZE 30M TABLESPACE GROUP testgroup;
ALTER TABLESPACE mytmp GROUP testgroup;
SELECT * FROM DBA_TABLESPACE_GROUPS;
DROP TABLESPACE name INCLUDING CONTENTS AND DATAFILES;
删除组后不能回复,应该先删除表空间,再删除组。
创建表空间时,数据文件也创建了,移动数据文件:
1. ALTER TABLESPACE mytmp OFFLINE;
2. 手动移动文件到其他表空间
3. ALTER TABLESPACE mytmp RENAME TO mytp;
4. ALTER TABLESPACE mytmp ONLINE;
删除不再使用的数据文件:
何时不能删:
1. 数据文件或者表空间只读
2. 数据文件中有数据
3. 数据文件是表空间中唯一一个或者第一个数据文件
事务
事务包含一条或多条语句,是Oracle中的基本工作单元,是用户定义的一个数据库操作序列,不可分割。
ACID:
原子性,一致性(所有数据具有一致状态,原来的规则仍沿用),隔离性(可串行,互相不重叠),持久性(影响永久)
常用语句:
SET TRANSACTION
COMMIT
SAVEPOINT
ROLLBACK
ROLLBACK TO SAVEPOINT
显式事务:
登录数据库或事务结束后,第一次DML执行时事务会开启。
隐式事务:
每条数据操作语句,例如SELECT, INSERT等都是隐式事物的一部分。
事务结束的情况:
1. 执行DDL语句,如CREATE, GRANT, DROP
2. COMMIT, ROLLBACK 执行
3. 正常退出SQL Plus 自动提交,否则ROLLBACK。
事务日志:
保存针对数据的操作或者针对任务的操作(如创建索引),当取消事务操作时,系统执行反操作,保证系统一致性。
检查点机制:
如果日志中事务全部完成,则检查点把事务提交到数据库,并作一个检查点提交标识;
否则,做未提交标识。
锁
锁在共享资源中进行控制访问。Oracle处理数据时用到的锁自动获取,也运行用户手动上锁。
并发操作可能出现的问题:
脏读,幻读(UPDATE同时进行了INSERT),不可重复读(因为某个事物改变了数据,多次读取的数据不同),丢失更新(多个更新只能保存最后一个)。
分类:
共享锁:用于读数据,允许多个同时读,不允许修改
排它锁:用于修改,确保不会多重更新
形成死锁的条件:
请求与保持,不可剥夺,循环等待,互斥条件。
可能死锁的资源:
锁,线程,内存,并发查询执行的相关资源。
减少死锁:
相同的次序使用资源,设置超时参数,避免在事务内与用户交互减少锁定时间。
在事务中使用锁保护指定的资源,事务,锁,触发器,约束等都是为了保护数据完整性。