数据库基本操作(大多使用例子来解释操作命令)

在开始介绍数据库基本操作之前,我们需要了解什么是数据库。

数据库是按照数据结构来组织、存储和管理数据的仓库。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。

简单的说,数据库就是存储数据的仓库,它的作用就是存储数据,因此,我们操作数据库实质是想要操作数据库的数据。因此对数据库的操作实质就是对数据库进行增删改查数据。

(我们老师说三天讲完数据库相关内容,看能不能做到,哈哈哈哈)


创建数据库和表,修改约束,添加删除字段(day one)

-- 创建数据库
CREATE DATABASE company;
-- 进入数据库
use company;
-- 创建数据库中的表一 offices
CREATE table offices(
  officeCode int(10) UNIQUE NOT NULL,
  city int(11) NOT NULL,
  address VARCHAR(50),
  country VARCHAR(50) NOT NULL,
  postalCode VARCHAR(50) UNIQUE,
-- 设置主键
  PRIMARY KEY(officeCode)
);
-- 创建数据库中的表二 employees
CREATE table employees(
  employeeNumber INT(11) UNIQUE NOT NULL auto_increment,
  lastName VARCHAR(50) NOT NULL,
  firstName VARCHAR(50) NOT NULL,
  mobile VARCHAR(25) UNIQUE,
  officeCode INT(10)NOT NULL,
  jobTitle VARCHAR(50) NOT NULL,
  birth DATETIME NOT NULL,
  note VARCHAR(255),
  sex VARCHAR(5),
  PRIMARY KEY(employeeNumber),
-- 设置外键
  CONSTRAINT fk_office_employee FOREIGN KEY (officeCode) REFERENCES offices(officeCode)
);

-- 修改位置(将mobile字段移动到officeCode之后)
ALTER table employees MODIFY mobile VARCHAR(25) AFTER officeCode;
-- 修改字段名字(将birth字段改名为employee_birth)
ALTER TABLE employees CHANGE birth employee_birth DATE;
-- 修改字段的数据类型(将sex从varchar修改为char)
ALTER TABLE employees MODIFY sex CHAR(1) NOT NULL;
-- 删除表中字段(将note字段删除)
ALTER TABLE employees DROP note;
-- 添加新字段(添加favoriate_activity)
ALTER TABLE employees add favoriate_activity VARCHAR(100);
-- 删除一个作为外键的表,需要先将关联外键的关联解除,然后删除表
ALTER table employees DROP FOREIGN KEY fk_office_employee;
-- 删除表
DROP TABLE offices;
-- 修改数据库引擎
ALTER TABLE employees ENGINE=MyISAM;
-- 修改表名
ALTER TABLE employees RENAME employees_info;

-- 检查表的情况
SELECT * FROM offices;
SELECT * FROM employees;

-- 检查表的结构
DESC offices;
DESC employees;

上面的例题是对数据库表进行创建修改删除的一些简单命令。

在列出常用命令之前还是要先对数据库有一定的了解。

数据库分为关系型数据库和非关系型数据库。

关系型数据库就是指表与表之间有很多复杂的关联关系的数据库。常见的关系型数据库有MySQL、SqlServer和Oracle等。

非关系型数据库又被称为NoSQL(Not Only SQL ),意为不仅仅是SQL( Structured QueryLanguage,结构化查询语言),不需要事先定义结构,也就是不需要建表建库等,每条记录可以又不同的类型和约束条件。非关系型数据库分为四种:

1是使用键值对存储:代表软件为redis

2是使用列储存:代表软件为Hbase

3是文档数据库存储:代表软件为MongoDB

4是使用图形护具库存储:代表软件为InfoGrid

创建数据库和数据表相关的命令

创建数据库
-- CREATE DATABASE 数据库名

查看数据库
-- show DATABASES;

删除数据库
-- DROP DATABASE IF EXISTS 数据库名;

切换数据库
-- USE 数据库名;

查看数据库引擎
-- show ENGINES;

查看当前默认引擎
-- show VARIABLES like 'storage_engine';

创建表
-- CREATE table 表名(
-- 列名 数据类型 [约束] [默认值]
-- )[ENGINE=存储引擎][DEFAULT CHARSET=字符编码集];

-- 存储引擎的选择:MYISAM(支持全文索引)  INNODB(支持事务,外键) memory(哈希索引)

mysql支持的数据类型
-- 数值类型:
--          整数:int(n)
--          小数类型:decinal(m,n)

