百木园-与人分享,
就是让自己快乐。

MySQL学习笔记-day03

1、约束

1.1、唯一性约束(unique)

唯一性约束修饰的字段具有唯一性,不能重复。但可以为NULL。

案例:给某一列添加unique
drop table if exists t_user;
create table t_user(
    id int,
    username varchar(255) unique
);
insert into t_user values(1,\'zhangsan\');
insert into t_user values(2,\'zhangsan\');
# 错误:ERROR 1062 (23000): Duplicate entry \'zhangsan\' for key \'username\'
insert into t_user(id) values(2);
insert into t_user(id) values(3);
insert into t_user(id) values(4);
案例:给两个列或者多个列添加unique
表集约束--联合起来具有唯一性
drop table if exists t_user;
create table t_user(
    id int,
    usercode varchar(255),
    username varchar(255),
    unique(usercode,username) //多个字段联合添加约束
);
insert into t_user values(1,\'111\',\'zs\');
insert into t_user values(2,\'111\',\'ls\');
insert into t_user values(3,\'222\',\'zs\');
select * from t_user;
	+------+----------+----------+
	| id   | usercode | username |
	+------+----------+----------+
	|    1 | 111      | zs       |
	|    2 | 111      | ls       |
	|    3 | 222      | zs       |
	+------+----------+----------+
insert into t_user values(4,\'111\',\'zs\');
# 错误:ERROR 1062 (23000): Duplicate entry \'111-zs\' for key \'usercode\'
列集约束--单个列具有唯一性
drop table if exists t_user;
create table t_user(
    id int,
    usercode varchar(255) unique,
    username varchar(255) unique
);
insert into t_user values(1,\'111\',\'zs\');
insert into t_user values(2,\'111\',\'ls\');
# 错误:ERROR 1062 (23000): Duplicate entry \'111\' for key \'usercode\'
select * from t_user;
	 +------+----------+----------+
	 | id   | usercode | username |
	 +------+----------+----------+
	 |    1 | 111      | zs       |
	 +------+----------+----------+
# 注意:not null只有列级约束,没有表集约束。

1.2、主键约束

怎么给一张表添加主键约束?
drop table if exists t_user;
create table t_user(
    id int primary key, # 列级约束
    username varchar(255),
    email varchar(255)
);
insert into t_user(id,username,email) values(2,\'ls\',\'ls@123.com\');
insert into t_user(id,username,email) values(3,\'ww\',\'ww@123.com\');
select * from t_user;
    +----+----------+------------+
	| id | username | email      |
	+----+----------+------------+
	|  1 | zs       | zs@123.com |
	|  2 | ls       | ls@123.com |
	|  3 | ww       | ww@123.com |
	+----+----------+------------+
# 不能重复
insert into t_user(id,username,email) values(1,\'jack\',\'jack@123.com\');
# 错误:ERROR 1062 (23000): Duplicate entry \'1\' for key \'PRIMARY\'

# 不能为空
insert into t_user(username,email) values(\'jack\',\'jack@123.com\');
# 错误:ERROR 1364 (HY000): Field \'id\' doesn\'t have a default value

根据以上的测试得出:id是主键,因为添加了主键约束,主键字段中的数据不能为NULL,也不能重复。

主键的特点:不能为NULL,也不能重复。

主键相关的术语

主键约束:primary key

主键字段:id字段添加primary key之后,id叫做主键字段。

主键值:id字段中的每一个值都是主键值。

主键有什么用?
  • 表的设计三范式中有要求,第一范式就要求任何一张表都应该有主键。
  • 主键的作用:主键值就是这行记录在这张表当中的唯一标识。(就像一个人的身份证)
主键的分类?

根据主键字段的字段数量来划分:

单一主键(建议的,常用的。)

复合主键(多个字段联合起来添加一个主键约束。不建议使用)

根据主键性质来划分:

自然主键:主键值最好就是一个和业务没有任何关系的自然数。(这种方法是推荐的。)
业务主键:主键值和系统的业务挂钩,例如:拿着银行卡的卡号做主键,拿着身份证号码作为主键。(不推荐使用)
最好不要拿着和业务挂钩的字段作为主键。因为以后的业务一旦发生改变的时候,主键值可能也需要随着发生变化,但有的时候没有办法变化,因为变化可能导致主键值重复。

一张表的主键约束只能有一个

使用表集约束定义主键
drop table if exists t_user;
create table t_user(
    id int, 
    username varchar(255),
    primary key(id)
);	
insert into t_user(id,username) values(1,\'zs\');
insert into t_user(id,username) values(2,\'ls\');
insert into t_user(id,username) values(3,\'ws\');
insert into t_user(id,username) values(4,\'cs\');
select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	|  2 | ls       |
	|  3 | ws       |
	|  4 | cs       |
	+----+----------+
mysql主键值自增 auto_increment(非常重要)
drop table if exists t_user;
create table t_user(
    id int primary key auto_increment,	//id字段自动维护一个自增数字,从1开始,以1递增。
    username varchar(255)
);
insert into t_user(username) values(\'a\');
insert into t_user(username) values(\'b\');
insert into t_user(username) values(\'c\');
insert into t_user(username) values(\'d\');
insert into t_user(username) values(\'e\');
insert into t_user(username) values(\'f\');
select * from t_user;
    +----+----------+
	| id | username |
	+----+----------+
	|  1 | a        |
	|  2 | b        |
	|  3 | c        |
	|  4 | d        |
	|  5 | e        |
	|  6 | f        |
	+----+----------+

提示:Oracle当中也提供了一个自增机制,叫做:序列(sequence)对象。

1.3、外键约束

关于外键约束的相关术语

外键约束:foreign key

外键字段:添加有外键约束的字段

外键值:外键字段中的每一个值

业务背景:请设计数据库表,用来维护学生和班级的信息

第一种方案:一张表存储所有数据

缺点:冗余。【不推荐】学生属于同一班级,则他们的班级编号和班级名称都是相同的。要修改一个班,就需要修改很多行。

第二种方案:两种表(学生表和班级表) 每一种数据,使用一个表来存储。

t_class 班级表————父表

cno(pk)		cname
-----------------------------
101			高三1班
102			高三2班
....

t_student 学生表————子表

sno(pk)		sname		classno(fk:该字段添加外键约束)
------------------------------------------------------------------
1			zhangsan	101
2			lisi		101
3			wangwu		101
4			zhaoliu		102
5			tangqi		102

将以上表的建表语句写出:
t_student 学生表中的classno字段引用t_class 班级表中的cno字段,此时t_student表叫做子表。t_class表叫做父表。

顺序要求:
删除数据的时候,先删除子表,再删除父表。
添加数据的时候,先添加父表,再添加子表。
创建表的时候,先创建父表,再创建子表。
删除表的时候,先删除子表,再删除父表。

drop table if exists t_student;
drop table if exists t_class;
create table t_class(
    cno int,
    cname varchar(255),
    primary key(cno)
);
create table t_student(
    sno int,
    sname varchar(255),
    classno int,
    primary key(sno),
    foreign key(classno) references t_class(cno)
);

insert into t_class values(101,\'xxx\');
insert into t_class values(102,\'yyy\');

insert into t_student values(1,\'zs\',101);
insert into t_student values(2,\'ls\',101);
insert into t_student values(3,\'wu\',102);
insert into t_student values(4,\'zl\',102);
insert into t_student values(5,\'tq\',102);

select * from t_class;
select * from t_student;

insert into t_student values(6,\'zh\',103);
# 错误:ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`bjpowernode`.`t_student`,CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))
外键值可以为NULL吗?

外键值可以为NULL。

insert into t_student(sno,sname) values(6,\'sl\');
select * from t_student;
	+------+-------+---------+
	| sno  | sname | classno |
	+------+-------+---------+
	|    1 | zs    |     101 |
	|    2 | ls    |     101 |
	|    3 | wu    |     102 |
	|    4 | zl    |     102 |
	|    5 | tq    |     102 |
	|    6 | sl    |    NULL |
	+------+-------+---------+
外键字段引用其他表的某个字段的时候,被引用的字段必须是主键吗?

不是。不一定是主键,但必须有唯一性。

2、存储引擎(了解) 描述表的存储方式

mysql默认使用的存储引擎是InnoDB方式。默认采用的字符集是UTF-8。

2.1、存储引擎的使用

  • 数据库中的各表均被(在创建表时)指定的存储引擎来处理。
  • 服务器可用的引擎依赖以下因素:
    • MySQL的版本
    • 服务器在开发时如何被配置
    • 启动选项:为了解当前服务器中有哪些存储引擎可用,可使用SHOW ENGINES语句;(末尾加“\\G”可以让结果显示更加易读)

2.2、什么叫存储引擎?

存储引擎这个名字只有在mysql中存在。(Oracle中有对应的机制,但不叫存储引擎。Oracle中没有特殊的名字,就是“表的存储方式”。)

mysql支持很多存储引擎,每一种存储引擎都对应了一种不同的存储方式。

2.3、查看当前mysql支持的存储引擎?

show engines \\G;

2.4、常用的存储引擎?

MyISAM存储引擎是MySQL最常用的引擎,但是这种引擎不是默认的。
Engine: MyISAM
	     Support: YES
	     Comment: MyISAM storage engine
	Transactions: NO	// 不支持事务
		  XA: NO
	  Savepoints: NO

MyISAM这种存储引擎不支持事务。

它管理的表具有以下特征:

  • 使用三个文件表示每个表:

    • 格式文件 —— 存储表结构的定义(mytable.frm)
    • 数据文件 —— 存储表行的内容(mytable.MYD)
    • 索引文件 —— 存储表上索引(mytable.MYI)
  • 灵活的ATUO_INCREMENT字段处理。

  • 可被转换成压缩、只读表来节省空间。

优点:可被压缩,节省存储空间。并且可以转换成只读表,提高检索效率。

缺点:不支持事务。


InnoDB存储引擎是MySQL的缺省引擎。
Engine: InnoDB
	     Support: DEFAULT
	     Comment: Supports transactions, row-level locking, and foreign keys
	Transactions: YES
		  XA: YES   //支持事务
	  Savepoints: YES

它管理的表具有下列主要特征:

  • 每个InnoDB表在数据库目录中以.frm格式文件表示
  • InnoDB表空间tablespace被用于存储表的内容(tablespace只是一个逻辑概念)
  • 提供一组用来记录事务性活动的日志文件
  • COMMIT(提交)SAVEPOINTROLLBACK(回滚)支持事务处理
  • 提供全ACID兼容,ACID事务具有的四个特征
  • 在MySQL服务器崩溃后提供自动恢复机制
  • 多版本(MVCC)和行级锁定
  • 支持外键及引用的完整性,包括级联删除和更新

表的结构存储在xxx.frm文件中

数据存储在tablespace这样的表空间中

优点:支持事务、行级锁、外键等。这种存储引擎数据的安全得到保障。

缺点:(数据存储在tablespace这样的表空间中)无法被压缩,无法转换成只读。


MEMORY存储引擎
Engine: MEMORY 
	     Support: YES
	     Comment: Hash based, stored in memory, useful for temporary tables
	Transactions: NO
		  XA: NO //不支持事务
	  Savepoints: NO

MEMORY存储引擎管理的表具有下列特征:

  • 在数据库目录内,每个表均以.frm格式的文件表示。
  • 表数据及索引被存储在内存当中。
  • 表级锁机制。
  • 不能包含TEXT或者BLOB字段。

使用MEMORY存储引擎的表,其数据存储在内存中,且行的长度固定,这两个特点使得MEMORY存储引擎非常快。

优点:查询速度最快。

缺点:不支持事务。数据容易丢失。因为所有数据和索引都是存储在内存当中的,断电就没。以前叫做HEPA引擎。

2.5、每一个存储引擎都有自己的优缺点,需要在合适的时机选择合适的存储引擎。

  • MyISAM表最合适于大量的数据读而少量数据更新的混合操作。MyISAM表的另一种适用场景是使用压缩的只读表。
  • 如果查询中包含较多的数据更新,应使用InnoDB。其行级锁机制和多版本的支持为数据读取和更新的混合操作提供了良好的并发机制。
  • 可使用MEMORY存储引擎来存储非永久需要的数据,或者是能够从基于磁盘的表中重新生成的数据。

3、事务(Transaction)

3.1、什么是事务?

一个事务是一个完整的业务逻辑单元,不可再分。

比如:银行账户转账,从A账户向B账户转账10000。需要执行两条update语句:

update t_act set balance = blance - 10000 where actno = \'act-001\';
update t_act set balance = blance + 10000 where actno = \'act-002\';

以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。

要想保证以上两条DML语句同时成功,或者同时失败,那么就需要使用数据库的“事务机制”。

3.2、和事务相关的语句只有:DML语句。(insert delete update)

为什么?

因为它们这三个语句都是和数据库表当中的“数据”相关的。

事务的存在是为了保证数据的完整性、安全性。

3.3、假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗?

所有的业务都能使用1条DML语句搞定就不需要事务了。但实际情况不是这样的,通常一个“事儿(事务【业务】)”需要多条DML语句共同联合完成。

3.4、事务的四大特性

事务包括四大特性:ACID

A:原子性:事务是最小的工作单元,不可再分。
C:一致性:事务必须保证多条DML语句同时成功或者同时失败。
I:隔离性:事务A和事务B之间具有隔离。
D:持久性:持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。

3.5、关于事务之间的隔离性(4个级别) 一般不会使用 Serializable 和Read uncommitted 这两种隔离级别

隔离性是指,多个用户的并发事务访问同一个数据库时,一个用户的事务不应该被其他用户的事务干扰,多个并发事务之间要相互隔离。

事务隔离性存在隔离级别,理论上隔离级别包括4个:

第一级别:读未提交(read uncommitted)

对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。

这种隔离级别解决了脏读现象。

第二级别:读已提交(read committed)

对方事务提交之后的数据我方可以读取到。

读已提交存在的问题是:不可重复读。

第三级别:可重复读(repeatable read)

这种隔离级别解决了:不可重复读问题。

可重复读存在的问题:读取到的数据是幻象。

第四级别:序列化/串行化

解决了所有问题。

效率低。需要事务排队。一致性最好的,性能最差的。

Oracle数据库默认的隔离级别是:读已提交。

mysql数据库默认的隔离级别是:可重复读。

3.6、演示事务

mysql事务默认情况下是自动提交的。(什么是自动提交?只要执行任意一条DML语句,则提交一次。)

怎么关闭自动提交? ———— start transaction;

准备表
drop table if exists t_user;
create table t_user(
    id int primary key auto_increment,
    username varchar(255)
);
演示
insert into t_user(username) values(\'zs\');

select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	+----+----------+
	
rollback;

select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	+----+----------+

演示:使用start transaction;关闭自动提交机制。

start transaction;

insert into t_user(username) values(\'lisi\');

select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	|  2 | lisi     |
	+----+----------+
	
insert into t_user(username) values(\'wangwu\');

select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	|  2 | lisi     |
	|  3 | wangwu   |
	+----+----------+
	
rollback;

select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	+----+----------+

mysql> start transaction;
	Query OK, 0 rows affected (0.00 sec)

	mysql> insert into t_user(username) values(\'wangwu\');
	Query OK, 1 row affected (0.00 sec)

	mysql> insert into t_user(username) values(\'rose\');
	Query OK, 1 row affected (0.00 sec)

	mysql> insert into t_user(username) values(\'jack\');
	Query OK, 1 row affected (0.00 sec)

	mysql> select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	|  4 | wangwu   |
	|  5 | rose     |
	|  6 | jack     |
	+----+----------+
	4 rows in set (0.00 sec)

	mysql> commit;
	Query OK, 0 rows affected (0.00 sec)

	mysql> select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	|  4 | wangwu   |
	|  5 | rose     |
	|  6 | jack     |
	+----+----------+
	4 rows in set (0.00 sec)

	mysql> rollback;
	Query OK, 0 rows affected (0.00 sec)

	mysql> select * from t_user;
	+----+----------+
	| id | username |
	+----+----------+
	|  1 | zs       |
	|  4 | wangwu   |
	|  5 | rose     |
	|  6 | jack     |
	+----+----------+
	4 rows in set (0.00 sec)

3.7、使用两个事务演示以上的隔离级别

第一:演示第一级别:读未提交read uncommitted

设置事务的全局隔离级别:

set global transaction isolation level read uncommitted;

查看事务的全局隔离级别:

select @@global.tx_isolation;
		+-----------------------+
		| @@global.tx_isolation |
		+-----------------------+
		| READ-UNCOMMITTED      |
		+-----------------------+

第二:演示read committed

set global transaction isolation level read committed;

第三:演示repeatable read

set global transaction isolation level repeatable read;

第四:演示serializable

set global transaction isolation level serializable;

mysql远程登录:mysql -h192.168.151.18 -uroot -p123

4、索引

4.1、什么是索引?有什么用?

索引相当于一本书的目录,通过目录可以快速的找到对应的资源。

在数据库方面,查询一张表的时候有两种检索方式:

第一种方式:全表扫描

第二种方式:根据索引检索(效率很高)

索引为什么可以提高检索效率?

其实最根本的原理是缩小了扫描的范围。

索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引也是数据库当中的对象,也是需要数据库不断的维护。是有维护成本的。比如,表中的数据经常

被修改,这样就不适合添加索引,因为数据一旦修改,索引需要重新排序,进行维护。

索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始,然后读完整个表直到它找出相关的行。表越大,花费时间越

多。对于一个有序字段,可以运用二分查找(Binary Search),这就是为什么性能能得到本质上的提高。

MYISAM和InnoDB都是B+Tree作为索引结构。

(主键:unique都会默认的添加索引)

添加索引是给某一个字段,或者说某些字段添加索引。

select ename,sal from emp where ename = \'SIMITH\';

当ename字段上没有添加索引的时候,以上sql语句会进行全表扫描,扫描ename字段中所有的值。

当ename字段上添加索引的时候,以上sql语句会根据索引扫描,快速定位。

4.2、怎么创建索引对象?怎么删除索引对象?

创建索引对象
create index 索引名称 on 表名(字段名);
删除索引对象
drop index 索引名称 on 表名;

4.3、什么时候考虑给字段添加索引?(满足什么条件)

  • 数据量庞大。(根据客户的需求,根据线上的环境)
  • 该字段很少的DML操作。(因为字段进行修改操作,索引也需要维护)
  • 该字段经常出现在where子句中。(经常根据哪个字段查询)

4.4、注意:主键和具有unique约束的字段会自动添加索引。

根据主键查询效率较高。尽量根据主键检索。

4.5、查看sql语句的执行计划:

explain select ename,job from emp where sal = 5000;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   14 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

explain主要用于分析查询语句或表结构的性能瓶颈。

1、explain的作用

通过explain+sql语句可以知道如下内容:

①表的读取顺序。(对应id)

②数据读取操作的操作类型。(对应select_type)

③哪些索引可以使用。(对应possible_keys)

④哪些索引被实际使用。(对应key)

⑤表直接的引用。(对应ref)

⑥每张表有多少行被优化器查询。(对应rows)

explain select ename,job,sal from emp where sal > 1500 group by sal;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                        |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------+
|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   14 | Using where; Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------+

给薪资sal字段添加索引:

create index emp_sal_index on emp(sal);
explain select ename,job from emp where sal = 5000;
+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key           | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+
|  1 | SIMPLE      | emp   | ref  | emp_sal_index | emp_sal_index | 9       | const |    1 | Using where |
+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+

4.6、索引底层采用的数据结构是:B + Tree

4.7、索引的实现原理?

通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的“物理地址”,最终通过索引检索到数据之后,获取到关联的物理地址,通过物理

地址定位表中的数据,效率是最高的。

create index emp_ename_index on emp(ename);
select ename from emp where ename = \'SIMITH\';

通过索引转换为:

select ename from emp where 物理地址 = 0x3;

4.8、索引的分类?

单一索引:给单个字段添加索引

复合索引:给多个字段联合起来添加1个索引

主键索引:主键上会自动添加索引

唯一索引:有unique约束的字段上会自动添加索引

4.9、索引什么时候失效?

模糊查询like。

查询ename字段中包含有“A”的。

create index emp_ename_index on emp(ename);
select ename from emp where ename like \'%A%\';

模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的,会进行全表扫描。

模糊查询时,第一个位置最好不要写%!

5、视图(view)(了解)

5.1、什么是视图?

站在不同的角度去看待数据。(同一张表的数据,通过不同的角度去看待。)

  • 视图是一种根据查询(也就是SELECT表达式)定义的数据库对象,用于获取想要看到和使用的局部数据。

  • 视图有时也被称为“虚拟表”。

  • 视图可以被用来从常规表(称为“基表”)或其他视图中查询数据。

  • 相对于从基表中直接获取数据,视图有以下好处:

    • 访问数据变的简单

    • 可被用来对不同用户显示不同的表的内容。

      • 用来协助适配表的结构以适应前端现有的应用程序

      • 视图作用:

        • 提高检索效率

        • 隐藏表的实现细节【面向视图检索】

5.2、怎么创建视图?怎么删除视图?

create view myview as select empno,ename from emp;
drop view myview;

注意:只有DQL语句才能以视图对象的方式创建出来。

5.3、对视图进行增删改查,会影响到原表数据。(通过视图影响原表数据的,不是直接操作的原表。)

可以对视图进行CRUD操作。

5.4、面向视图操作?

(create view myview as select empno,ename from emp;)
select * from myview;
	+-------+--------+
	| empno | ename  |
	+-------+--------+
	|  7369 | SIMITH |
	|  7499 | ALLEN  |
	|  7521 | WARD   |
	|  7566 | JONES  |
	|  7654 | MARTIN |
	|  7698 | BLAKE  |
	|  7782 | CLARK  |
	|  7788 | SCOTT  |
	|  7839 | KING   |
	|  7844 | TURNER |
	|  7876 | ADAMS  |
	|  7900 | JAMES  |
	|  7902 | FORD   |
	|  7934 | MILLER |
	+-------+--------+
create table emp_bak as select * from emp;# 复制表结构及数据到新表emp_bak。
create view myview1 as select empno,ename,sal from emp_bak;# 通过原表emp_bak,创建视图myview1。
update myview1 set ename = \'hehe\',sal = 1 where empno = 7369;# 通过视图修改原表数据。
delete from myview1 where empno = 7369;# 通过视图删除原表数据。

5.5、视图的作用?—— 保密

视图可以隐藏表的实现细节。保密级别较高的系统,数据库只对外提供相关的视图,java程序员只对视图对象进行CRUD。视图并不会提高查询效率。

create view myview2 as select empno a,ename b,sal c from emp_bak;# 创建视图
select * from myview2;
	+------+--------+---------+
	| a    | b      | c       |
	+------+--------+---------+
	| 7499 | ALLEN  | 1600.00 |
	| 7521 | WARD   | 1250.00 |
	| 7566 | JONES  | 2975.00 |
	| 7654 | MARTIN | 1250.00 |
	| 7698 | BLAKE  | 2850.00 |
	| 7782 | CLARK  | 2450.00 |
	| 7788 | SCOTT  | 3000.00 |
	| 7839 | KING   | 5000.00 |
	| 7844 | TURNER | 1500.00 |
	| 7876 | ADAMS  | 1100.00 |
	| 7900 | JAMES  |  950.00 |
	| 7902 | FORD   | 3000.00 |
	| 7934 | MILLER | 1300.00 |
	+------+--------+---------+
insert into myview2(a,b,c) values(8000,\'GOD\',9999);# 插入数据
select * from myview2;
	+------+--------+---------+
	| a    | b      | c       |
	+------+--------+---------+
	| 7499 | ALLEN  | 1600.00 |
	| 7521 | WARD   | 1250.00 |
	| 7566 | JONES  | 2975.00 |
	| 7654 | MARTIN | 1250.00 |
	| 7698 | BLAKE  | 2850.00 |
	| 7782 | CLARK  | 2450.00 |
	| 7788 | SCOTT  | 3000.00 |
	| 7839 | KING   | 5000.00 |
	| 7844 | TURNER | 1500.00 |
	| 7876 | ADAMS  | 1100.00 |
	| 7900 | JAMES  |  950.00 |
	| 7902 | FORD   | 3000.00 |
	| 7934 | MILLER | 1300.00 |
	| 8000 | GOD    | 9999.00 |
	+------+--------+---------+
	select * from emp_bak;# 视图myview2对应的原表emp_bak
	+-------+--------+-----------+------+------------+---------+---------+--------+
	| empno | ename  | job       | mgr  | hiredate   | sal     | comm    | deptno |
	+-------+--------+-----------+------+------------+---------+---------+--------+
	|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 | 1600.00 |  300.00 |     30 |
	|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 | 1250.00 |  500.00 |     30 |
	|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 | 2975.00 |    NULL |     20 |
	|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 | 1250.00 | 1400.00 |     30 |
	|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 | 2850.00 |    NULL |     30 |
	|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 | 2450.00 |    NULL |     10 |
	|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 | 3000.00 |    NULL |     20 |
	|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 | 5000.00 |    NULL |     10 |
	|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 | 1500.00 |    NULL |     30 |
	|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 | 1100.00 |    NULL |     20 |
	|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 |  950.00 |    NULL |     30 |
	|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 | 3000.00 |    NULL |     20 |
	|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 | 1300.00 |    NULL |     10 |
	|  8000 | GOD    | NULL      | NULL | NULL       | 9999.00 |    NULL |   NULL |
	+-------+--------+-----------+------+------------+---------+---------+--------+

6、DBA命令(了解) —— 最重要的是导入导出

6.1、新建用户

create user username identified by \'password\';

说明:username————你将创建的用户名,password————该用户的登录密码。如果为空,则该用户不需要密码登录服务器。

6.2、授权

grant all privileges on dbname.tbname to \'username\'@\'login ip\' identified by \'password\' with grant option;
  1. dbname=* 表示所有数据库。
  2. tbname=* 表示所有表(如果要授予该用户对所有数据库和表的相应操作权限则可用表示, 如.*)。
  3. login ip=%表示任何ip。
  4. password为空,表示不需要密码即可登录。
  5. with grant option表示该用户还可以授权其他用户。
  6. 说明:privileges——用户的操作权限,如select , insert , update 等,如果要授予所有的权限则使用all。
6.1.1、细粒度授权

首先以root用户进入mysql,然后键入命令:grant select,insert,update,delect on *.* to p361 @localhost identified by \"123\";如果希望该用户能够在任何机器上登录mysql,则将localhost改为“%”;

6.1.2、粗粒度授权

我们测试用户一般使用该命令授权,grant all privileges *.* to \'p3610\'@\'%\' identified by \"123\";

注意:用以上命令授权的用户不能给其它用户授权,如果想要该用户可以授权,用以下命令:

grant privileges on databasename.tablename to \'mysql_user_name\'@\'host\' with grant option;
privileges包括:
  1. alter:修改数据库的表
  2. create:创建新的数据库或表
  3. delete:删除表数据
  4. drop:删除数据库/表
  5. index:创建/删除索引
  6. insert:添加表数据
  7. select:查询表数据
  8. update:更新表数据
  9. all:运行任何操作
  10. usage:只允许登录

6.3、回收权限

revoke privileges on dbname[.tbname] from username;
revoke privileges on *.* from p361;
修改密码

进入mysql库中

use mysql;
select * from user;
update user set password = password(\'qwe\') where user = \'p646\';
刷新权限
flush privileges;

6.4、导入导出

6.4.1、导出
6.4.1.1、导出整个数据库

在windows的dos命令窗口(不要登录到mysql系统当中)中执行:mysqldump bjpowernonde>D:\\bjpowernode.sql -uroot -p123;

6.4.1.2、导出指定库下的指定表

在windows的dos命令窗口中执行:mysqldump bjpowernode>D:\\bjpowernode.sql -uroot -proot;

6.4.2、导入

登录MySQL数据库管理系统之后,

create database bjpowernode;
use bjpowernode;

执行:

source D:\\bjpowernode.sql;

7、数据库设计三范式(重点内容,面试经常问)

7.1、什么是设计范式?

设计表的依据。按照这个三范式设计的表不会出现数据冗余。

7.2、三范式都是哪些?

第一范式:任何一张表都应该有范式一,并且每一字段原子性不可再分。

数据库表中不能出现重复记录,每个字段是原子性的不能再分。

关于第一范式,每一行必须唯一,也就是每个表必须有主键,这是我们数据库设计的最基本要求。

第二范式:建立在第一范式的基础之上,另外要求所有非主键字段完全依赖主键,不能产生部分依赖。

多对多?三张表,关系表两个外键。

t_student学生表
sno(pk)		sname
-----------------
1		张三
2		李四
3		王五
t_teacher讲师表
t(pk)		tname
-----------------
1		王老师		
2		张老师
3		李老师
t_student_teacher_relation学生教师关系表
id(pk)		sno(fk)		tno(fk)
-------------------------------
1		1		3
2		1		1
3		2		2
4		2		3
5		3		1
6		3		3

第三范式:建议在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。

一对多?两张表,多的加外键。

班级t_class
cno(pk)	cname
-------------
1		班级1
2		班级2
学生t_student
sno(pk)	sname		classno(fk)
-------------------------------
101		张1		1
102		张2		1
103		张3		2
104		张4		2
105		张5		2

提醒:在实际开发中,以满足用户的需求为主,有的时候会拿冗余换执行速度。

7.3、一对一怎么设计?

一对一设计有两种方案:主键共享和外键唯一。

第一种:主键共享
t_user_login	用户登录表
id(pk)		username	password
--------------------------------
1		zs		123
2		ls		456
t_user_detail	用户详细信息表
id(pk+fk)		realname	tel	...
-----------------------------------
1		张三		12345678901
2		李四		09876543211
第二种:外键唯一
id(pk+fk)		realname	tel	userid(fk+unique)	...
-------------------------------------------------------
1		张三		12345678901	1
2		李四		09876543211	2

8、扩展

MYSQL中处理插入过程主键或唯一重复值的解决办法

1.IGNORE:有则忽略,无则插入

2.REPLACE:有则删除再插入,无则插入

3.ON DUPLIACATE KEY UPDATE:有则更新,无则插入


来源:https://www.cnblogs.com/zhllw/p/16172787.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » MySQL学习笔记-day03

相关推荐

  • 暂无文章