Mysql 和 Oracle 的基本知识总结

查看databases,tables,use

mysql:

select version();

show databases;

show tables;

use username

可以使用 desc t_user 来查看表结构、表中列的声明顺序

oracle:

select * from all_users;

select * from user_tables;

select table_name from user_tables; //当前用户的表

select table_name from all_tables; //所有用户的表

select table_name from dba_tables; //包括系统表

select table_name from dba_tables where owner=‘zfxfzb’

conn username;

对于null的处理:

mysql:

计算每个员工的年薪?
select ename,(sal+comm)*12 as yearsal from emp;
重点:所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL。
使用ifnull函数:
select ename,(sal+ifnull(comm,0))*12 as yearsal from emp;

ifnull() 空处理函数?
ifnull(可能为NULL的数据,被当做什么处理) : 属于单行处理函数。

oracle:

使用nvl函数可以将null进行替换

group by

记住一个规则:当一条语句中有group by的话,select后面只能跟分组函数和参与分组的字段。

distinct

1、关于查询结果集的去重?
mysql> select distinct job from emp; // distinct关键字去除重复记录。

mysql> select ename,distinct job from emp;
以上的sql语句是错误的。
记住:distinct只能出现在所有字段的最前面。

案例:统计岗位的数量?
select count(distinct job) from emp;

format

column name format a15;

只有Oracle中有用

笛卡儿积

笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。

多表连接查询

根据表的连接方式来划分,包括:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)
全连接

内连接之非等值连接:最大的特点是:连接条件中的关系是非等量关系

select 
	e.ename,e.sal,s.grade
from
	emp e
join
	salgrade s
on
	e.sal between s.losal and s.hisal;

外连接:

当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。

外连接最重要的特点是:主表的数据无条件的全部查询出来。

全连接:

全外连接,即无论on中的条件满不满足,都保留所有表所有数据

由于mysql不支持全外连接,所以此条语句只能在其他数据库中执行

select s.name,t.name from student s full outer join teacher t on s.tId = t.id;

子查询

  • 案例:找出高于平均薪资的员工信息。
    select * from emp where sal > avg(sal); //错误的写法,where后面不能直接使用分组函数。

    正确写法:select * from emp where sal > (select avg(sal) from emp);

  • 案例:找出每个部门平均薪水的等级

    第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值)
    select deptno,avg(sal) as avgsal from emp group by deptno;

    第二步:将以上的查询结果当做临时表t,让t表和salgrade s表连接,条件是:t.avgsal between s.losal and s.hisal

操作结果集

  • Union,对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;

  • Union All,对两个结果集进行并集操作,包括重复行,不进行排序;

  • Intersect,对两个结果集进行交集操作,不包括重复行,同时进行默认规则的排序;

  • Minus,对两个结果集进行差操作,不包括重复行,同时进行默认规则的排序。

  可以在最后一个结果集中指定Order by子句改变排序方式。

分页查询(five stars)

mysql:

  1. limit是mysql特有的,其他数据库中没有,不通用。(Oracle中有一个相同的机制,叫做rownum)

  2. limit取结果集中的部分数据,这是它的作用。

  3. 语法机制:
    limit startIndex, length
    startIndex表示起始位置,默认从0开始,0表示第一条数据。
    length表示取几个

       案例:取出工资前5名的员工(思路:降序取前5个)
       	select ename,sal from emp order by sal desc;
       	取前5个:
       		select ename,sal from emp order by sal desc limit 0, 5;
       		select ename,sal from emp order by sal desc limit 5;
    
  4. limit是sql语句最后执行的一个环节

    案例:找出工资排名在第4到第9名的员工?

    select ename,sal from emp order by sal desc limit 3,6;
    
  5. 通用的标准分页sql

    公式:

    假如要显示的页数是page,每页显示的条目数为size

    select *
    from emp
    limit (page-1)*size,size;