字符串类型:
--          定长:char(n) 若长度小于n,则使用空格填充
--          可变长:varchar(n)

-- SET(值1,值2,……)  类似枚举
-- 日期类型 DATE TIME 

数据库中的约束概念和添加删除主外键的方法

3个列级别
-- 非空约束
-- 唯一键约束
-- 默认值约束
两个表级别
-- 主键约束
-- 外键约束

表已经创建的情况下添加主外键约束
-- ALTER TABLE 表名 ADD PRIMARY KEY(主键字段)/FOREIGN KEY;
-- ALTER table 从表名 ADD CONSTRAINT fk_xx_xxx FOREIGN KEY(外键字段名) REFERENCES 主表名(主表主键);

表已经创建的情况下删除主外键
-- ALTER table 表名 DROP PRIMARY KEY/FOREIGN KEY;
-- ALTER TABLE 从表名 DROP FOREIGN KEY fk_xx_xxx;

修改操作的命令

修改表名
-- alter table 旧表名 RENAME [TO] 新表名;

修改字段的数据类型
-- ALTER TABLE 表名 MODIFY 字段名 字段类型 [约束];

查看表结构
-- DESC tb_temp1;

修改字段名
-- ALTER TABLE 表名 CHANGE 旧字段名 新字段名 数据类型;

添加字段
-- ALTER TABLE 表名 ADD 新字段名 数据类型 约束;

删除字段
-- ALTER TABLE 表名 DROP 字段名;

修改字段的排列位置
-- ALTER TABLE 表名 MODIFY 字段名 数据类型 FIRST|AFTER 已经存在的列名;

修改表的存储引擎
-- ALTER TABLE 表名 ENGINE=值;

对表内数据进行增删改查的操作(day two)

数据库中的内容比较复杂的是查询,本次的例题就都是查询的使用,其中相对较为复杂的又是多表查询的内容。

所以,就简单的放点常用命令在下面好了。

create table employee(
num int primary key auto_increment,
name varchar(20) not null,
addr varchar(30) not null,
zip varchar(50) not null,
tel varchar(50) not null,
email varchar(20),
depno int not null,
birth date not null,
sex set('男','女') not null

)auto_increment=001;
insert into employee(name,addr,zip,tel,email,depno,birth,sex)
values('王林','武汉大学','430074','87598405',null,2,'1985-2-1','男'),
			('王芳','华中科大','430073','62534231',null,1,'1966-3-28','男'),
			('张晓','武汉理工大','430072','87596985',null,1,'1972-12-9','男'),
			('王小燕','武汉交大',' 430071','85743261','[email protected]',1,'1950-7-30','女'),
			('李华','华中农大','430070','87569865',null,5,'1962-10-18','男'),
			('李明','华中师大','430075','85362143',' [email protected]',5,'1955-09-28','男'),
			('田丽','中商财大','430076','87596985','[email protected]',3,'1968-08-10','女'),
			('吴天','武汉电力','430077','36985612',' [email protected]',5,'1964-10-01','男'),
			('刘备','武汉邮科院','430078','69865231',null,3,'1967-04-02','男'),
			('赵云','学府家园','430071','68592312',null,4,'1968-11-18','男'),
			('貂蝉','湖北工大','430074','65987654',null,4,'1959-09-03','女');


create table salary(
 Num int PRIMARY KEY auto_increment,
 InCome DECIMAL(6,2),
 OutCome DECIMAL(5,2)
)auto_increment=001;

INSERT into salary 
VALUES(0,2100.8,123.09),
      (0,1582.62,88.03),
      (0,2569.88,185.65),
      (0,1987.01,79.58),
      (0,2066.15,108.0),
      (0,2980.7,210.2),
      (0,3259.98,281.52),
      (0,2860.0,198),
      (0,2347.68,180),
      (0,2531.98,199.08),
      (0,2240.0,121.0);

create table Department(
	Depno int primary key auto_increment,
	DepName varchar(20),
	Remark varchar(20)
);

insert into Department values(0,'财务部',null),
														 (0,'人事资源部',null),
														 (0,'经理办公室',null),
														 (0,'研发部',null),
														 (0,'市场部',null);


ALTER table Employee add CONSTRAINT fk_Department_employee FOREIGN KEY (Depno) REFERENCES Department(Depno);
ALTER table Employee add CONSTRAINT fk_salary_employee FOREIGN KEY (Num) REFERENCES salary(Num);

