[toc]
## 安装
> [官方下载地址](http://www.jb51.net/article/96898.htm)
>
> [安装注意事项](http://www.jb51.net/article/96898.htm)
## 数据库的基本概念
### 实体
只要是在客观世界存在的、可以被描述出来的都是实体
### 数据库
数据库就是数据的仓库,可以存放结构化的数据
### 数据库管理系统(DBMS)
是一种系统软件,提供操作数据库的环境,可以通过数据库管理系统对数据进行插入、修改、删除和查询等操作。
### SQL
结构化查询语言 专门用来和数据库进行交流的语言,几乎所有的DBMS都支持SQ
![](http://img.zhufengpeixun.cn/dbmspng.png)
#### SQL规范
- SQL语句不区分大小写,建议SQL关键字大写,表名和列表小写
- 命令用分号结尾
- 命令可以缩进和换行,一种类型的关键字放在一行
- 可以写单行和多行注释 , #和--是单行注释,/*/多行注释
#### SQL组成
##### DDL(data definition language)
是数据定义语言。
主要的命令有`CREATE`、`ALTER`、`DROP`等,**DDL**主要是用在定义或改变(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用。
##### DML(data manipulation language)
manipulation:.操纵;操作;处理;篡改
是数据库操纵语言
它们是`SELECT`、`UPDATE`、`INSERT`、`DELETE`,就像它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言。
##### DCL(DataControlLanguage)
是数据库控制语言
是用来设置或更改数据库用户或角色权限的语句,包括(`grant`、`revoke`等)语句
#### SQL运算符
是一种符号,它是用来进行列间或则变量之间的比较和数学运算的。
##### 算数运算符
`+,-,*,/,%`
![](https://box.kancloud.cn/cc799286b016247bb3a9215ad2e8fc31_347x286.png)
**不能**直接将姓和名相加
![](https://box.kancloud.cn/1e843425962fb2edf889a09bd184ac96_522x247.png)
需要使用内置函数
![](https://box.kancloud.cn/e6fa109f052f2b8f0b5bbb28ad1419c7_659x161.png)
##### 逻辑运算符 与 比较运算符
`AND`,`OR`,`NOT`
and
```
SELECT * FROM users WHERE age > 10 AND age < 80;
```
or
```
SELECT * FROM users WHERE age < 10 OR age > 80;
```
not
```
SELECT * FROM users WHERE NOT(age < 10 OR age > 80);
```
between 闭区间,包括30和50
```
SELECT * FROM users WHERE age BETWEEN 30 AND 50
```
枚举 30或则80岁
```
SELECT * FROM users WHERE age in (30,80);
```
## 数据表
- 表是数据库中包含所有数据的数据库对象,也是其它对象的基础。
- 表定义是一个列的集合,数据在表中是按行和列的格式组织的,用来存放数据
- 行也称为记录用来存放一个个实体,列称为字段用来描述实体的某一个属性
![](http://img.zhufengpeixun.cn/table.png)
## MYSQL配置
C:\Program Files\MySQL\MySQL Server 5.5\my.ini
- port 端口号
- basedir 安装目录
- datadir 数据存放访目录(不是数据库系统的的存放目录)
- charcter-set-server 字符集
- default-storage-engine 存储引擎
- sql-mode 语法模式
- max-connections 最大连接数
## MySQL启动和停止
```
net start MySQL
net stop MySQL
```
以配置文件启动
```
C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld" --defaults-file="C:\Program Files\MySQL\MySQL Server 5.5\my.ini"
```
## 连接服务器
```
mysql -h 127.0.0.1 -P 3306 -uroot -p123456
exit
```
## 数据库操作
### 切换数据库
```
use test;
```
### 显示有哪些表
```
show tables;
show tables from mysql;
```
### 显示当前数据库
```
select database();
```
## 表操作
### 查询表结构
```
desc user;
```
### 创建表
![](https://box.kancloud.cn/fc1d789d381e91feb31140e1ef0abb6c_340x299.png)
```
//1 3 代表初始值为1 步长为3
CREATE TABLE student(
id init(11) NOT NULL PRIMARY KEY AUTO_INCREMENT 1 3,
name varchar(50) NOT NULL,
age init(11),
city varchar(50) DEFAULT '北京'
)
```
#### 设置主键
![](https://box.kancloud.cn/704bf0ba33cd9beff55ef9b5aa709a0d_402x316.png)
#### 设置联合主键
### 查询
```
SELECT * FROM student;
SELECT name,age FROM student;
```
```
SELECT <列名>
FROM <表名>
[WHERE <查询条件表达式>]
[ORDER BY <排序的列名>[ASC或DESC]]
```
虽然有些参数是可选的 但顺序是固定的,order不能在where前面
可以给列名自定义名字
![](https://box.kancloud.cn/c06431d7da5d39feefc55ff142723a3b_474x450.png)
增加一列固定值
![](https://box.kancloud.cn/9f92cc90c9d4a6f29c8914c7a2584965_721x262.png)
分页 `LIMIT skip_num,page_size`
![](https://box.kancloud.cn/3e5a4e37f9da8c1628f284182db6baf5_440x267.png)
`DISTINCT` 取样
```
SELECT DISTINCT home FROM users
```
`ORDER BY`可以指定多个条件,先按第一个条件排,在第一个的基础上再按第二个条件排
![](https://box.kancloud.cn/66b7717fdff4de89520326995c43c1f3_452x332.png)
### 修改表
#### 增加一列
```
ALTER TABLE student ADD COLUMN idcard varchar(15) NOT NULL;
```
#### 修改字段
```
ALTER TABLE student MODIFY COLUMN idcard varchar(18) NOT NULL;
```
#### 删除列
```
ALTER TABLE student DROP COLUMN idcard varchar(18) NOT NULL;
```
#### 添加主键索引
```
ALTER TABLE student ADD PRIMARY KEY(id);
```
#### 添加唯一索引
```
ALTER TABLE student ADD UNIQUE INDEX unique_idcard(idcard)
```
给`idcard`字段添加了一个名为`unique_idcard`的唯一索引。
#### 添加外键索引
constraint: 约束;局促,态度不自然;强制
```
ALTER TABLE score ADD CONSTRAINT fk_student_id FOREIGN KEY(student_id) REFERENCE student(id)
```
其中`student_id`为`score`表中的键,它是个子键,被主表(student)的`id`主键所约束。
这意味着student中的id有什么,score表中的student_id才允许有什么,比如说student有id:1、2、3,那么score表中的student_id也顶多只能有1、2、3
另外要删除表时,必须先删除子表才能删除主表。
### 插入
```
INSERT INTO users(firstname,lastname,email,age,birthday) VALUES('张','三','123@qq.com',100,'1984-12-30');
```
- 插入的字段要与你`INTO xx()`选择的字段一一对应
- 不指定字段时,`INTO xx()`相当于全字段
![](https://box.kancloud.cn/b35cf83ca4151b715524638e60da689b_661x235.png)
- 必须要有,即使用null占位,如果是null且对应id会自动生成
#### 其它注意事项
- 每次插入一行数据,不能只插入一部分数据,插入的数据是否有效将按照整行的完整性要求来检验
- 每个数据值的数据类型、精度、位数必须与要应的列名精确匹配
- 不能为标识符指定值
- 如果某字段设置为不能为空,则必须插入数据
- 插入数据时还要符合检查性约束的要求
- 有缺省值的列,可以使用DEFAULT关键字来代替插入实际的值
### 更新
默认会全部更新? So,需要搭配`where`
```
UPDATE users SET home = '上海',birthday='xxx' WHERE id = 6;
```
#### 注意事项
- 多列时用逗号隔开,一定要加更新条件以免错误更新
- 多个联合条件使用 AND `id=7 and idcard='1231'`
- 判断某字段是否为空 `email is null or email =`
![](https://box.kancloud.cn/540b68f7e9a922b8ac69cc1fd0c27b6f_269x65.png)
![](https://box.kancloud.cn/35de033035a95ff3cbcb9d3b63296f70_301x65.png)
### 删除
```
DELETE [FROM] 表名 [WHERE <删除条件>]
```
```
DELETE FROM student WHERE id=7;
```
#### 注意事项
- Delete语句是对整行进行操作,因此不需要提供列名
- 如果要删除主表数据,则要先删除子表记录
### TRUNCATE 截断表
截断整个表中的数据
```
TRUNCATE TABLE 表名
```
和`DELETE`还有一点重要的区别在于会让`id`的计数器重新开始计数。(无法再通过MySQL恢复,delete会有日志,尽量在生产环境中不要使用这个命令)
### 删除表
```
DROP TABLE student
```
## 数据完整性
- 为了实现数据完整性,需要检验数据库表中的每行和每列数据是否符合要求
- 在创建表的时候,应该保证以后的数据输入是正确的,错误的数据不允许输入
### 域完整性
不同的字段需要设置为各种合适的类型,比如年龄就是整数类型
![](http://img.zhufengpeixun.cn/datatype.jpg)
(mysql支持的所有数据类型)
varchar(n),长度不能大于n,大于n会报错,小于n放几个字符就是几个字符
char(n)则是即使你只有一个字符,也会占用50个字符的空间
### 默认值
默认值是指如果用户没有指定值的情况下会记录的此字段指定一个提供一个预先设定的值
![](https://box.kancloud.cn/c63a1775f969a7e4718482d9b8de4d7c_548x377.png)
### 非空约束
我们可以指定某个字段不能不输入,必须提供一个非空的值
![](https://box.kancloud.cn/242953f8fd520b28d399efa4c6015b81_507x112.png)
## 实体完整性
### 主键约束
#### 主键
表中一列或者几列组合的值能用来唯一标识表中的每一行,这样的列或者列组合称为表的主键,主键表的数据不能重复。
>主键的选择标准
- 最少性 尽量选择单个键作为主键
- 稳定性 ,由于主键是用来在两个表间建立联接的,所以不能经常更新,最好就不更新
### 外键
成绩表中的学生ID应该在学生表中是存在的 我们应该让成绩表中的ID只能引用学生表中的ID,它们的值应该是一一对应的,也就是说成绩表中的ID是成绩表中的外键,对应学生表的主键 ,这样就可以保证数据的引用完整性
### 唯一索引
唯一约束是指某个字段值是唯一的,在所有的记录中不能有重复的值.
![](https://box.kancloud.cn/01a068bf355b769d992ce692cd512b88_457x135.png)
索引名字随便取
### 标识列
标识列,即id,用来标识每一条数据
当表中没有合适的列作为主键时可以考虑增加标识列,标识列是一个无实际业务含义的列,仅仅用来区分每条记录。
标识列的值是自动生成的,不能在该列上输入数据
>思考: 如果标识列id的初始值为1,增长量为3,则输入3行数据以后,再删除1行,下次再输入数据行的时候,标识值自动插入的值是多少? //->4 不会回收利用
### 外键约束
一个表的外键必须引用另一个表的主键,比如成绩表中的学生ID会引用学生表的主键,课程ID会引用成绩表的主键
- 主表没有记录,子表中不能添加相应的记录
- 修改和删除主表记录不能让子表记录孤立,必须相应修改和删除
- 数据操作 8.1 创建学生表
![](https://box.kancloud.cn/3739470aa82d5b66bdb592ff055c0741_612x199.png)
(fk,foreign key的意思,不是固定的随便取)
另外要删除表时,必须先删除子表才能删除主表。
## 函数
函数不仅在`select`能用,在哪都可以用
### length()
![](https://box.kancloud.cn/3a4d5902820d7e87c9392e5fc3fa5244_411x226.png)
### upper/lower()
### substr()
第一种和第二种是等价的,第是哪个参数为截取的长度
![](https://box.kancloud.cn/4b2e385202842b4ebcff1e20fcc6a7bb_464x106.png)
### INSTR()
相当于indexOf
```
SELECT INSTR(email,'@') FROM student;
```
### LPAD/RPAD
等同于padsStartsWith
```
SELECT LPAD('ahh',10,'0')
```
### replace
```
SELECT REPPLACE('ahhh','a','A'); //->Ahhh
```
### round
### ceil
### floor
### truncate
不管怎样,一律舍去
```
SELECT TRUNCATE(2.668,2); //->2.66
```
### mod
取余
```
SELECT MOD(-10,3); //->-1
```
### now
返回当前事件,年月日时分秒
![](https://box.kancloud.cn/69fa1e580c61640466033dd093173049_250x171.png)
### curdate
年月日
### curtime
时分秒
### year(now())
年
### month(now())
### day(now())
### hour(now())
### minute(now())
### second(now())
### str_to_date()
```
str_to_date('2018-09-03 10-20-16','%m-%d-%Y $s-$i-$H')
```
| 序号 |格式符 |功能 |
| --- | --- | --- |
|1 | %Y |4位的年份 |
| 2 | %y |2位的年份 |
| 3|%m |月份(01,02) |
|4 |%c |月份(1,2) |
| 5 | %d |日(01,02) |
| 6 |%H |小时(24小时制) |
| 7 |%h |小时(12小时制) |
| 8| %i |分钟(00,01) |
| 9 | %s |秒(00,01) |
![](https://box.kancloud.cn/2c285b74536e85045f00c6cdbc4ca620_405x69.png)
### version()
数据库版本 ->5.6.0推荐
### database()
返回当前数据库
### FORMAT(1000.111,n)
保留n位小数
![](https://box.kancloud.cn/50a407a7d62f286a73ded3fa3e949910_558x307.png)
### LEFT/RIGHT
![](https://box.kancloud.cn/c6206c01dc63c957a53421d4bd1cc998_507x234.png)
### 数学函数
### 日期函数
![](https://box.kancloud.cn/4b206e6b5543fc317669c853e82a58ee_659x133.png)
### connection_id();
### user
![](https://box.kancloud.cn/4c6399a376d5fd87f8aafb906f7b3c16_371x123.png)
### 其它函数
```
SELECT CONNECTION_ID();
SELECT DATABASE();
SELECT VERSION();
select LAST_INSERT_ID();
SELECT USER();
SELECT MD5('123456');//摘要算法
SELECT PASSWORD('123456');//修改当前用户的密码
SELECT User,Password from mysql.user;
```
### 流程控制函数
mysql中相等是一个等号
if
```
//类似于三元
SELECT IF(gender=1,'男','女') FROM student;
```
case
```
CASE
WHEN 常量1 then 要显示的值或语句1
WHEN 常量2 then 要显示的值或语句2
ELSE 要显示的值
END
SELECT
CASE
WHEN grade<60 then '不及格'
WHEN grade>=60 then '及格'
ELSE '未知'
END
FROM score;
```
当`case`后面根了个变量时,when后只能放常量,但如果`case`后没有东西,那么when后就可以带上变量
![](https://box.kancloud.cn/eb7d0fe28adcfb99fb6dafc7138b77f1_483x428.png)
### 自定义函数
只有返回值的话 可以不用大括号直接放函数体
case1
```
CREATE FUNCTION znow() RETURNS VARCHAR(30)
RETURN DATE_FORMAT(NOW(),'%Y年%m月%d日 %H点:%i分:s秒');
SELECT znow1();
```
case2
```
CREATE FUNCTION zadd(num1 INT,num2 INT) RETURNS INT
RETURN num1+num2;
SELECT zadd1(1,2);
```
case3
有两个语句必须要包一下,用的是`BEGIN`和`END`
```
CREATE TABLE stu(id int PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50));
CREATE FUNCTION addUser(name VARCHAR(50)) RETURNS INT
BEGIN
INSERT INTO stu(name) VALUES(name);
RETURN LAST_INSERT_ID();
END
SELECT addUser('zfpx');
DROP FUNCTION addUser
```
## 模糊查询
就是查询的条件是模糊的,不是特别明确的
### 通配符
![](http://img.zhufengpeixun.cn/matchchar.png)
### BETWEEN AND
```
select * from score where grade between 80 and 100
```
### IN
```
select * from student where city in ('北京','上海','广东')
```
### IS NUL
- 查询没有邮箱的 IS NUL
- 查询有邮箱的 IS NOT NULL