MySQL 分为安装包安装和压缩包安装两种方式,区别在于压缩包安装的配置在安装包的安装过程中进行设置。
压缩包直接解压到文件夹里即可。解压完成后,在根目录下建立配置文件 my.ini。
[mysqld]
# 设置端口,默认3306
port=3306
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 允许最大连接数
max_connections=20
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8
然后设置环境变量,新建变量名 MYSQL_HOME ,值为解压目录。然后添加 %MYSQL_HOME%\bin 到 path 环境变量里:。
之后可以对 mysql 进行一些操作:
mysqld --initialize --user=mysql --console
mysqld --install
net start mysql
mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
create user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
初始化后会在 mysql 目录下生成一个 data 文件夹,即之后使用的数据库所在。如果临时密码丢失了可以删除此文件夹重新初始化。
使用安装包安装比较简单,只是一些选项需要选择:
其他的选择 next 和 是 就可以了,接下来会自动进行安装。当安装完成后会进行配置。
之后一路下路步,就会开始进行配置了。配置完成后会有连接测试,输入用户名和密码,点击 check ,会显示连接成功。之后没有什么需要配置的了,一路 next 就行。
net stop mysql
SC delete mysql
或使用
mysqld -remove MySQL
HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Eventlog/Applications/MySQL
HKEY_LOCAL_MACHINE/SYSTEM/ControlSet002/Services/Eventlog/Applications/MySQL
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog/Applications/MySQL
MySQL 的图形管理工具还是挺多的,推荐使用 Navicat、SQLyog、phpMyAdmin
DDL (Data Definition Language) 是数据定义语言,该语言主要包含对数据库、表结构的常用操作,用来修改表结构。
| SQL命令 | 功能 | 举例 |
|---|---|---|
| show databases | 查看所有数据库 | |
| create database | 创建数据库 | create database [if not exists] mydb1 [charset=utf8] |
| use | 切换(选择要操作的)数据库 | use mydb1 |
| drop database | 删除数据库 | drop database[if exists] mydb1 |
| alter database character | 修改数据库编码 | alter database mydb1 character set utf8 |
create table [if not exists] 表名(
字段名1 类型[(宽度)] [约束条件] [comment '字段说明'],
字段名2 类型[(宽度)] [约束条件] [comment '字段说明'],
字段名3 类型[(宽度)] [约束条件] [comment '字段说明']
) [表的一些设置];
show tables;
show create table 表名;
desc 表名;
drop table 表名;
alter table 表名 add 列名 类型(长度) [约束];
alter table 表名 change 旧列名 新列名 类型(长度) [约束];
alter table 表名 modify 列名 数据类型 [约束];
rename table 表名 to 新表名;
数据类型大致有三大类:数值类型、日期和时间类型、字符串类型
定义数值类型时,默认定义为有符号。如果在数据类型后添加 UNSIGNED 则声明为无符号数据类型。
| 类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
|---|---|---|---|---|
| TINYINT | 1 byte | (-128,127) | (0,255) | 小整数值 |
| SMALLINT | 2 bytes | (-32768,32767) | (0,65535) | 大整数值 |
| SMEDIUMINT | 3 bytes | (-838608,838607) | (0,16777215) | 大整数值 |
| INT或INTEGER | 4 bytes | (-2147483648,2147483647) | (0,4294967295) | 大整数值 |
| BIGINT | 8 bytes | (-9223372036854775808,0223372036854775807) | (0,18446744073709551615) | 极大整数值 |
| FLOAT | 4 bytes | - | - | 单精度浮点数值 |
| DOUBLE | 8 bytes | - | - | 双精度浮点数值 |
| 类型 | 大小 | 用途 |
|---|---|---|
| CHAR | 0-255 bytes | 定长字符串 |
| VARCHAR | 0-65535 bytes | 变长字符串 |
| TINYBLOB | 0-255 bytes | 不超过255个字符的二进制字符串 |
| TINYTEXT | 0-255 bytes | 短文本字符串 |
| BOLB | 0-65535bytes | 二进制形式的长文本数据 |
| TEXT0-65535 bytes | 长文本数据 | |
| LONGBLOB | 0-4294967295 bytes | 二进制形式的极大文本数据 |
| LONGTEXT | 0-4294967295 bytes | 极大文本数据 |
| 类型 | 大小 | 范围 | 格式 | 用途 |
|---|---|---|---|---|
| DATE | 3 | 1000-01-01 / 9999-12-31 | YYYY-MM-DD | 日期值 |
| TIME | 3 | ‘-838:59:59’ / ‘838:59:59’ | hh:mm:ss | 时间值或持续时间 |
| YEAR | 1 | 1901 / 2155 | YYYY | 年份值 |
| DATETIME | 8 | 1000-01-01 00:00:00 / 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
| TIMESTAMP | 4 | 1970-01-01 00:00:00 / 2038-01-19 03:14:07 | YYYYMMDD HHMMSS | 时间戳 |
DML(Data Manipulation Language) 数据操作语言,用来对数据库中表的数据记录进行操作,主要就是增、删、改。
数据插入使用 insert ,有两种写法:
// 向某些列插入数据
insert into 表名 (列名1, 列名2, 列名3 ...) values (值1, 值2, 值3 ...);
// 向所有列插入数据
insert into 表名 values (值1, 值2, 值3 ...);
数据删除使用 delete
// delete 只删除数据内容
delete from 表名 [where 条件];
// truncate 用于清空表,包含表结构信息
truncate table 表名
truncate 表名
数据修改使用 update,如果不加条件,则是修改所有数据
update 表名 set 字段名=值, 字段名=值...;
update 表名 set 字段名=值, 字段名=值... where 条件;
约束(constraint) 实际上就是表中数据的限制条件,其目的是为了保证表中的记录完整性和有效性,比如某些列不为空或不能重复等。
约束的分类有:
字段名 字段类型 primary key,
或
primary key (字段名1, 字段名2 ...)
create table 表名 (
字段名 数据类型 primary key auto_increment,
字段名 数据类型
)auto_increment=初始值;
或
alter table 表名 auto_increment=初始值;
字段名 数据类型 not null;
或
alter table 表名 modify 字段名 数据类型 not null;
字段名 数据类型 unique;
或
alter table 表名 add constraint 约束名 unique 列名;
字段名 数据类型 default 默认值;
或
alter table 表名 modify 列名 类型 default 默认值;
字段名 数据类型 zerofill
-- 创建表时,在约束部分写入外键约束
[constraint <外键名>] foreign key 字段名 [, 字段名 ...] references <主表名> 主键列 [, 主键列 ...];
-- 通过修改表的方式添加外键约束
alter table 从表名 add constraint 外键名 foreign key 字段名 references 主表名 主键列;
DQL(Data Quary Language) 就是查询操作,其语法格式为
select
[all|distinct]
<目的列表达式1> [别名],
<目的列表达式2> [别名]...
from
<表名或视图名1> [别名],
<表名或视图名2> [别名]...
[where <条件表达式>]
[group by <列名> [having <条件表达式>]]
[order by <列名> [asc|desc]]
[limit <数字或者列表>];
可以简化为
select *| 列名 from 表名 where 条件;
select * from 表名;
select 列名1, 列名2 from 表名;
select * from 表名 as 表别名;
select 列名 as 列别名 from 表名;
select distinct 列名 from 表名;
select 列名1, 列名2, 列运算表达式 from 表名;
| 运算符 | 说明 |
|---|---|
| + | 加 |
| - | 减 |
| * | 乘 |
| / 或 DIV | 除 |
| % 或 MOD | 模,求余 |
| 运算符 | 说明 |
|---|---|
| = | 等于 |
| < 、<= 、>、>= | 小于、小于等于、大于、大于等于 |
| <=> | 安全等于,两个操作码均为 NULL时,其所得值为1,而当一个操作码为NULL时,其所得值为0 |
| <> 或 != | 不等于 |
| IS NULL 或 ISNULL | 判断一个值是否为NULL |
| IS NOT NULL | 判断一个值是否不为NULL |
| LEAST | 当有两个或多个参数时,返回最小值 |
| GREATEST | 当有两个或多个参数时,返回最大值 |
| BETWEEN AND | 判断一个值是否在两个值之间 |
| IN | 判断一个值是否属于列表中的任意一个 |
| NOT IN | 判断一个值是否不属于列表 |
| LIKE | 通配符匹配 |
| ERGEXP | 正则表达式匹配 |
| 通配符 | 说明 |
|---|---|
| % | 匹配任意字符 |
| _ | 匹配单个字符 |
| 运算符 | 说明 |
|---|---|
| NOT 或 ! | 逻辑非 |
| AND 或 && | 逻辑与 |
| OR 或 || | 逻辑或 |
| XOR | 逻辑异或 |
| 运算符 | 说明 |
|---|---|
| | | 按位或 |
| & | 按位与 |
| ^ | 按位异或 |
| << | 按位左移 |
| >> | 按位右移 |
| ~ | 按位取反 |
通过运算符,可以将需要查询的条件写在查询语句的 where 后面,以获取各种需要的数据。
可以使用 SQL 语法中的 order by 来设定根据哪个字段进行排序,asc 代表升序,desc 代表降序,默认升序。
select
字段1, 字段2, ...
from 表
order by 字段1 [asc|desc], 字段2 [asc|desc] ...;
聚合查询是对某一列数据进行处理,返回一个单一的值。需注意的是聚合函数会忽略空值。
| 聚合函数 | 说明 |
|---|---|
| count() | 统计指定列不为NULL的记录行数 |
| sum() | 计算指定列的数值和,如果类型不是数值类型,则结果为0 |
| max() | 计算指定列的最大值,如果类型是字符串类型,那么使用字符串排序运算 |
| min() | 计算指定列的最小值,如果类型是字符串类型,那么使用字符串排序运算 |
| avg() | 计算指定列的平均值,如果类型不是数值类型,则结果为0 |
分组查询是指使用 group by 对查询信息进行分类
select 字段1, 字段2, ... from 表名 group by 分组字段 having 分组条件;
需注意的是,分组字段可以是多个字段。如果是多个字段,则必须所有字段的值相同才分到同一组。
如果查询结果太多,则可以使用 limit 进行分页
-- 显示前 n 条查询结果
select 字段1, 字段2, ... from 表名 limit n;
-- 分页显示,从第 m 条索引开始,查询 n 条数据,注意 m 是索引号,即从 0 开始计算。
-- 如果按页查询,m 的计算方式为 (页码 - 1) * 每页大小,n 就是每页大小
select 字段1, 字段2, ... from 表名 limit m,n;
有时候需要将查询结果导入到另一张表,可以使用 INSERT INTO SELECT 语句
-- 将表1的查询结果(也可以是整个表)插入到表2
insert into 表2名[(字段1, 字段2, ...)] select 字段1, 字段2, ... from 表1名
需要注意的是,插入表必须存在,相应字段及字段类型必须一致。
关系数据库中,多个表可以通过一些相同的字段或关系进行关联。这些关系主要分为一对一关系、一对多/多对一关系、多对多关系。关系的确定由主键和外键负责。
两个表中,一个表添加唯一外键指向另一方的主键,确保双方数据能够一对一的相互对应,就是一对一关系。实际运用中一对一关系很少见,一般遇到时最好是合并表。
在两个表中,数据多的一方建立外键,指向一的一方的主键,就是一对多或多对一关系。简单说就是数据少的表中数据都能和另一个表中若干条数据进行对应关联。
多对多的关系需要借助第三张表。通过中间表能够将多对多的关系拆成一对多的关系。中间表至少要有两个外键,分别指向原来两个表的主键。
在外键约束下,多个关系表数据操作需要注意的有:
可以通过删除外键约束取消多表的关系
alter table <从表名> drop froeign key <外键约束名>;
多表查询就是同时查询两个或连个以上的表。
交叉连接查询会产生笛卡尔积(即将两张表的数据相乘,会产生大量冗余),所以一般不使用。
select * from 表A, 表B;
内连接查询结果是两表的交集,即属于表A且属于表B。
select * from A inner join B on 条件;
外连接查询又分为左外连接、右外连接、满外连接三种情况。对于左右外连接查询,如果没有满足查询的条件并不是不返回而是根据左或右表将不满足条件的值全部填为 NULL。
select * from A left outer join B on 条件;
select * from A right outer join B on 条件;
-- 使用 full join 满外连接查询
select * form A full outer join B on 条件;
-- 使用 union 联合左外连接和右外连接,达到查询并集的目的
-- union 是将两个查询结果上下拼接并去重,union all 则不进行去重操作
select * from A left outer join B on 条件
union [all]
select * from A right outer join B on 条件;
子查询就是 select 的嵌套,即在上一步查询结果的基础上再次进行查询。大部分子查询可以使用关联查询替代,而关联查询的效率会高出子查询。
-- 查询条件基于另一个查询语句,例如
select * from 表 where 字段 = (select max(字段) from 表);
-- ALL|ANY 关键字格式
select * from 表 where 字段 运算符 all|any (查询条件);
-- IN 关键字格式
select * from 表 where 字段 in (查询条件);
-- EXISTS 关键字格式
select * from 表 where exists (查询条件);
子查询除了使用像是上例中的等号等运算符外,还可以使用一些关键字,达到更巧妙的查询目的。
| 关键字 | 说明 | 备注 |
|---|---|---|
| ALL | all 后添加查询条件,表示需要同全部查询子集进行比较并满足条件 | where c > all(查询语句) 等价于 where c > 查询结果1 and c > 查询结果2 |
| ANY(SOME) | any 后添加查询条件,表示同全部查询子集进行比较,满足任一即可 | ANY 类似于 ALL ,区别在于 ALL 对于结果判定是且的关系,而ANY是或 |
| IN | in 后添加查询条件,表示包含在查询子集之中 | 在 in 之前加上 not 可以将条件反过来 |
| EXISTS | exists 后添加查询条件,如果查询子集中有数据结果则为 true,执行外层查询,否则相反 | exists 关键字的运算效率高于其他关键字 |
将一张表自己和自己关联起来,当成多张表使用就是自关联。注意自关联时必须给表起别名。
select 字段列表 from 表1 as 别名1 join 表1 as 别名2 on 条件;
表自关联常用在树状图的数据库记录上。一般树状图的数据记录有3个字段:编号、节点名称、上级编号。如果通过这种表来查询节点和节点上级的关系,则可以使用自关联。
select * from 表1 as a left join 表1 as b on a.parent_id = b.id
MySQL 的函数主要分为六类:聚合函数、数学函数、字符串函数、日期函数、控制流函数、窗口函数
常用的聚合函数除了聚合查询中的5种外,还有 group_concat()。
此函数首先根据指定的列进行分组,并且用分隔符分割,将同一分组中的值连接起来,返回一个结果。即将符合条件的分组列转为行返回。
group_concat([distinct] 字段名 [order by 排序字段 asc|desc] [sepatator '分隔符'])
常用的数学函数有
| 函数名 | 描述 | 备注 |
|---|---|---|
| abs(x) | 返回x的绝对值 | select abs(-1) – 返回1 |
| ceil(x) | 返回大于或等于x的最小整数 | select ceil(1.5) – 返回2 |
| floor(x) | 返回小于或等于x的最大整数 | select floor(1.5) – 返回1 |
| greatest(expr1,expr2,…) | 返回列表中最大值 | 类似于 max() |
| least(expr1,expr2,…) | 返回列表中的最小值 | 类似于 min() |
| max(expression) | 返回字段中的最大值 | 类似于greatest() |
| min(expression) | 返回字段中的最小值 | 类似于least() |
| mod(x,y) | 取余数 | select mod(5,2) – 返回1 |
| pi() | 返回圆周率 | select pi() – 返回3.141593 |
| power(x,y) | 求x的y次方 | select power(2,3) – 返回8 |
| rand() | 返回0-1之间的一个随机数 | select rand() – 返回随机数 |
| round(x) | 返回四舍五入后的整数 | select round(1.2345) – 返回1 |
| round(x,y) | 返回x四舍五入后保留y位的小数 | select round(1.2345,3) --返回1.235 |
| truncate(x,y) | 返回x不进行四舍五入保留y位小数的值 | select truncate(1.23456,3) – 返回1.234 |
| 函数名 | 描述 |
|---|---|
| lenth(s) | 返回字符串的字节长度 |
| char_length(s) / character_length(s) | 返回字符串的字符数量 |
| concat(s1,s2,…sn) | 将多个字符串合并为一个字符串 |
| concat_ws(x,s1,s2,…sn) | 同concat()函数,区别在于使用x分隔,x也可以是分隔符 |
| field(s,s1,s2,…) | 返回字符串s在字符串列表(s1,s2,…)中第一次出现的位置 |
| ltrim(s) / rtrim(s) / trim(s) | 返回去掉开始/结尾/两端处空格的字符串s |
| mid(s,n,len) / substring(s,n,len) | 从字符串s的n位置处截取长度为len的字符串并返回 |
| position(s1 in s) | 从字符串s中获取s1第一次出现的位置 |
| replace(s,s1,s2) | 将字符串s2替代字符串s中的字符串s1,并返回s |
| reverse(s) | 将字符串s逆序并返回 |
| right(s,n) | 返回字符串s的右数n个字符 |
| strcmp(s1,s2) | 比较两个字符串,如果 s1 = s2 则返回0,s1 > s2 返回1,s1 < s2 返回 -1 |
| ucase(s) / upper(s) | 字符串转大写 |
| lcase(s) / lower(s) | 字符串转小写 |
| 函数名 | 描述 |
|---|---|
| unix_timestamp() | 返回时间戳 |
| unix_timestamp(date_string) | 将指定日期转为时间戳 |
| from_unixtime(unixtime[,string format]) | 将时间戳转为指定格式日期 |
| curdate() / current_date() | 返回当前日期 |
| curtime() / current_time() | 返回当前时间 |
| current_timestamp() | 返回当前日期和时间 |
| date(expr) | 从表达式中提取日期值 |
| datediff(d1,d2) | 计算两个日期之间间隔天数 |
| timediff(t1,t2) | 计算两个时间之间间隔时间 |
| date_format(d,f) | 按表达式f的要求格式化日期d |
| str_to_date(s,f) | 将字符串s按照格式f转化为时间 |
| date_sub(date,expr) | 从日期data减去指定的时间间隔 |
| extract(type from d) | 从日期d中获取type指定的类型的值 |
| last_day(d) | 返回指定日期d的那月中的最后一天 |
| makedate(year,day-of-year) | 基于年份year和所在年中的天数序号 day-of-year 返回一个日期 |
| year(d) / month(d) / day(d) | 返回日期中的年/月/日 |
| hour(t) / minute(t) / second(t) | 返回时间中的时/分/秒 |
| quarter(d) | 返回日期d是当年的第几季度 |
| monthname(d) | 返回日期d的月份英文名称 |
| dayname(d) | 返回日期d的星期英文名称 |
| dayofweek(d) | 返回日期d是星期的第几天,以周日为每星期的第一天 |
| dayofyear(d) | 返回日期d是当年的第几天 |
| week(d) / weekofyear(d) | 计算日期d是当年的第几个星期,范围0-53 |
| weekday(d) | 计算日期d是星期几,0为周一 |
| now() | 返回当前日期和时间 |
| 函数名 | 描述 |
|---|---|
| if(expr,v1,v2) | 如果表达式expr成立返回v1,否则返回v2 |
| ifnull(v1,v2) | 如果v1不为空则返回v1,否则返回v2 |
| isnull(expr) | 返回判断表达式是否为null |
| nullif(expr1,expr2) | 比较两个表达式,如果相等返回null,否则返回expr1 |
流控制函数还包括 case when 语句。case 是函数开始,end 表示结束。如果某一条件成立,执行其结果,后面其他的就不执行了。
select case expression
when condition1 then result1
when condition2 then result2
...
else result
end
窗口函数又称开窗函数,是新版中增加的一大特点。其语法结构如下:
窗口函数名 (expr) over (
partition by ...
order by ...
frame_clause
)
其中参数 expr 有些函数不需要。over子句包含三个选项:
视图是一个虚拟的表,其本质是根据 SQL 语句获取动态的数据集,并为其命名。使用时只需使用视图名,可以当作表来用。
创建视图的语法为:
create [ or replace] [algorithm = { undefined | merge | temptable }]
view view_name [(column_list)]
as select_statement
[with [cascaded | local] check option];
参数说明:
alter view 视图名 as 查询语句;
视图中的行和基表中的行之间如果具有一对一的关系,则可以通过更新视图来更新基表。如果视图包含以下结构中的任何一种,那么它就不可更新:
需要注意的是,视图虽然可以更新数据,但是有很多限制。一般情况下,最好将视图作为查询数据的虚拟表,而不要通过视图更新数据。
-- 重命名视图
rename table 视图名 to 新视图名;
-- 删除视图
drop view [if exists] 视图名;
删除视图时,只删除视图的定义,不删除数据。
存储过程简单的说就是一组语句集,可以实现一些比较复杂的逻辑功能,类似于函数、方法,是SQL语言层面的代码封装与重用。
触发器是一种特殊的存储过程,当执行 DML 操作时能够自动触发触发器的执行,无需手动调用。触发器的这种特性可以协助应用在数据库端确保数据的完整性、日志记录、数据校验等操作。
索引是通过某种算法,构建出一个数据模型,用于快速找出在某个列中有特定值的行,能够节省大量时间和资源。