-- 查询每个雇员的所有记录
SELECT * FROM Employee;

-- 查询前5个会员的所有记录
SELECT * FROM Employee LIMIT 0,5;

-- 查询每个雇员的地址和电话
SELECT Addr,Tel FROM Employee;

-- 查询num为001的雇员地址和电话
SELECT Addr,Tel FROM Employee WHERE num=1;

-- 查询表Employee
SELECT Name,InCome as '实际工资' FROM salary s,Employee e WHERE s.num=e.num;

-- 查询女雇员的地址和电话
SELECT Addr as '地址',Tel as '电话' FROM Employee where sex='女';

-- 计算每个雇员的实际收入
SELECT Name,InCome-OutCome as '实际收入' FROM salary s,Employee e WHERE s.num=e.num;

-- 找出所有姓王的雇员的部门号
SELECT e.`name`,d.Depno from Employee e,Department d WHERE e.depno=d.Depno and e.name like '王%';  

-- 找出比所有财务部雇员收入都高的雇员姓名
SELECT DISTINCT Name FROM Employee e,salary s WHERE e.num=s.Num AND s.InCome > ALL(SELECT InCome FROM Employee e,Department d,salary s WHERE s.num=e.num and d.Depno=e.depno and DepName='财务部');
-- 找出所有收入在2000-3000之间雇员的编号
SELECT Num FROM employee,salary where InCome BETWEEN 2000 AND 3000;

-- 练习2
-- 查找在财务部工作的雇员的情况
SELECT * FROM Employee e,department d WHERE e.depno=d.Depno;
-- 查找在财务部且年龄不低于研发部任一雇员年龄的雇员的姓名
SELECT DISTINCT Name FROM Employee e,Department d where e.Depno=1 and e.birth < ALL(SELECT birth FROM Employee e,Department d WHERE e.depno=d.Depno and DepName='研发部');
-- 查找比所有财务收入都高的雇员姓名
SELECT DISTINCT Name FROM Employee e,salary s WHERE s.num=e.num and s.InCome > ALL(SELECT income FROM Employee e,Department d,salary s WHERE s.num=e.num and d.Depno=e.depno and DepName='财务部');

-- 练习3
-- 查找每个雇员的情况和薪水情况
SELECT *,income from employee e,salary s WHERE e.num=s.Num;

-- 查找财务部收入在2200元以上的雇员姓名及其薪水详细情况
SELECT name,income,outcome from employee e ,salary s,department d WHERE e.num=s.Num AND d.Depno=e.depno and d.DepName='财务部' AND InCome>2200;


-- 练习4
-- 求财务部雇员的平均实际收入
SELECT AVG(income-come) as '财务部实际收入' from salary s,employee e,department d where s.num=e.num and e.depno=d.Depno and d.DepName='财务部'; 

-- 求财务部雇员总人数
SELECT COUNT(*) FROM employee e,department d WHERE e.depno=d.Depno AND d.DepName='财务部';

-- 练习5
-- 求各部门的雇员数
SELECT count(e.depno),e.depno,d.DepName from department d,employee e WHERE d.Depno=e.depno GROUP BY e.depno;

-- 求部门的平均薪水大于2500的部门信息
SELECT  d.DepName,d.Depno,AVG(s.income) from salary s,employee e,department d where s.num=e.num and e.depno=d.Depno GROUP BY e.depno HAVING AVG(s.income)>2500; 


select * from Department;
select * from salary;

增删改数据的语法

语法:
  插入
-- INSERT INTO 表名(列名...) VALUES (值...);
--   注意:没有指定列名,默认插入全部列的值
--         指定的列的个数和值的个数要一致,顺序也要一致,数据类型也要匹配

  修改
-- UPDATE 表名 SET 列名1=新值,列名2=新值...[WHERE 条件];
--   注意:若没有where子句,则代表修改全部
--         有where子句代表修改满足条件的记录
  
  删除
-- DELETE FROM 表名 [WHERE 条件];
--   注意:drop DELETE 表名;删除表
--         TRUNCATE TABLE 表名;清空表中的数据,快速删除一张表,然后创建这张表
--         DELETE FROM 表名;删除表中的记录

单表查询的语法

语法:
  SELECT DISTINCT *|字段列表
  FROM 表名
  [WHERE 过滤条件]
  [GROUP BY 分组字段1,分组字段2...]
  [HAVING 分组后的过滤条件]
  [ORDER BY 排序字段1 asc|DESC,排序字段2 ASC|DESC]
  [LIMIT m,n]