oracle:

  1. Oracle中,有一个特殊的关键字rownum,被称为:伪列。

    rownum只有Oracle数据中才有。

    1. rownum (伪列),就像表中的列一样,但是在表中并不存在。

      伪列并不能像表中真实的列一样随便操作,伪列只能用于查询

      select rownum,last_name from s_emp;

    2. 伪列,可以根据查询结果的条数,自动生成,并且一定是从1开始连续不断的数字

      伪列rownum的本质就是给查询的一行行结果标上行号

    3)如果伪列用在where条件中,那么它只能有以下操作:

    • rownum 如果是相同的条件,那么伪列只能等于1

      如果等于其他值,那么就查询不出任何结果

    • rownum 如果是大于的条件,那么伪列只能大于0

    • rownum 可以小于任何数

  2. 伪列rownum实现分页查询

    • 给rownum起一个别名rn,然后把这个sql语句作为第二条sql语句的子查询,并且把它当做一张虚拟的表,那么这时候,这个虚拟表中的rn是可以当做普通的字段进行操作了

      select t.id,t.last_name,t.dept_id
      from 
          (
              select rownum rn,id,last_name,dept_id
          	from s_emp where rownum<=10 
          ) t 
      where t.rn>=6;
      
    • rownum结合关键字minus完成分页

      select rownum,last_name from s_emp where rownum <=7 
      minus 
      select rownum,last_name from s_emp where rownum < 3;
      

建表

create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型,

);

命名

对应表和列的名字:

\1. 必须是字母开头

\2. 必须是1-30个字符之间的长度

\3. 表名中只能出现字母、数字、_、#

\4. 不能和数据库中己有对象的名字重复

\5. 不能是数据库中的关键字

数据类型

mysql:

1、整型
TINYINT SMALLINT INT BIGINT

2、浮点型
FLOAT(m,n)
DOUBLE(m,n)
DECIMAL(m,n)
m和n可选

3、字符型

CHAR(n):n可选
VARCHAR(n):n必选
TEXT
n表示最多字符个数

4、日期型

DATE TIME DATETIME TIMESTAMP

5、二进制型

BLOB 存储图片数据

6、

CLOB 存储大文本

char和varchar怎么选择?
在实际的开发中,当某个字段中的数据长度不发生改变的时候,是定长的,例如:性别、生日等都是采用char。
当一个字段的数据长度不确定,例如:简介、姓名等都是采用varchar。

oracle:

\1. char varchar varchar2 都是存储字符串

char 存储数据的长度是固定的。varchar2 存储数据的长度是可变的。

char 效率比 varchar2效率高。 varchar是数据库标准类型,varchar2类型是oracle数据库中特有的

varchar2不能存空字符串,可以存null。varchar可以存空字符串

Oracle建议使用VARCHAR2

\2. number(p,s)

p 表示最大位数(整数位+小数位), s表示保留的小数位(四舍五入),也可以为负数。

例如,number(5,2)

存进去123.456,取出来为123.46

存进去12345.456,运行报错:值大于为此列指定的允许精度

注意1,其实这时候整数位最大只能有3位,因为要留俩位给小数位

注意2,可以直接使用number,不加参数,描述没有默认没限制

\3. date

日期类型

\4. blob

存二进制对象,例如视频,音频,图片等

\5. clob

存储大文本,例如很多很多文字

约束

说明:用于限制表中字段的数据的,从而进一步保证数据表的数据是一致的、准确的、可靠的!

NOT NULL 非空:用于限制该字段为必填项
DEFAULT 默认:用于限制该字段没有显式插入值,则直接显式默认值
PRIMARY KEY 主键:用于限制该字段值不能重复,设置为主键列的字段默认不能为空
一个表只能有一个主键,当然可以是组合主键 primary key(id)

主键的分类?
根据主键字段的字段数量来划分:
单一主键(推荐的,常用的。)
复合主键(多个字段联合起来添加一个主键约束)(复合主键不建议使用,因为复合主键违背三范式。)
根据主键性质来划分:
自然主键:主键值最好就是一个和业务没有任何关系的自然数。(这种方式是推荐的)
业务主键:主键值和系统的业务挂钩,例如:拿着银行卡的卡号做主键,拿着身份证号码作为主键。(不推荐用)
最好不要拿着和业务挂钩的字段作为主键。因为以后的业务一旦发生改变的时候,主键值可能也需要
随着发生变化,但有的时候没有办法变化,因为变化可能会导致主键值重复。

