本系列文章将针对MySQL数据库的由浅到深进行讲解
数据库作为应用广泛的数据存储方式之一,是目前全栈、后端、算法工程师必须掌握的一类工具,本文将进行一系列关于数据库的分析,包含并不限于MySQL等主流数据库。
作为目前主流使用的免费数据库,MySQL收到了许多学者和工程师的欢迎,目前也是使用较为广泛的数据库之一,MySQL属于MySQL AB公司开发的小型关系数据库,该公司已经被sun公司收购,而sun公司又被oracle公司收购,因此,目前MySQL是由oracle公司进行维护的。
官方下载地址
接下来的介绍将以windows版本为例
安装只要一直点下一步就可以了。
跳过安装配置(如果有需要之后我会继续发一篇相关的文章)直接进入操作。
数据库: 英文单词DataBase,简称DB。按照一定格式存储数据的一些文件的组合。顾名思义:存储数据的仓库,实际上就是一堆文件,这些文件中存储了具有特定格式的数据。
数据库管理系统: DataBaseManagementSystem,简称DBMS。是专门用来管理数据库中数据的,数据库管理信息系统可以对数据库当中的数据进行增、删、改、查。
常见的数据库管理系统: MySQL、Oracle、MS、SqlServer、DB2、sybase、OceanBase等。
SQL: Structure Query Language(结构化查询语言)简称SQL,简单来讲程序员编写SQL语言,然后DBMS执行SQL语言,最终完成数据库中数据的增、删、改、查。
三者之间的关系:DBMS- -执行- -SQL- - 操作- - DB.
上文中,已经描述过SQL语言的概念,接下来将对SQL语言进行详细的描述。
在进行SQL语言学习之间,应该先明白一个概念,就是数据库中最基本的单元是:表(table) , 数据库当中以表格的形式展示数据,任何一张表都有行和列。
行(row):被称为数据/记录。
列(column):被称为字段。
在关系性数据库当中,为了确保数据的完整性和唯一性,在创建表时除了必须指定字段名称、字段类型、字段属性,还需要使用约束(constraint)、索引(index)、主键(primary key)、外键(foregin key)等功能属性。
MySQL数据库中的列类型有三类:数值类、字符串类和日期/时间类。
数据列表类型 | 存储空间 | 说明 | 取值范围 |
---|---|---|---|
TINYINT | 1字节 | 非常小的整数 | 带符号值:-128~127 无符号值: 0~255 |
SMALLINT | 2字节 | 较小的整数 | 带符号值:-32768~32767 无符号值:0~65535 |
MEDIUMNT | 3字节 | 中等大小的整数 | 带符号值:-8288608~8388607 无符号值:0~16777215 |
INT | 4字节 | 标准整数 | 带符号值:-2147483648~2147483647 无符号值:0~4294967295 |
FLOAT | 4或8字节 | 单精度浮点数 | 最小非零值:±1.175494351E-38 最大非零值:±3.402823466E+38 |
BOUBLE | 8字节 | 双精度浮点数 | 最小非零值:±2.2250738585072014E-308 最大非零值:±1.7976931348623157E+308 |
数据列表类型 | 存储空间 | 说明 | 取值范围 |
---|---|---|---|
CHAR[M] | M字节 | 定长字符串 | M字节 |
VARCHAR[M] | L+1字节 | 可变字符串 | M字节 |
TINYBLOD,TINYTEXT | L+1字节 | 非常小的BLOB和文本串 | 28 -1字节 |
BLOD,TEXT | L+2字节 | 小BLOB和文本串 | 216 -1字节 |
ENUM(‘value1’,‘value2’…) | 1或2字节 | 枚举:可赋予某个枚举成员 | 65535个成员 |
SET(‘value1’,‘value2’…) | 1、2、3、4或8字节 | 枚举:可赋予多个集合成员 | 64个成员 |
注意:虽然VARCHAR和TEXT两者使用起来是变长的,但会使表中产生许多脆片要定期运行OPTIMIZE TABLE语句以保持其性能。所以在设计表得时候请谨慎。
数据列表类型 | 存储空间 | 说明 | 取值范围 |
---|---|---|---|
DATE | 3字节 | “YYYY-MM-DD”格式表示的日期值 | 1000-01-01~9999-12-31 |
TIME | 3字节 | “hh:mm:ss”格式表示的时间值 | -838:59:59~838:59:59 |
TIME | 8字节 | “YYYY-MM-DD hh:mm:ss”格式 | 1000-01-01 00:00:00~9999-12-31 23:59:59 |
TIMESTAMP | 4字节 | “YYYYMMDDhhmmss”格式表示的时间戳 | 19700101000000~2037年的某个时刻 |
YEAR | 1字节 | “YYYY”格式的年份值 | 1901~2155 |
1+'2' #会转换成1+2=3 1+'abc' #会转换成1+0=1.由于abc不能转换成任何值,所以默认为零
优点:
1、简单易学,具有很强的操作性
2、绝大多数重要的数据库管理系统均支持SQL
3、高度非过程化;用SQL操作数据库时大部分的工作由DBMS自动完成
分类:
1、DDL(Data Definition Language) 数据定义语言,用来操作数据库、表、列等; 常用语句:CREATE、 ALTER、DROP
2、DML(Data Manipulation Language) 数据操作语言,用来操作数据库中表里的数据;常用语句:INSERT、 UPDATE、 DELETE
3、DCL(Data Control Language) 数据控制语言,用来操作访问权限和安全级别; 常用语句:GRANT、DENY
4、DQL(Data Query Language) 数据查询语言,用来查询数据 常用语句:SELECT
接下来列举一些关于数据库的连接、创建、查看、删除等操作。
数据库的启停:
在windows操作系统中使用命令启动数据库: net stop 服务器名; net start 服务器名; 注意!在启停数据库的时候要以管理员身份启动窗口
数据库的基本操作:
登录mysql:mysql -h -u用户名 -p用户密码; 退出mysql:exit 创建数据库 : create database [IF NOT EXISTS]数据库名; 查看有哪些数据库:show databases; 删除数据库:drop database [IF EXISTS] 数据库名;
运行效果:
创建名为:TEST的数据库
查看数据库:
使用数据库:use database;
查看当前使用的数据库:select database();
删除数据库(删库跑路必备)
创建表:create table 表名{ 字段名1 字段类型 字段属性 字段约束, 字段名2 字段类型 字段属性 字段约束, 字段名3 字段类型 字段属性 字段约束, 字段名4 字段类型 字段属性 字段约束, ... }表类型 表字符集;
查看表的创建语句:
show create table 表名;
查看表结构:
查看当前库中的表:
show tables
查看其他库中的表:
show tables from 数据库名称;
ALTER TABLE 表名 ACTION;其中ACTION是ALTER TABLE 的从句,包括为指定的表添加一个新列、为表添加一个索引、更改指定列的默认值、更改列类型、删除一列、删除索引、更改表名等语句。下面简单介绍几种常用的语句:
为指定的数据表添加一个新字段:
ALTER TABLE 表名 ADD 字段名<建表语句>[FIRST|AFTER 列名]
其中FIRST、AFTER是指在列头添加还是在列尾添加。
为指定的数据表更改原有字段的类型。
```sql ALTER TABLE 表名 CHANGE(MODIFY) 列名 <建表语句> ``` ```sql ALTER TABLE users MODIFY telnum int(20) UNSIGNED; ALTER TABLE users CHANGE telnum telno INT(20) UNSIGNED; ``` <font size=3> 上述语句当中的区别在于CHANGE不光可以修改字段属性,还可以修改字段名;而MODIFY只可以修改字段属性。
为指定的数据表重命名
ALTER TABLE 旧表名 RENAME AS 新表名;
ALTER TABLE users RENAME AS userlist;
删除列
ALTER TABLE 表名 DROP 字段名;
DROP TABLE IF EXISTS 表名;
INSERT INTO 表名(字段名1,字段名2,字段名3...) VALUES(值1,值2,值3...)
示例,向users中插入一条数据:
INSERT INTO users(id,username,userpassword,sex,birthday) VALUES(1,'sam','123','男','2021-7-13');
在使用insert语句时候,每个字段和其属性是一一对应的,因此在输入过程中注意数据的顺序。另外,也可以在输入时不输入字段名,直接跟VALUES(),此时默认对所有字段进行插入值,在填入数据时要注意。
INSERT INTO users VALUES(值1,值2...);
UPDATE users SET 字段名1=值1,字段名2=值2... WHERE 条件;注意,如果没有条件,那么意味着所有数据全部更新。 示例,更新users中‘sam’名字为‘zhangsan’:
UPDATE users SET username = 'zhangsan' WHERE id = '1';
DELETE FROM 表名 WHERE 条件;如果没有WHERE语句,则表示会删除一张表的所有数据(注意,表不会被删,删除表使用DROP语句),否则删除指定数据。 示例,新建一张名为student的表,而后删除。 新建:
CREATE TABLE student( id int(10), name varchar(20), age int ); INSERT INTO student(id,name,age) VALUES(1,'ZHANGSAN',18),(2,'LISI',19);
删除‘LISI’的记录:
DELETE FROM student WHERE name = 'LISI';
删除student表:
DELETE FROM student;
还有一种删除语句:
TRUNCATE TABLE 表名;两者的区别: (1)DELETE语句后可跟WHERE子句,可通过指定WHERE子句中的条件表达式只删除满足条件的部分记录;但是,TRUNCATE语句只能用于删除表中的所有记录。 (2)使用TRUNCATE语句删除表中的数据后,再次向表中添加记录时自动增加字段的默认初始值重新由1开始;使用DELETE语句删除表中所有记录后,再次向表中添加记录时自动增加字段的值为删除时该字段的最大值加1。 (3)DELETE语句是DML语句,TRUNCATE语句通常被认为是DDL语句。 (4)DELETE删除可以回滚,恢复数据,表中数据被删除,但是硬盘上的存储空间没有释放;TRUNCATE无法回滚,但删除更快。但是DELETE可以回滚的条件是MySQL中已经设置了binlog,设置后可以根据时间回滚。
SELECT 字段名 FROM 表名;其中,字段名可以跟‘AS 别名’来给字段添加别名显示;字段名可以直接使用数学运算(+,-,*,/)完成对该字段内的数据的数学运算。 在示例之前,我们先对users 表添加几条数据:
INSERT INTO users(id,username,userpassword,sex,birthday) VALUES(2,'LISI','123','女','2021-06-30'),(3,'wangwu','456','女','2021-05-30'),(4,'zhaoliu','789','男','2018-05-24');
查询表中全部内容
SELECT 字段1、字段2、。。。。 FROM 表名 WHERE 条件1、条件2、。。。。;
示例:查询’sex = ‘男’'的姓名记录:
SELECT username AS name FROM users WHERE sex='男';
在上边的示例中,查询出了所有男的姓名,可以观察到在显示的时候,使用了AS语句对查询的结果进行另命名。
示例:计算id=6的人的十倍工资:
SELECT sal*10 AS '工资' FROM users WHERE id='6';
接下来,我们对条件语句进行进一步了解。
条件查询中WHERE支持的运算符,如下:
运算符 | 说明 |
---|---|
= | 等于 |
<>或!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
between…and… | 两个值之间,等同于>=and<= |
is null | 为null(is not null 不为空) |
and | 并且 |
or | 或者 |
in | 包含,相当于多个or(not in 不在这个范围) |
not | not可以取非,主要用在is 或 in中 |
like | 模糊查询,支持%或者下划线匹配 %匹配任意个字符 下划线,一个下划线只匹配一个字符 |
由于后边会涉及到多表查询等操作,所以从新使用新的数据库表,格式如下:
员工表:
薪资等级表:
部门表:
下面我们对运算符做一些简单说明,其中常见的就不做示例了,如下:
between … and …. 两个值之间, 等同于 >= and <=
查询薪资在2450和3000之间的员工信息?包括2450和3000
第一种方式:>= and <= (and是并且的意思。)
select empno,ename,sal from emp where sal >= 2450 and sal <= 3000;
第二种方式:
between … and … select empno,ename,sal from emp where sal between 2450 and 3000; 注意: 使用between and的时候,必须遵循左小右大。 between and是闭区间,包括两端的值。
is null
查询哪些员工的津贴为null
SELECT empno,ename,comm FROM EMP WHERE comm is null;
注意,在MySQL中null不能使用等号衡量。而是使用is null,这是因为Null代表的是什么都没有,这里的什么都没有同时意味着Null不是一个值,因此,不能使用等号衡量。
and
and 语句又译为‘交’,是指同时满足and左右两端条件。求集合的交集。
查询工作岗位是MANAGER并且工资大于2500的员工信息?
SELECT empno,ename,job,sal FROM EMP WHERE job='MANAGER' AND sal>2500;
or
和and相反,or,是指满足其中一个条件即可。求集合的并集。
查询工作岗位是MANAGER和SALESMAN的员工?
select empno,ename,job from emp where job = 'MANAGER'; select empno,ename,job from emp where job = 'SALESMAN'; select empno,ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
这里要做一个说明,当and和or 同时出现在条件查询中时,and的优先级高于or的优先级。如果想让or限制性就需要给or语句加小括号,总的来讲,如果不确定执行的优先级,就给条件加小括号。
in
in语句用于指定条件的范围吗,例如:
查询工作岗位是MANAGER和SALESMAN的员工?
select empno,ename,job from emp where job = 'MANAGER' or job = 'SALESMAN'; select empno,ename,job from emp where job in('MANAGER', 'SALESMAN'); 这两个句子意义一样。
like模糊查询
首先,like语句可以检索目标项和数据项所匹配的数据(类似于知网中关键字查询)。
简单举个例子,查找名字为’SMITH’的数据:
SELECT * FROM EMP WHERE ename like 'SMITH';
这个查找中:ename like ‘SMITH’ 作用和 ename = ‘SMITH’ 一样,从这里并不能直接看出LIKE语句作用,接下来问题变为:
查询名字中包含 ‘A’ 的所有员工信息?
SELECT * FROM EMP WHERE ename like '%A%';
了解了LIKE语句的意义后,接下来区分%和下划线的不同:
%可以匹配任意长度的字符;
下划线只能匹配单个字符;
注意,两个方式出现在关键字左边及只检索左边,右边同理;出现在两边则全关键字检索。
数据处理函数又被称为单行处理函数。其特点是:一个输入对应一个输出。
常见的单行处理函数:
函数名 | 含义 |
---|---|
lower | 转成小写 |
upper | 转成大写 |
substr | 取子串,substr(待截取字符串,起始下标【从1开始】,结束下标) |
length | 取字符串长度 |
concat | 进行字符串的拼接 |
trim | 去除空格 |
str_to_date | 字符串转换成日期 |
round | 四舍五入,round(待处理数字,保留小数点的位数) |
rand | 生成随机数,rand()默认生成0-1之间的 |
ifnull | 空值处理函数,ifnull(数据,替换数据) |
case…when…then…else…end | 当…时…其他…结束 |
SELECT UPPER(ename) AS name FROM EMP;
名字首字母小写:
SELECT CONCAT(lower(substr(ename,1,1)),substr(ename,2,LENGTH(ename)-1)) AS name FROM EMP;
case…when…then…else…end示例:
当员工的工作岗位是MANAGER的时候,工资上调10%,当工作岗位是SALESMAN的时候,工资上调50%,其它正常。(注意:不修改数据库,只是将查询结果显示为工资上调)
SELECT ename,job,sal AS oldsal,(case job WHEN job='MANAGER' THEN sal*1.1 WHEN job='SALESMAN' THEN sal*1.5 ELSE sal end) AS newsal FROM EMP;
聚合函数也叫分组函数、多行处理函数:输入多行,输出一行。
分组函数在使用的时候必须先进行分组,然后才能用。
函数名 | 说明 |
---|---|
count | 计数 |
sum | 求和 |
avg | 平均数 |
max | 最大值 |
min | 最小值 |
这五个函数的使用方法是相同的
示例:
SELECT COUNT(ename) AS '人数' FROM EMP;
聚合函数使用起来很方便,但是有一些注意事项:
1.只有SELECT子句和HAVING子句、ORDER BY子句中能够使用聚合函数。不可以在WHERE语句中使用。
2.分组函数自动忽略NULL,你不需要提前对NULL进行处理。
3.分组函数中count(*)和count(具体字段)有什么区别?
在实际使用时,有可能需要对列数据进行分组,然后再对分组数据进行操作。
分组查询句式:
SELECT ... FROM ... GROUP BY ...
统计每个部门人数:
SELECT COUNT(ename) AS '人数', JOB AS '部门'FROM EMP GROUP BY JOB;
在我的理解中,group by 就是将目标列拆分为一个新表,而且将重复项去除了。
可以两个字段联合成一个字段看。
示例:每个部门不同岗位的最高薪资
SELECT deptno,job,max(sal) FROM EMP GROUP BY deptno,job;
有时候分完组之后进行操作时,需要对数据进行进一步过滤,但是在WHERE语句中又无法使用聚合函数,可以使用HAVING语句对分组都的数据进行进一步过滤,HAVING不能单独使用,必须跟在GROUP BY之后。
要求显示每个部门最大薪资大于3000的数据。
SELECT deptno,max(sal) FROM EMP GROUP BY deptno HAVING max(sal) > 3000;
在这里可以抛出一个问题,可以先将薪资大于3000的全部筛选出来,再继续进行分组。
SELECT deptno,max(sal) FROM EMP WHERE sal > 3000 GROUP BY deptno;
同样可以达到效果,因此在使用having语句前请慎重,考虑是否必须使用having,因为where条件语句执行效率比having 高,在数据量大的时候体现比较明显。
排序语句很好理解,就是对查询的数据按照升序(降序)排列。
SELECT ... FROM ... WHERE ... GROUP BY ... ORDER BY 字段名1 [ASC丨DESC] #ASC表示升序,是默认排序可以不写;DESC 降序,需要填写。
limit语句的句式很简单,但是limit语句一定要在ORDER BY 语句之后使用!!!
SELECT ... FROM ... WHERE ... GROUP BY ... ORDER BY ... LIMIT startIndex,length #startIndex是指开始下标;length指长度。
limit作用:将查询结果集的一部分取出来。通常使用在分页查询当中(当然使用limit和offset进行分页,在分页数量很多的情况下,效率比较低,作为了解)。
示例:按照薪资降序,取出排名在前5名的员工?
#第一种方式,只填写一个数字是指:默认从第一个开始往后取五个值。 SELECT ename,sal FROM EMP ORDER BY sal LIMIT 5; #第二种方式 SELECT ename,sal FROM EMP ORDER BY sal LIMIT 0,5;
接下来说一下LIMIT语句在分页中的用法。
假设,从第0也开始,每页显示3条记录。那么:
页码 | limit | 记录编号 |
---|---|---|
第1页 | limit 0,3 | [0,1,2] |
第2页 | limit 3,3 | [3,4.5] |
第3页 | limit 6,3 | [6,7,8] |
第4页 | limit 9,3 | [9,10,11] |
第5页 | limit 12,3 | [12,13,14] |
第n页 | limit (n-1)*3,3 | [(n-1)*3, (n-1)*3+1, (n-1)*3+2] |
从上表中可以总结一个规律,如果知道每页显示的记录数pagesize和页码pageno我们就可以使用LIMIT语句从数据库中读取数据,公式如下:
s
t
a
r
t
I
n
d
e
x
=
(
p
a
g
e
n
o
−
1
)
∗
p
a
g
e
s
i
z
e
startIndex = (pageno-1)*pagesize
startIndex=(pageno−1)∗pagesize
也就是说,我们只需要从前端获取记录数pagesize和页码pageno就可以进行分页操作了。
连接查询是指对多张表中的数据同时进行查询,多表的连接是关系型数据模型的主要特点,也是区别于其他类型数据库管理系统的一个标志。
根据表的连接方式分类:内连接(等值连接、非等值连接、自连接)和外连接(左外连接、右外连接)。
在进行示例之前,我先解释一下笛卡尔积现象。主要是指:在连接两张表时,不增加任何条件,则表的匹配次数等两张表行数相乘。通过笛卡尔积现象表明,尽量减少表的连接次数。
如:select name, age from namelist, agelist;这时,每一个name都会和所有age进行匹配。
如何避免笛卡尔积现象:连接时增加条件。
示例:以下是等值连接,也就是建立等式关系。
SELECT 别名1.字段1,别名2.字段2... FROM 表1 AS 别名1 JOIN 表2 AS 别名2 ON 别名1.某字段=表2.某字段
SELECT E.ename,D.dname FROM EMP AS E JOIN DEPT AS D ON E.DEPTNO=D.DEPTNO;
以上SQL语句在ON之后建立了等号条件,因此称为等值连接,而非等值连接就是建立非等号连接(如:!=,>,<,between…and…等)。
内连接之自连接:即将一张表看作两张表,相互连接。
查询员工的上级领导,要求显示员工名和对应的领导名?
SELECT E1.ename,E2.ename FROM EMP AS E1 JOIN EMP AS E2 WHERE E1.MGR = E2.EMPNO;
外联接:又分为右外连接和左外连接,其中的差异是以左表为主表还是以右表为主表,主表的内容会全部显示,右表按查询要求显示,右表无法匹配的则会用NULL填充,其实第一个示例(显示每个人所属部门),就可以使用左连接。
外连接句式:
SELECT 表1.字段,表2.字段 FROM 表1 AS 别名1 LEFT[RIGHT] JOIN 表2 AS 别名2 ON 别名1.某字段=表2.某字段
显示每个人所属的部门:
SELECT E.ename,D.dname FROM EMP AS E LEFT JOIN DEPT AS D ON E.DEPTNO=D.DEPTNO;
多表连接句式:
select ... from a join b on a和b的连接条件 join c on a和c的连接条件 right join d on a和d的连接条件
其实就是a和b 先连接,之后在和c连接,之后在和d连接。理论上讲可以实现很多表连接,但是考虑到笛卡尔积现象导致的连接效率问题,在大厂中,一般不建议使用三张表以上的表连接查询。
什么叫子查询呢?
举个例子,在SELECT语句中嵌套一个SELECT语句,被嵌套的SELECT语句称为子查询。
子查询可以出现的位置:
SELECT ..(SELECT ..).. FROM ..(SELECT).. WHERE ..(SELECT)..
在子查询中只能返回一列,并将形成的结果作为父查询的条件在主句中进一步查询。SQL语言中允许多层嵌套查询,即一个子查询中还可以有其他子查询。嵌套查询中的求解方法是由里向外处理的,即每个子查询都是在上一级查询之前求解,子查询的结果用于建立其父查讯的查找条件。
示例一WHERE子查询
找出比最低工资高的员工姓名和工资?
实现思路:
第一步:查询最低工资是多少
SELECT min(sal) FROM EMP;
第二步:找出>800的员工及对应薪资
SELECT ename,sal FROM EMP WHERE sal > 800;
第三步:合并
SELECT ename,sal FROM EMP WHERE sal > (SELECT min(sal) FROM EMP);
在WHERE子查询中,还可以包含ANY()、ALL()、EXISTS()、以及算式运算方法,这里就不多叙述了。
示例二FROM子查询:
from后面的子查询,可以将子查询的查询结果当做一张临时表。
找出每个岗位的平均工资的薪资等级。
第一步:找出每个岗位的平均工资(按照岗位分组求平均值)
SELECT job,avg(sal) FROM EMP GROUP BY job;
第二步:把以上的查询结果就当做一张真实存在的表t。
SELECT T.*,S.grade FROM (SELECT job,avg(sal) AS avgsal FROM EMP GROUP BY job) AS T LEFT JOIN SALGRADE S ON T.avgsal between S.losal AND S.hisal;
示例三SELECT子查询:
找出每个员工的部门名称,要求显示员工名,部门名?
SELECT e.ename,e.deptno,(SELECT d.dname FROM DEPT d WHERE e.deptno = d.deptno) AS dname FROM EMP e;
注意,对于select后面的子查询来说,这个子查询只能一次返回1条结果,多于1条,就报错了!
在9中,讨论过笛卡尔积现象会降低查询效率,那么在连接查询中使用ON后加入条件来缓解笛卡尔积现象,本节中介绍得UNION合并查询,也可以有效缓解查询效率低得情况。
union的效率要比连接表要高,对于表连接来说,每接一次新表,则匹配的次数满足笛卡尔积,成倍翻。
union可以减少匹配次数,在减少匹配次数的情况下,完成两个结果集的拼接。
如:
select ename,job from emp where job = 'MANAGER' union select ename from emp where job = 'SALESMAN';
select ... from ... where ... group by ... having ... order by ... limit ... 执行顺序? 1.from 2.where 3.group by 4.having 5.select 6.order by 7.limit..
约束对应的英语单词:constraint
在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的
完整性、有效性!!!
约束的作用就是为了保证:表中的数据有效!!
约束名 | 说明 |
---|---|
PRIMARY KEY | 主键约束(添加该约束得字段,主键值是每一行得唯一标识) |
FOREIGN KEY | 外键约束 |
NOT NULL | 非空约束 |
UNIQUE | 唯一性约束 (也就是添加该约束得字段值不能重复) |
CHECK(mysql不支持,oracle支持) | 检查约束 |
DEFAULT | 默认值约束 |
非空约束 not null;
唯一约束 unique; 单独加在字段名后表示该字段唯一,不能有重复值
如: name unique, 两个字段联合唯一:
create table linshi( id int, name varchar(255), email varchar(255), unique(name,unique) );
主键约束 primary key
主键特征:not null + unique
主键又可以分为:自然主键、业务主键
自然主键:主键值是一个自然数,和业务没关系。
业务逐渐:主键值和业务紧密关联,如:用银行卡号做主键。
auto_increment 自增;
外键约束 foreign key
foreign key(外键名) reference 父表名(主键名)
检查约束
mySQL不支持,oraclo支持。
数据库范式:数据库表的设计依据。
目的:避免表中数据的冗余,空间浪费。
第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分;
第二范式:在第一范式基础上,要求所有非主键字段完全依赖主键,不要产生部分依赖。
第三范式:在第二范式基础上,要求所有非主键字段直接依赖主键,不要产生传递依赖。
sql中表越多,连接次数越多,效率越低,笛卡尔积现象。
实际中会减少表的连接次数,来换取执行效率。
视图是一种根据查询(也就是SELECT表达式)定义得数据库对象,用于获取想要看到的得和使用的局部数据;
视图也被称为‘虚拟表’;
视图可以被用来从常规表或者其他视图中查询数据
视图有以下好处:
创建视图:
CREATE VIEW 视图名 as select * from emp;
删除视图:
DROP VIEW 视图名;
!!!对视图的增删改查会影响原表。
视图相当于简化了SQL语句,简化开发,利于维护。
本篇内容写到这里,对于MySQL的基本操作就已经描述完了,当然还有许多没有涉及的,如:事务、索引、数据库的原理等等,这些东西篇幅较大,我计划每类分为一个单独的文章去讲述,希望我的整理的东西可以对各位有一定的帮助。