sql语句的执行顺序:1.from 2. where 3.group by 4. select 5.order by 6.limit


-- 单表查询
-- ---单列查询
SELECT sname from student;

-- ---多列查询
SELECT sname,sage FROM student;

-- ---查询所有
SELECT * from student;
SELECT sno,sname,ssex,sage,sdept FROM student;

SELECT studnet.sno from student;
SELECT s.sno FROM student as s;-- 给表取一个别名 s

-- 排序 ORDER BY 列名1 ASC|DESC,列名2 ASC|DESC,...
-- ---默认是asc
SELECT * FROM student ORDER BY sage DESC,sno [ASC]; 

-- 过滤条件(where);
-- ---=  !=  <> >  <  >=  <=  BETWEEN 值 and 值
-- ---AND OR in NOT
-- --- is NULL
-- --- is not null

-- 模糊查询  LIKE

-- 分组  GROUP BY 列名1,列名2,列名...

-- 分页  limit m,n;   n表示pageSize,代表每页显示的个数
--                    m表示pageSize*(pageNum-1) 是当前页的前面的所有记录个数

-- DISTINCT 去重

多表查询的语法

-- 1.笛卡尔积 select * from 表1,表2;

    select * from department; -- 4条记录
    select * from employee; -- 14条记录
    select * from employee,department;  -- 56条记录

-- 2. 等值连接 (通过两张表之间的外键关键起来)
   select * from employee a ,department b where a.department_id=b.id;

-- 3. 内连接 表1 inner join  表2  on  关联条件
   select * from employee a inner join department b  on a.department_id=b.id;

-- 4. 外连接 (需要分清楚左右表)
    -- 左外连接  left [outer] join   左表全部数据 + 满足条件的数据
    select * from 左表 left join 右表  on 条件;

    -- 右外连接  right [outer] join   满足条件的数据+ 右表所有的数据

     -- 示例: 求出每个部门下的员工人数,若没有员工显示0
     --        左连接,并且左表 department表
     
   select a.id,count(b.id) from department a left join employee b 
   on a.id=b.department_id
   group by a.id 

-- 5 嵌套查询
     create table tb1(num1 int not null);
     create table tb2(num2 int not null);
     insert into tb1(num1) values(1),(5),(13),(27);
     insert into tb2(num2) values(6),(14),(11),(20);
     select * from tb1; select * from tb2;

    -- num1 只要比tb2中某一个值大就返回true,就可以查出来
    select num1 from tb1  where num1 > any( select num2 from tb2);

    select num1 from tb1 where num1 > (select min(num2) from tb2);

    -- num1需要比tb2中所有值都大,才可以查出来
    select num1 from tb1  where num1 > all( select num2 from tb2);

    
    select num1 from tb1 where num1 > (select max(num2) from tb2);


-- 6 联合查询 并集 union 和 union all  区别:是否合并重复的记录

   select name,salary from employee where salary>3000  -- 1  KING 5000
   union all
   select name,salary from employee where department_id in(1,2); --8

函数、索引、视图、用户和事务(day three)

话不多说,直接放命令。

自连接:自己连接自己。

-- 力扣 181. 超过经理收入的员工

-- 一张表自己连接自己查询: 自连接

-- select * from department;
select * from employee;

-- 超过经理收入的员工
-- 提示: 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,
--       此外还有一列对应员工的经理的 manager_id。

-- 编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名
  explain
  select 员工.name
  from employee 员工,employee 经理
  where 员工.manager_id=经理.id  and 员工.salary > 经理.salary;

