# 确保表不存在
drop table if exists department;
# 创建表
create table department(
d_id int auto_increment primary key,
d_name varchar(6)
)auto_increment = 501 ;
# 确保表不存在
drop table if exists employee;
# 创建表
create table employee(
id int auto_increment primary key,
name varchar(10),
password varchar(20),
money int default 1000,
sex enum('female', 'male') default 'male',
department_id int
);
insert department (d_name) values("销售部"), ("技术部"), ("售后部");
+-----+-----------+
| id | name |
+-----+-----------+
| 501 | 销售部 |
| 502 | 技术部 |
| 503 | 售后部 |
+-----+-----------+
insert employee (name, sex, password, department_id)values
('John', 'male', '111', 501),
('Jane', 'female', '222', 503),
('Mike', 'male', '333', 502),
('Tom', 'male', 'aaa', 503),
('Amy', 'female', '999', 501);
+----+------+----------+-------+--------+---------------+
| id | name | password | money | sex | department_id |
+----+------+----------+-------+--------+---------------+
| 1 | John | 111 | 1000 | male | 501 |
| 2 | Jane | 222 | 1000 | female | 503 |
| 3 | Mike | 333 | 1000 | male | 502 |
| 4 | Tom | aaa | 1000 | male | 503 |
| 5 | Amy | 999 | 1000 | female | 501 |
+----+------+----------+-------+--------+---------------+
简化复杂查询:通过在视图中定义复杂的查询逻辑,包括连接多个表、过滤条件、聚合函数等,使用户能够以更简洁明了的方式进行数据检索。
数据安全性:通过限制用户对数据的访问权限,视图可以用于隐藏敏感数据或只提供部分数据给特定的用户。通过定义视图并设置相应的权限,可以保护数据的安全性,防止未经授权的用户访问敏感信息。
数据完整性:视图可以用于实现数据完整性约束,即对数据的有效性进行验证。通过定义视图并添加计算列、过滤条件等约束,可以确保所返回的数据满足一定的条件,提高数据的准确性和一致性。
逻辑数据独立性:通过解耦应用程序与底层数据表结构,视图使得应用程序不需要了解底层表结构的细节。这样,当底层数据库发生变化时,只需调整底层视图的定义而无需修改应用程序,提高系统的可维护性和扩展性。
性能优化:物化视图作为一种缓存机制,将视图的查询结果存储在磁盘上,提高查询性能。特别在基本表数据频繁变动时,物化视图可以减少查询的计算开销和响应时间,从而提升系统的性能。
create view 视图名 as
select 字段名,...
from 表名
join 表名 on 条件
where 条件
create view emp_dep as
select * from employee
left join department
on employee.department_id = department.d_id;
select * from emp_dep;
+----+------+--------+---------------+------+-----------+
| id | name | sex | department_id | d_id | d_name |
+----+------+--------+---------------+------+-----------+
| 1 | John | male | 501 | 501 | 销售部 |
| 5 | Amy | female | 501 | 501 | 销售部 |
| 3 | Mike | male | 502 | 502 | 技术部 |
| 2 | Jane | female | 503 | 503 | 售后部 |
| 4 | Tom | male | 503 | 503 | 售后部 |
+----+------+--------+---------------+------+-----------+
insert employee (name, sex, department_id)
values('lulu', 'female', 502);
select * from emp_dep;
+----+------+--------+---------------+------+-----------+
| id | name | sex | department_id | d_id | d_name |
+----+------+--------+---------------+------+-----------+
| 1 | John | male | 501 | 501 | 销售部 |
| 5 | Amy | female | 501 | 501 | 销售部 |
| 3 | Mike | male | 502 | 502 | 技术部 |
| 6 | lulu | female | 502 | 502 | 技术部 |
| 2 | Jane | female | 503 | 503 | 售后部 |
| 4 | Tom | male | 503 | 503 | 售后部 |
+----+------+--------+---------------+------+-----------+
delete from emp_dep
where id = 6;
ERROR 1288 (HY000): The target table emp_dep of the DELETE is not updatable
update emp_dep
set department_id = 502
where name = tom;
ERROR 1288 (HY000): The target table emp_dep of the UPDATE is not updatable
show tables;
+---------------+
| Tables_in_db4 |
+---------------+
| department |
| emp_dep |
| employee |
+---------------+
desc emp_dep;
+---------------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------------------+------+-----+---------+-------+
| id | int(11) | NO | | 0 | |
| name | varchar(10) | YES | | NULL | |
| sex | enum('female','male') | YES | | male | |
| department_id | int(11) | YES | | NULL | |
| d_id | int(11) | YES | | 0 | |
| d_name | varchar(6) | YES | | NULL | |
+---------------+-----------------------+------+-----+---------+-------+
drop view id exists 触发器名;
drop view emp_dep;
;
;
出现# 修改为 $$
delimiter $$
# 修改回来 ;
delimiter ;
delimiter $$
create trigger 触发器名
{before | after} {insert | update | delete} on 表名
for each row
begin
--触发器执行的语句
--new
--old
end $$
delimiter ;
# 例如
tri_表名_after_insert
NEW
:
NEW
用于引用触发器中正在处理的行的新值。在 BEFORE INSERT
和 BEFORE UPDATE
触发器中,NEW
包含即将插入或更新到表中的数据。在 AFTER INSERT
、AFTER UPDATE
和 AFTER DELETE
触发器中,NEW
包含已经插入、更新或删除的数据。BEFORE INSERT
和 AFTER INSERT
触发器中,NEW
是唯一的,并包含即将或已经插入到表中的数据。OLD
:
OLD
用于引用触发器中正在处理的行的旧值。在 BEFORE UPDATE
和 AFTER UPDATE
触发器中,OLD
包含即将或已经被更新的行的旧值。在 BEFORE DELETE
和 AFTER DELETE
触发器中,OLD
包含即将或已经被删除的行的旧值。BEFORE UPDATE
和 AFTER UPDATE
触发器中,OLD
包含被更新的数据的旧值。在 BEFORE DELETE
和 AFTER DELETE
触发器中,OLD
包含被删除的数据的旧值。drop trigger if exists 触发器名
delimiter $$
create trigger tri_employee_before_insert before insert on employee
for each row
begin
if new.department_id not in (select d_id from department) then
signal sqlstate '45000'
set message_text = "部门id不存在";
end if;
end $$
delimiter ;
insert employee (name, sex, department_id) values('liuliu', 'male', 505);
ERROR 1644 (45000): 部门id不存在
minsert employee (name, sex, department_id) values('liuliu', 'male', 501);
Query OK, 1 row affected (0.00 sec)
drop trigger if exists tri_employee_after_update;
delimiter $$
create trigger tri_employee_after_update after update on employee
for each row
begin
if old.password = new.password then
signal sqlstate '01000'
set message_text = '修改成功,但密码安全性较低,和之前一样';
# 不允许返回值
# select '修改成功,但密码安全性较低,和之前一样';
end if;
end $$
delimiter ;
# 查看id为2的员工密码
select password
from employee
where id=2;
+----------+
| password |
+----------+
| 222 |
+----------+
# 修改的密码和之前一样
update employee
set password = '222'
where id = 2;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
CREATE TRIGGER generate_uuid_trigger BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
SET NEW.uuid = UUID();
END
CREATE TRIGGER update_last_modified_trigger BEFORE UPDATE ON table_name
FOR EACH ROW
BEGIN
SET NEW.last_modified = NOW();
END
CREATE TRIGGER archive_deleted_record_trigger AFTER DELETE ON table_name
FOR EACH ROW
BEGIN
INSERT INTO history_table (id, deleted_at)
VALUES (OLD.id, NOW());
END
CREATE TRIGGER check_condition_trigger BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
IF NEW.column_name < 10 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Value must be greater than 10';
END IF;
END
# 主要是为了区分错误执行语句和全局结束语句
create trigger tri_after_insert_cmd after insert on cmd
for each row
begin
if NEW.success = "no" then
insert into errlog(err_cmd,err_time)
values(NEW.cmd,NEW.sub_time);
end if;
end
用户提交订单的操作流程可以总结为以下步骤:
这个流程确保了在用户提交订单后,系统进行了必要的检查、处理、通知和更新操作,以提供完整的购物体验。
# 开启事务
start transaction;
# 执行事务操作
......
......
# 提交事务或者回滚事务
# 此时会结束事务
commit; | rollback;
任务
初始每个人都是1000元
让我们来试试一号给二号转100元试试
开启事务
start transaction;
update employee
set money = money - 100
where id = 1;
update employee
set money = money + 100
where id = 2;
select id, money
from employee
where id in (1, 2);
+----+-------+
| id | money |
+----+-------+
| 1 | 900 |
| 2 | 1100 |
+----+-------+
rollback;
select id, money
from employee
where id in (1, 2);
+----+-------+
| id | money |
+----+-------+
| 1 | 1000 |
| 2 | 1000 |
+----+-------+
update employee
set money = money - 100
where id = 1;
update employee
set money = money + 100
where id = 2;
commit;
rollback;
select id, money
from employee
where id in (1, 2);
+----+-------+
| id | money |
+----+-------+
| 1 | 900 |
| 2 | 1100 |
+----+-------+