UNIQUE 唯一:用于限制该字段值不能重复 unique(email)

CHECK检查:用于限制该字段值必须满足指定条件
CHECK(age BETWEEN 1 AND 100)

注意Oracle数据库有check约束,但是mysql没有,目前mysql不支持该约束。

FOREIGN KEY 外键:用于限制两个表的关系,要求外键列的值必须来自于主表的关联列
要求:
①主表的关联列和从表的关联列的类型必须一致,意思一样,名称无要求
外键值可以为NULL?
外键可以为NULL。

​ 外键字段引用其他表的某个字段的时候,被引用的字段必须是主键吗?
​ 注意:被引用的字段不一定是主键,但至少具有unique约束。

​ 列级约束:references t_customer(id)

​ 表级约束:foreign key(customer_id) references t_customer(id)

表级约束和列级约束对比:

\1. 表级约束和列级约束所写的位置不一样

\2. not null约束不能用表级约束来声明

\3. 表级约束和列级约束声明语法稍有所不同

\4. 如果要声明的约束为联合主键联合外键联合唯一的时候,就一定要用表级约束

在创建约束的时候(行级、表级都可以),还可以给约束起一个名字,这时候就要使用关键字

constraint

constraint 关键字:

\1. constraint是约束的意思

\2. 建表的时候可以给约束起一个名字,这个名字起的规律一般会是:表名_列名_约束类型

\3. 如果没有给约束起名字,那么系统也会给这个约束起一个默认的名字

\4. 将来我们可以根据之前给约束起好的名字,而找到这个约束,然后进行修改获取其他操作

delete on

on delete xxx 语句是在声明外键约束的时候使用的

  1. on delete no action

    如果在建外键的时候,不加on delete语句,默认就是 on delete no action

  2. on delete cascade

    删除成功了,同时级联(cascade)删除了,t_order表中所关联的那条数据

  3. on delete set null

    删除成功了,同时把t_order表中所关联的那条数据的外键设置为了null

create table t_order( 
    id number, price number, 
    customer_id number, 
    constraint order_id_pk primary key(id), 
    constraint order_cid_fk foreign key(customer_id) references t_customer(id) on delete set null );

主键自增

  • mysql提供主键值自增:(非常重要。)

    create table t_user(
    			id int primary key auto_increment, // id字段自动维护一个自增的数字,从1开始,以1递增。
    			username varchar(255)
    		);
    
  • oracle依靠序列sequence实现主键自增

    • 序列(Sequence),它也是一种数据库对象。

      它作用主要用来帮助表去创建自动增长的主键。

      序列是oracle数据库所特有的对象,其他数据库中是没有的。

      创建序列的默认语法:

      create sequence 序列名;
      

      查看序列的当前值,语法:

      select 序列名.currval from dual;
      

      查看序列下一个值,语法:

      select 序列名.nextval from dual;
      

      创建好一个序列之后,不能先使用currval,因为当前还没有值,需要先使用nextval,之后才

      可以使用currval

      查询当前用户的序列:

      select sequence_name from user_sequences;
      

      删除序列语法:

      drop sequence 序列名
      
    • 使用序列产生id值:

      insert into t_user(id,name,salary) values(t_user_seq.nextval,'tom',2000);
      

视图

视图(view),它也是一种数据库对象

视图其实就是提取一张表或者多张表的数据生成一个映射。

操作视图从而达到操作原表的效果,方便数据管理和安全操作。

视图的主要作用是隐藏表中的重要数据、代替比较长的sql语句。

存储引擎

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

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

常见的存储引擎

  • MyISAM这种存储引擎不支持事务。
    MyISAM是mysql最常用的存储引擎,但是这种引擎不是默认的。
    MyISAM采用三个文件组织一张表:
    xxx.frm(存储格式的文件)
    xxx.MYD(存储表中数据的文件)
    xxx.MYI(存储表中索引的文件)
    优点:可被压缩,节省存储空间。并且可以转换为只读表,提高检索效率。
    缺点:不支持事务。

  • InnoDB

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

    表的结构存储在xxx.frm文件中
    数据存储在tablespace这样的表空间中(逻辑概念),无法被压缩,无法转换成只读。
    这种InnoDB存储引擎在MySQL数据库崩溃之后提供自动恢复机制。
    InnoDB支持级联删除和级联更新。

  • MEMORY