数据库中的常用函数

   -- <1>数学函数
   select 10/3; -- 不是整除3.3333
   select 10 div 3;  -- 整除
   select mod(-10,-3); -- 求余数
   select rand(); -- 随机数 [0,1) 之间的随机数
   select pow(2,3); -- 求x的y次方 
   select sqrt(4); -- 平方根,若负数返回NULL
   select floor(-1.2); -- 返回小于等于参数的最大整数
   select round(12345.6789); -- 返回整数12346
   select round(12345.6789,2);-- 12345.68  2小数点保留2位有效数字
   select truncate(3.1495926,2); -- 小数点后保留2(直接截取不四舍五入)
   select truncate(12345.6789,-3); -- 12000
   select sign(10),sign(-10),sign(0);  -- 正数 1  负数 -1 零 0

   -- <2>字符串函数
   select * from employee1 where char_length(name)=2;

   select concat(name,sex) from employee1;
   select concat_ws('^_^',name,sex) from employee1;

   select ascii('A'); -- 65
   select bin(8); -- 10进制数转2进制数 1000
   select hex(28); -- 10进制数转16进制数 1C
   select bit_length('张'); 
   select char(65); -- A
   select char_length('秋分'),length('秋分');
   -- 字符个数  字节个数 utf8 一个汉字占3个字节
   select concat('a','b');  -- ab 将子字符串连接
   select concat_ws('--','a','b');  -- a--b
   select find_in_set('x', 'a,b,c,d,x,y,z');
   select instr('coaoaohelloao','ao'); -- 返回'ao' 第1次出现的位置 indexOf
   select upper('abc');
   
    -- 查询所有学生的姓
   select name,substr( name from 1  for 1) from employee;
   select name,SUBSTRING(name,1,2) from employee; -- 从1开始截取,截取2个字符
   select left(name,1) from employee;
   select REPEAT('我喜欢学习',2);


   -- <3>获取当前系统时间
   select now(),sysdate(),current_date(),current_timestamp();
   select curdate(),curtime();
   -- 获取今天星期几
   select weekday('2020-08-12'); -- 0 星期一 1 星期二
    -- 获取now的月份
    select month(now()),monthname(now());
    -- 获取日期
    select dayofmonth(now());
    -- 获取季度
    select quarter(now());
    -- 获取年
    select year(now());
    -- 日期格式化
    select date_format(now(),'%Y年%m月%d日');

    select * from employee where year(hire_date)=1981;
    select * from employee where month(hire_date)=2;
  

-- <4> 加密函数和解密函数
     select password(123456);  -- *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9
     -- password是不可以解密

    select encode('12345','加密规则');

    select decode(encode('12345','加密规则'),'加密规则');


-- <5>系统函数
-- 流程控制的函数
-- 1> if(expr1,expr2,expr3)  
-- 第1个表达式为true则输出第2个表达式,否则输出第3个表达式

-- 高考成绩>=600分,则输出优秀,否则输出hehe

   select  if(sscore>=600,'优秀','hehe')  from t_student;


-- 2> ifnull(expr1,expr2) 如果expr1为null,则返回第2个表达式

-- 3> case when then  end 类似于java的switch
   case 值 
		 when  条件1  then  输出结果1
		 when  条件2  then  输出结果2
   else
       输出结果
   end

索引

 什么是索引?

索引是一个单独的、存储在磁盘上的数据库结构,他们包含着对数据库表里面所有记录的引用指针。对相关列使用索引是提高查询操作速度的最佳途径。

可以得到索引的本质:索引是数据结构, 索引的目的是提高查询效率。

 如果没有索引,查询需要从第1条记录去遍历的查找,直到找到我们需要的,一个一个找和直接根据索引定位到数据有差距。

如何创建索引?

索引分类
    - 单值索引:即一个索引只包含单个列,一个表可以有多个单列索引
    - 唯一索引:索引列的值必须唯一,但允许有空值
    - 复合索引:即一个索引包含多个列
    创建索引的语法?
    方式一:create [unique] index indexName on tableName (columnName (length) )
    --   如果是CHAR,VARCHAR类型,length可以小于字段实际长度;
    --   如果是BLOB和TEXT类型,必须指定length。
    方式二:alter table  tableName add [unique] index [indexName] (columnName (length) )

    -- 示例:为tb_demo1表 id 创建一个索引
      create unique index uk_id on tb_demo1(id);

 

如何删除索引?

删除:DROP INDEX [indexName] ON mytable;

查看索引?

SHOW INDEX FROM table_name;

 -- 示例:

SHOW INDEX FROM tb_demo1;


什么情况下需要建立索引?

哪些情况需要建索引

     - 主键自动建立唯一索引
      alter table 表名 add primary key(列名1,...); 

     - 频繁作为查询的条件的字段应该创建索引

     - 查询中与其他表关联的字段,外键关系建立索引

     - 频繁更新的字段不适合创建索引:因为每次更新不单单是更新了记录还会更新索引,加重IO负担

     - Where条件里用不到的字段不创建索引

     - 单列/组合索引的选择问题(在高并发下倾向创建组合索引)

     - 查询中排序的字段,若通过索引去访问将大大提高排序的速度

     - 查询中统计或者分组字段

哪些不适合建索引

    - 表记录太少
    - 经常增删改的表
    - 数据重复且分布平均的表字段,因此应该只为经常查询和经常排序的数据列建立索引。
    - 注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。
 

-- 创建一张表
create table tb_demo1(
  id int,
  name varchar(100)
);

-- 创建一个存储过程
-- 类似于java中方法
create procedure proc_01() -- public void proc_01()
begin  -- {
  declare i int default 1; -- int i=1;
  my_loop:loop   -- while(true){       
  if i<=100000 then   
    insert into tb_demo1(id,name) values(i,concat('名字',i));
  else 
    leave my_loop;  -- break;
  end if;
  set i=i+1; -- i++;
  end loop my_loop; -- }
end; -- }
    
call proc_01();

视图

 

 1》视图的概念
   从一张或者多张表中查询出来的结果,是一张虚拟的表。
	 它没有真实的数据,数据来源于原表,就是SQL语句的结果集。
	 你可以像操作表一样去操作视图。
-- 因为视图没有数据,数据存储在原表中
-- 当对视图进行修改,删除时,相应的原表也会发生改变。若原表的数据发生改变
-- 视图中的数据也会发生改变。

 2》视图的作用
  1、简单化,直接查询视图就是你想要的结果,不用写复杂的sql了
   那些被经常用于查询的复杂的sql语句可以定义成视图。
    -- 查询每个部门的员工人数
     create or replace  view v_dept_num as
			 select a.id 部门编号,count(b.id) 部门人数
			 from department a left join employee b  
			 on a.id=b.department_id
			 group by a.id;

   -- 有了视图
    select * from v_dept_num;
  2、 安全性
    不允许用户访问表,因为表中有敏感的数据
    例如: 一个员工表,一般用户只能看到每个员工工号和姓名,工资和年龄等看不到
          其实一般的用户看到的只是这个表的视图
      select no,name,salary,age from emp;
      create or replace view v_emp  as  select no,name from emp;
      
  3、屏蔽真实表结构变化带来的影响
  4、实现了逻辑数据独立性


3》 如何查看视图?
   desc 视图名称;
   desc v_dept_num;

   show create view 视图名称;
   show create view v_dept_num;

   SHOW TABLE STATUS LIKE '视图名'
   show table status like 'v_dept_num';

4》视图的更新操作不能被执行的情况,具体如下:
	1)视图中不包含基本表中被定义为非空的列
	2)在定义视图的SELECT语句后的字段列表中使用了数学表达式
	3)在定义视图的SELECT语句后的字段列表中使用聚合函数
	4)在定义视图的SELECT语句中使用了DISTINCT,UNION,GROUP BY或HAVING子句

 -- 对视图进行修改update操作
 -- 例如这个操作就会跟新失败 update v_dept_num set 部门人数=100 where 部门编号=4;


5》 删除视图
    drop view if exists 视图名称;


6》 视图和表的区别
 1  视图虚拟表   表是基本表
 2  视图是已经编译好的sql语句,是基于sql语句的结果集的可视化的表
    而表不是,表就是存储真实数据的表
 3 视图没有实际的物理记录,表有
 4 表中是有内容, 视图没有只是一个窗口
 5 表占物理空间,视图不占物理空间
 6 视图是查看表的一种方式,只是一个sql语句的集合,从安全角度
   防止用户接触真实的表。
 7 视图的创建和销毁不会影响原表,但是修改视图中的数据会影响原表
   同理修改表的数据也会影响视图。

用户新建删除和权限赋予移除

1》 mysql的用户分为 root用户和普通用户

2》 如何创建新用户

    create user '用户名'@'ip地址' identified by '密码';
   
   -- create user 'qiufen'@'localhost' identified by '123456';

3》 如何删除用户 (不要删除root账户)

    drop user '用户名'@'ip地址';


4》新创建的用户没有任何权限?
   学习如何授予权限 和 回收权限

   
   -- grant 权限名称 on  数据库名.* to '用户名'@'localhost';
   -- revoke 权限名称 on 数据库名.* from '用户名'@'localhost';
    
   示例1:授予秋分访问j2005_db数据库的权限
          grant all on j2005_db.* to  'qiufen'@'localhost';

   示例2:把访问j2005_db的权限收回
          revoke all on j2005_db.* from 'qiufen'@'localhost';