缺点:不支持事务。数据容易丢失。因为所有数据和都是存储在内存当中的。
优点:查询速度最快。
以前叫做HEPA引擎。

事务

事务是逻辑上的⼀组操作,要么都执⾏,要么都不执⾏。

事务最经典也经常被拿出来说例⼦就是转账了。假如⼩明要给⼩红转账1000元,这个转账会涉及到两个

关键操作就是:将⼩明的余额减少1000元,将⼩红的余额增加1000元。万⼀在这两个操作之间突然出现

错误⽐如银⾏系统崩溃,导致⼩明余额减少⽽⼩红的余额没有增加,这样就不对了。事务就是保证这两

个关键操作要么都成功,要么都要失败。

  • 和事务相关的语句只有:DML语句。(insert delete update)
    为什么?因为它们这三个语句都是和数据库表当中的“数据”相关的。
    事务的存在是为了保证数据的完整性,安全性。

  • 事务包括四大特性:ACID

    1. 原⼦性(Atomicity): 事务是最⼩的执⾏单位,不允许分割。事务的原⼦性确保动作要么全部

    完成,要么完全不起作⽤;

    1. ⼀致性(Consistency): 执⾏事务前后,数据保持⼀致,多个事务对同⼀个数据读取的结果是

    相同的;

    1. 隔离性(Isolation): 并发访问数据库时,⼀个⽤户的事务不被其他事务所⼲扰,各并发事务

    之间数据库是独⽴的;

    1. 持久性(Durability): ⼀个事务被提交之后。它对数据库中数据的改变是持久的,即使数据

    库发⽣故障也不应该对其有任何影响。

索引

1、什么是索引?有什么用?
索引就相当于一本书的目录,通过目录可以快速的找到对应的资源。
在数据库方面,查询一张表的时候有两种检索方式:
第一种方式:全表扫描
第二种方式:根据索引检索(效率很高)

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

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

​ 索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引也是数据库当中
​ 的对象,也需要数据库不断的维护。是有维护成本的。比如,表中的数据经常被修改
​ 这样就不适合添加索引,因为数据一旦修改,索引需要重新排序,进行维护。

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

select ename,sal from emp where ename = 'SMITH';

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

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

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

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

  • 数据量庞大
  • 该字段很少的DML 操作(因为字段不断的修改,索引也需要不断的更新)
  • 该字段经常出现在 where 子句的后边(经常使用哪个字段查询)
  • 尽量使用数据量少的索引,如果索引的值很长,那么查询的速度会受到影响。

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

​ 根据主键查询效率更高,尽量根据主键查询。

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

mysql> explain select ename,sal 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 |
		+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

​ 给薪资sal字段添加索引:

create index emp_sal_index on emp(sal);
	
mysql> explain select ename,sal 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 |
	+----+-------------+-------+------+---------------+---------------+---------+-------+------+-------------+

6、索引的实现原理:

​ 7、 B + Tree

​ 通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的“物理地址”,
​ 最终通过索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率
​ 是最高的。
​ select ename from emp where ename = ‘SMITH’;
​ 通过索引转换为:
​ select ename from emp where 物理地址 = 0x3;

8、索引的分类

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

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

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

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

​ …

9、索引什么时候失效

  • 对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引

    alter table student add index my_index(name, age)   // name左边的列, age 右边的列                                                       
    select * from student where name = 'aaa'     // 会用到索引
    
    select * from student where age = 18          //  不会使用索引
    
  • select ename from emp where ename like ‘%A%’;
    模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的

  • 如果条件中有 or, 有条件没有使用索引,即使其中有条件带索引也不会使用,换言之, 就是要求使用的所有字段,都必须单独使用时能使用索引。

  • 如果列类型是字符串,那么一定要在条件中使用引号引用起来,否则不使用索引。

  • 如果mysql认为全表扫面要比使用索引快,则不使用索引。

    如:表里只有一条数据。

10、数据库设计三范式

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

第一范式:表中的每一个字段都是原子性不可再分的

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

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

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

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