5》 查看某个用户的权限

     使用SHOW GRANTS语句查询权限信息的基本语法结构如下:
     SHOW GRANTS FOR 'qiufen'@'localhost';

6》 如果忘记密码了怎么办?
     解决root用户密码丢失的步骤如下:
		1)停止MySQL服务器
		2)cmd,先将目录切换到mysql安装目录的bin目录,mysqld --skip-grant-tables启动MySQL服务,不要关闭这个窗口
		3)再打开一个新的cmd窗口,切换到bin目录,mysql -u root命令重新登录
		4)通过UPDATE重新设置密码:UPDATE mysql.user SET Password
		=PASSWORD('xxgc') WHERE User='root' AND Host='localhost';
		5)FLUSH PRIVILEGES;重新加载权限表

事务

-- 事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务
-- 事务四个特性:
		- 原子性(A):事务是最小单位,不可再分
		- 一致性(C):事务要求所有的DML语句操作的时候,必须保证同时成功或者同时失败
		- 隔离性(I):事务A和事务B之间具有隔离性
		- 持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)
-- 事务操作: transaction
    -  开启事务 start
    -  结束事务 end
    -  提交事务 commit
    -  回滚事务 rollback
-- 事务的隔离级别:
    -  读取未提交 (脏数据)
    -  读取已提交 (不能重复)
    -  可重复读   (幻读)-- mysql默认这个
    -  串行化     一个事务在操作数据库时,另一个事务等待

-- 示例:银行转账就是一个事务
-- actno       balance
-- 1           500
-- 2           100

create table tb_account(
  actno int primary key auto_increment,
  balance decimal(10,2)
);

insert into tb_account(balance) values(500),(100);

select * from tb_account;

-- 事务只和一些DML(insert,update,delete)语句相关
-- 转账这个业务就是一个事务
 -- 例如1号账户给2号账户转100元

update tb_account set balance=balance-100 where actno=1; 
update tb_account set balance=balance+100 where actno=2;  

-- 手动开启事务 (转账成功案例)
start transaction; -- 手动开启事务
update tb_account set balance=balance-100 where actno=1; 
update tb_account set balance=balance+100 where actno=2; 
commit; -- 提交事务,同步到数据文件中

select * from tb_account;

-- 手动开启事务 (转账失败案例)
start transaction; -- 手动开启事务
update tb_account set balance=balance-100 where actno=1; 
update tb_account set balance=balance+100 where actno=2; 
rollback; -- 事务回滚

select * from tb_account;

-- 设置事务的隔离级别
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
    SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

    global 全局   session 会话


  SELECT @@tx_isolation; -- 查看事务的隔离级别

  SELECT @@autocommit; -- mysql会自动提交事务
  -- 如果需要手动提交事务
  set autocommit=1;

事务示例

drop table info;
create table info(id int,msg varchar(20),t datetime);


-- 按照下面步骤来操作一下,加深下理解:
-- 先清除一下表,记得用测试表
truncate table  info;
-- 查询一下,这里表应该是空的了
select * from info;
-- 开启一个事务,正式我们的测试
start transaction;
-- 插入一条数据 “s1 before”
insert into info values(1,"s1 before",now());
-- 创建一个保留点
savepoint s1;
-- 再插入一条数据 “s1 after”
insert into info values(1,"s1 after",now());
-- 查询数据,发现2条 s1 before 和 s1 after
select * from info;
-- 回到保存点
rollback to s1;
-- 查询数据,发现1条 s1 before
select * from info;
-- 回到开启事务的位置,全部撤销
rollback;

--  讲解的是 mysql数据库默认提交事务 ,关闭mysql的默认提交  set autocommit=0;

-- 没有关闭自动提交事务之前
-- 再插入一条数据
insert into info values(1,"no transaction",now());
-- 再另外一个客户端直接查询,立马看到上面插入的数据 “no transaction”,也是验证了事务确实结束了
select * from info;


-- 上面我们插入数据,另外一个客户端立马就查询到了,
-- 说明是自动提交了我们的插入,现在我们设置不自动提交。
set autocommit=0;
-- 插入一条数据 “autocommit=0”
insert into info values(1,"autocommit=0",now());
-- 在另外一个客户端查询,你会发现,上面这条 "autocommit=0" 数据并没有插入
select * from info;
-- 提交,这个时候你再去另外一个客户端查询,才能查到你提交的数据 "autocommit=0"
commit;

 

你可能感兴趣的:(数据库,mysql,java)