文章目录
安装
特别说明
如果安装过Mysql过程中,出错了或者想重新再来一把
sc delete mysql 【删除已经安装好的mysql服务 慎重】
-
下载完成后,解压(最好不要有中文和空格)
-
添加环境变量
-
自己创建my.ini文件
[client]
port=3306
default-character-set=utf8
[mysqld]设置为自己MYSQL的安装目录
basedir=D:\program\mysql-5.7.19-winx64
设置为MYSQL的数据目录
datadir=D:\program\mysql-5.7.19-winx64\data
port=3306
character_set_server=utf8
#跳过安全检查
skip-grant-tables -
管理员身份打开cmd,然后修改到mysql的安装目录,输入以下内容
PS D:\program\mysql-5.7.19-winx64\bin> mysqld -install
Service successfully installed. -
初始化数据库
mysqld --initialize-insecure --user=mysql
-
启动mysql服务
net start mysql
关闭的命令是net stop mysql
-
登录mysql管理员
mysql -u root -p
-
修改root密码
mysql
mysql> use mysql;
Database changed
mysql> update user set authentication_string=password('yb0os1') where user='root' and Host='localhost';
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
mysql> flush privileges;#刷新权限
Query OK, 0 rows affected (0.01 sec)
-
修改my.ini
#skip-grant-tables
,再次进入就会进行权限验证了 -
命令行登录
mysql -h xxxx -P 3306 -u root -pxxxx
MySQL数据库普通表的本质依然是文件
数据库操作
创建数据库
mysql
create database [if not exists] db_name [create_specification[,create_specification]...]
#create_specification:
# character set:设置采用的字符集 默认utf8
# collate:指定数据库字符集的校对规则
# 默认utf8_general_ci 不区分大小写
# 创建一个utf8 区分大小写的表
create database test1 character set utf8 collate utf8_bin;
删除数据库
mysql
# 展示所有数据库
show databases;
# 显示数据库创建语句
show create database db_name;
# 数据库删除语句[慎重]
drop database [if exists] db_name;
备份、恢复数据库
mysql
# 备份 命令行下执行
mysqldump -u 用户名 -p -B 数据库1 ... 数据库n > 文件名.sql
# 恢复 进入mysql之后才能恢复
source 文件名.sql
数据类型
- 数值类型
- 文本、二进制类型
- 时间日期类型
使用规范:能够满足需求的情况下,尽量选择占用空间小的类型
整型
没有在后面指定unsigned
默认就是有符号
- tinyint:1B
- int:4B
- bigint:8B
bit类型
mysql
# 后面跟的数字代表位数 1-64 按照位显示的 查询时依然可以使用数来查询
create table t(num bit(8));
浮点型
- float:单精度
- double:双精度
- decimal(M,D):M是小数位数的总数,D是小数点后面的位数 M最大65 D最大30 默认 10,0
mysql
# 小数位数不够 补0 DECIMAL可以存放的数特别特别大
CREATE TABLE t(id DECIMAL(50,10));
INSERT INTO t VALUES(20.2222222);
SELECT * FROM t;
字符串
-
char:固定长度 最大255字符,char(4)即使插入'aa'也是会占用四个字符空间
-
varchar:可变长度,0-65535最大65535字节【utf8编码最大21844字符 1-3个字节用于记录大小】,所以不能填65535
- utf8 (65535-3)/3
- gbk (65535-3)/2
- varchar(4) 插入'aa'就是会占用两个字符空间,需要1-3个字节记录存放内容的长度
-
varchar(4) -> 代表四个字符,不管是字母还是中文都是可以放四个
-
如果存储的数据是定长(md5、邮编等)可以使用char,变长的varchar
-
查询速度 char>varchar
-
存储文本可以使用text
日期
- date 年月日
- time 时分秒
- datetime 年月日时分秒
- timestamp 需要配置
数据表操作
创建数据表
mysql
create table table_name(
field1 datatype,field2 datatype,...
)character set 字符集 collate 校对规则 engine 引擎
"""
field:指定列名
datatype:指定列类型 字段类型
character set:指定字符集,如果不指定默认使用数据库的
collate:校对规则,如果不指定默认使用数据库的
engine:引擎,涉及内容较多 后续专门写
"""
create table `user` (`id` INT,`username` VARCHAR(255),`password` VARCHAR(255),`birthday` date)
CHARACTER set utf8 COLLATE utf8_bin ENGINE innodb;
删除数据表
mysql
drop table table_name;
修改数据表
mysql
# 添加
alter table table_name add column datayype [dffault expr]...
# 修改
alter table table_name modify column datayype [dffault expr]...
# 删除
alter table table_name drop column
# 查看表的结构
desc table_name;
alter TABLE emp add image VARCHAR(255) ; -- 添加
alter TABLE emp MODIFY job VARCHAR(60); -- 修改
alter TABLE emp drop sex; -- 删除
rename TABLE emp to employee; -- 修改表名
alter TABLE employee CHARACTER set utf8;-- 修改字符集
ALTER TABLE employee CHANGE `name` user_name VARCHAR(32) not NULL DEFAULT ""; -- 修改列名
基础的CRUD增删改查
mysql
# 插入
insert into table_name (列名) values (对应的值)
insert into table_name values (对应的值) -- 如果所有的列都添加 可以省略列名 如果不是所有列都添加 那么要一一对应
# 更新
update tab_name set 列名=新值 [where xxx 条件] -- 如果不使用where就会更改所有
# 删除
delete from table_name [where xxx 条件] -- 如果不使用where就会删除所有
# 查找
select [distinct]col1,clo2,..|* from table_name [where xxx]
as -- 起别名 也可以进行运算
配合like
% -- 匹配零个或者多个
_ -- 匹配一个
mysql
# 排序
order by -- 排序 asc(升序 默认) desc(降序) 放在末尾
SELECT `name`,price FROM goods order by price;
-- 按照deptno升序 sal降序
SELECT * FROM emp ORDER BY deptno asc,sal desc;
# 统计函数
count(列名) -- 统计满足条件的某列有多少个,但是排除 null
count(*) -- 统计满足条件的记录的行数
SELECT count(id) FROM goods;
# 求和函数 仅对数值起作用 否则报错
sum
SELECT sum(price) from goods;
# 平均值函数 仅对数值起作用 否则报错
avg
# 合计函数 仅对数值起作用 否则报错
max / min
# group by 对列进行分组
# having 对分组后的结果进行过滤 也就是代替where 分组之后的过滤不能使用where
-- 显示每个部门的平均工资和最高工资
SELECT AVG(sal),MAX(sal),deptno FROM emp GROUP BY deptno;
-- 每个部门的每个岗位的平均工资和最高工资 按照部门分组之后再按照每个部门的工作
SELECT AVG(sal),MAX(sal),deptno,job FROM emp GROUP BY deptno,job;
-- 显示平均工资低于2000的部门号和平均工资
SELECT deptno,AVG(sal) FROM emp GROUP BY deptno HAVING avg(sal)<2000;
SELECT deptno,AVG(sal) as avg_sal FROM emp GROUP BY deptno HAVING avg_sal<2000;
# 分页查询
select ... limit start,rows -- 从start行开始 取rows行
# 书写顺序
group by、having、order by、limit
mysql中日期可以直接比较,但是格式要相同
多表查询
select * from emp,dept;
-- 第一个表的行数×第二张表的行数 --> 笛卡尔积
n个表至少要有n-1个限制条件才会正确
自连接:
- 同一张表看作为两个表
- 需要给表取别名
table_oldname table_newname
- 建议给列名取别名
mysql
SELECT worker.ename as '员工',boss.ename as '上级' FROM emp worker,emp boss WHERE worker.mgr = boss.empno;
子查询:
- 单行子查询:只返回一行数据的子查询语句
- 多行子查询:返回多行数据的子查询语句
- 子查询的临时表可以作为正常表使用
mysql
-- 单行子查询
SELECT * FROM emp WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'SMITH')
-- 多行子查询
SELECT empno,job,sal,deptno FROM emp WHERE job in (SELECT DISTINCT job FROM emp WHERE deptno=10) and deptno!=10
select goods_id,goods.cat_id,goods_name,price from (select cat_id,max(price) as max_price from goods group by cat_id)tmp,goods where tmp.cat_id=goods.cat_id and tmp.max_price = goods.price
-- all:比所有的
-- any:比其中一个
SELECT * FROM emp WHERE sal>all(SELECT sal FROM emp WHERE deptno = 30)
SELECT * FROM emp WHERE sal>any(SELECT sal FROM emp WHERE deptno = 30)
多列子查询:
- 返回多列数据的子查询语句
mysql
SELECT * FROM emp WHERE (deptno,job) = (SELECT deptno,job FROM emp WHERE ename = 'ALLEN') and ename!='ALLEN'
表的自我复制、去重
mysql
insert into table_name select * from table_name;
insert into table_name(xxx) select (xxx) from table_name;
create table name1 like name2; -- 创建一个新表name1和name2的结构一样
-- 去掉表的重复内容
/*
创建一个临时表 结构相同
通过distinct插入数据到临时表
*/
CREATE TABLE tmp LIKE goods;
INSERT INTO tmp SELECT DISTINCT * FROM goods;
INSERT INTO goods SELECT * FROM tmp;
DELETE FROM tmp;
合并查询 union
mysql
union all -- 结果合并 不会去重
union -- 结果合并 去重
-- 合并列数要相同
mysql表外连接
前面我们学习的查询,是利用 where 子句对两张表或者多张表,形成的笛卡尔积进行筛选,根据关联条件,显示所有匹配的记录,四配不上的,不显示
- 左外连接:左侧的表完全显示(即使左边的表没有匹配到)
- 右外连接:右侧的表完全显示(即使右边的表没有匹配到)
MYSQL
# 语法
select xxx from table1 right/left join table2 on 条件
# on后面等同于where 是筛选条件
mysql
-- 要求显示所有的学生 显示左边所有的,右边和左边匹配的
SELECT student.id,name,grade FROM student LEFT JOIN exam ON student.id=exam.id;
SELECT student.id,name,IFNULL(grade,0) FROM student LEFT JOIN exam ON student.id=exam.id;
-- 要求显示所有的成绩 显示右边所有的,左边和右边匹配的
SELECT student.id,name,grade FROM student RIGHT JOIN exam ON student.id=exam.id;
数据库约束
主键
主键列的值不可以为空;不可以重复;一张表最多只有一个主键,但是可以复合主键(比如id+name为主键);
主键的定义
- 字段名 primary key
- 在表定义的最后 primary key(列名primary key)
- 实际开发中每个表一般都设计一个主键
mysql
create table xx(id int primary key -- 表示主键
);
# 复合主键
CREATE TABLE tab1 (id int,name VARCHAR(30),PRIMARY KEY(id,`name`));
非空和唯一
unique
- 没有指定not null,即使指定了unique也可以有多个null
- 一张表可以有多个unique
mysql
CREATE TABLE tab1 (id int UNIQUE,name VARCHAR(30)); -- id不可以重复
not null
mysql
CREATE TABLE tab1 (id int not null,name VARCHAR(30)); -- id不可以重复
两者同时存在效果等价于主键
外键
用于定义主表和从表之间的关系
- 外键指向的表的字段,必须是主键或者unique
- 表的类型是innodb,这样的表才支持外键
- 外键字段的类型要和主键字段的类型一致
- 外键字段的值必须在主键字段出现过,或者为null(前提是外键字段允许是null)
- 一旦建立主外键关系,数据就不能随意的删除了
mysql
foreign key (本表字段名) references 主表明(主键名或者unique字段名)
mysql
CREATE TABLE class (id int PRIMARY KEY,`name` VARCHAR(32));
CREATE TABLE students(stu_id int PRIMARY KEY,`name`VARCHAR(32),class_id int,
FOREIGN KEY (class_id) REFERENCES class(id));
# students表的class_id必须属于class表中存在的id,不存在的就会插入失败 id必须是主键
INSERT INTO class VALUES(100,'安全2005');
INSERT INTO students VALUES(1,'alice',100);
DELETE FROM class WHERE id=100; -- 报错,有外键指向这条记录 所以无法删除
-- 有外键的删除 也就是两个表都要被影响,那么要么都删除成功 要么都删除失败 所以使用事务
start transaction;
UPDATE class set num=num-1 where classid = (SELECT classid from sutdent where name='张三');
DELETE FROM sutdent where name = '张三';
COMMIT;
行数据约束
check 用于强制行数据必须满足的条件
mysql5.7不支持check,只做语法检验但是不生效
mysql
create table tab (id int primary key,`name` varchar(32),sex varchar(32) check(sex in ('man','woman')))
自增长
auto_increment
- 一般自增长和主键配合
- 自增长也可以单独使用 要配合unique
- 自增长修饰整型(少数浮点数)
- 自增长开始值默认为1,修改默认值
alter table 表名 auto_increment=新的开始值
- 自增长:目前表中最大的值+1
mysql
CREATE TABLE t1 (id int PRIMARY KEY auto_increment)
INSERT INTO t1 VALUES(NULL) -- 默认自增长 从1开始
函数
统计函数
如上
min max sum avg
字符串相关函数
mysql
-- CHARSET(str)返回字串字符集
SELECT CHARSET(ename) FROM emp;
-- CONCAT (string1[,...])连接字符串
SELECT CONCAT(ename,'job is ',job) from emp;
-- INSTR(string,substring) 返回substring在string的位置,没有返回0
-- dual 亚元表,系统的,可以作为测试表使用
SELECT INSTR('duyingxxx','x');
-- UCASE(string2 ) 转为大写
SELECT UCASE('duyingxxx');
-- LCASE (string2)转为小写
SELECT LCASE('dadasDADA');
-- LEFT(string,length) 在string从左边取length个
SELECT LEFT("duuuyinggg",5);
-- RIGHT(string,length) 在string从右边取length个
SELECT right("duuuyinggg",5);
-- LENGTH (string) 返回string的长度[按照字节]
SELECT length("duuuyinggg");
-- replace(str,search_str,replace_str) 替换
SELECT REPLACE("你好呀,job","job","西施")
-- STRCMP (string1,string2) 逐字节比较大小 0相等 -1小于 1大于
SELECT STRCMP('aaa','AAA')
-- SUBSTRING(str FROM pos FOR len) 截取字符串 【从1开始计算】
SELECT SUBSTR("duyingying",1,2);
-- LTRIM(str) RTRIM(str) TRIM([remstr FROM] str) 去除左边/右边/左右两边的空格
数学相关函数
mysql
-- ABS(X) 绝对值
SELECT ABS(-1)
-- BIN(N) 十进制转二进制
SELECT BIN(10)
-- CEILING(X) 向上取整
SELECT CEILING(1.1)
-- CONV(N,from_base,to_base) 进制转换
SELECT CONV(10,10,2);
-- FLOOR(X) 向下取整
SELECT FLOOR(1.1);
SELECT FLOOR(-1.1);
-- FORMAT(X,D) 保留小数位数
SELECT FORMAT(1.2222222,2);
-- HEX(N_or_S) 转为十六进制
SELECT HEX(10);
-- LEAST(value1,value2,...) 求最小值
SELECT LEAST(10,2,3,555,12,0.5);
-- MOD(N,M) 求余数
SELECT MOD(10,3);
-- RAND() 返回一个随机数 0-1.0 加入种子之后每次随机数都是一样的
SELECT RAND();
SELECT RAND(1);
时间日期相关函数
mysql
-- CURRENT_DATE 当前日期
SELECT CURRENT_DATE();
-- CURRENT_TIME 当前时间
SELECT CURRENT_TIME();
-- CURRENT_TIMESTAMP() 当前时间戳
SELECT CURRENT_TIMESTAMP();
-- YEAR(date) MONTH(date) DAY(date) DATE(expr) 返回datetime的日期部分 /年/月/日
SELECT DATE(CURRENT_TIMESTAMP);
-- DATE_ADD(date,INTERVAL expr unit) 在date中加上日期或者时间
-- 十分钟以内的新闻
-- select * from meg where date_add(send_time,INTERVAL 10 MINUTE)>=NOW();
SELECT DATE_ADD(CURRENT_TIMESTAMP,INTERVAL 10 MINUTE);
-- DATE_SUB(date,INTERVAL expr unit) 在date中减去日期或者时间
-- DATEDIFF(expr1,expr2) 两个日期差 结果是天
SELECT DATEDIFF('2011-11-11','1990-01-01');
-- TIMEDIFF(expr1,expr2) 两个时间差 结果是多少时多少分多少秒
-- NOW() 当前时间
SELECT NOW();
-- UNIX_TIMESTAMP() 返回1970-1-1到现在的秒数
SELECT UNIX_TIMESTAMP();
-- FROM_UNIXTIME(unix_timestamp) 可以把unix_timestamp秒转化为指定格式的日期
-- 意义:可以存放一个整数表示一个时间,通过该函数进行转换
SELECT FROM_UNIXTIME(unix_timestamp(),'%Y-%m-%d');
SELECT FROM_UNIXTIME(unix_timestamp(),'%Y-%m-%d %H:%i:%s');
-- 当前月份的最后一天
last_day()
加密和系统函数
mysql
-- user() 查询用户
SELECT user();
-- DATABASE() 数据库名称
SELECT DATABASE();
-- MD5(str) md5 32bit字符串
SELECT MD5('dddd');
-- PASSWORD(str)
SELECT PASSWORD('xx'); -- 加密函数 MySQL用户密码就是password函数加密
SELECT * FROM mysql.`user`;
流程控制函数
mysql
-- IF(expr1,expr2,expr3) expr1为true返回expr2 否则返回expr3
SELECT IF(1=2,'真的','假的');
SELECT IF(1=1,'真的','假的');
-- IFNULL(expr1,expr2) expr1不为null 返回expr1 否则返回expr2
SELECT IFNULL(null,0.0);
SELECT IFNULL(1,0.0);
SELECT CASE WHEN TRUE THEN 'true'
ELSE 'false'
END;
SELECT ename,IFNULL(comm,0.0) FROM emp;
SELECT ename,if(comm is null,0.0,comm) FROM emp;
SELECT ename,(SELECT CASE
WHEN job='CLERK' THEN '职员'
WHEN job='MANAGER' THEN '经理'
WHEN job='SALESMAN' THEN '销售人员'
ELSE job END)as 'job' FROM emp;
索引
使用
提高数据库性能(查找很快),索引是性价比高,索引本身会占用空间
创建一个8000000数据的数据表,然后进行查询一条数据,看需要花费多久时间
mysql
SELECT * FROM emp WHERE empno = 123456; -- 2.5s
-- 创建索引后 只对创建了索引的列有效
CREATE INDEX empno_index ON emp(empno);
SELECT * FROM emp WHERE empno = 1234567; -- 0.314s
原理
id | name | age |
---|---|---|
1 | jack | 18 |
2 | tom | 20 |
3 | bob | 19 |
当没有索引的时候,select * from emp where id=1
进行全表扫描(即使扫描到id=1的也需要继续查找,因为不确定后续是否有id=1)
创建索引会形成一个数据结构-》比如二叉树
索引的代价
- 存盘占用更大
- 对表进行修改删除插入操作,会对索引重新维护,对速度有影响
类型
- 主键索引:主键自动的为主索引
- unique索引
- 普通索引
- 全文索引 - 一般开发不适用mysql自带的全文索引,而是使用solr和es
操作
mysql
CREATE TABLE t1 (id int,`name` VARCHAR(32));
-- 创建唯一索引 id不会重复,就使用唯一索引
CREATE UNIQUE INDEX id_index ON t1(id);
-- 创建普通索引 id以后可能会重复 使用普通索引
CREATE UNIQUE INDEX id_index ON t1(id);
ALTER TABLE t1 add index id_index (id);
-- 创建主键索引
-- 直接primary key就是主键索引
ALTER TABLE t1 add index PRIMARY KEY (id);
-- 删除唯一和普通索引
drop index id_index on t1;
-- 删除主键索引
alter table t1 drop primary key;
-- 查询索引
show index from t1;
show keys from t1;
show indexes from t1;
那些列上适合创建索引?
- 较频繁的作为查询条件字段应该创建索引
- 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件 比如性别
- 更新非常频繁的字段不适合创建索引
- 不会出现在WHERE子句中字段不该创建索引
事务
概念
事务用于保证数据的一致性,它是由一组相关的dml语句组成,该组dml语句要么全部执行成功,要么全部执行失败
dml:删除 修改 插入
转账要用到事务(一方钱减少 另一方钱必须增加)
当执行事务操作时(dml语句),mysql会在表上加锁,防止其它用户改表的数据,这对用户来讲是非常重要的
重要的操作
mysql
start transaction -- 开启一个事务
savepoint 保存点名 -- 设置保存点
rollback to 保存点名 -- 回退事务 不加to就回退到事务开始
commit -- 提交事务,所有的操作生效,不能回退 自动删除所有保存点
'
使用commit语句可以提交事务.当执行了commit语句子后,会确认事务的变化、结束事务、删除保存点、释放锁,数据生效。
当使用commit语句结束事务子后,其它会话[其他连接]将可以查看到事务变化后的新数据[所有数据就正式生效.]
'
START TRANSACTION;
SAVEPOINT a;
INSERT INTO test values(1,'bob');
SAVEPOINT b;
INSERT INTO test values(2,'alice');
SELECT * FROM test;
ROLLBACK to b;
SELECT * FROM test;
ROLLBACK TO a;
SELECT * FROM test;
细节
- 如果不开始事务,默认情况下dml是自动提交的,不能回滚
- 开始一个事务,但是没有创建保存点,可以执行rollback,默认就是回到事务开始的状态
- 可以在事务(还没提交)创建多个保存点
- 在事务没有提交前可以选择回退到哪一个保存点
- innodb存储引擎支持事务,myisam不支持
- 开始一个事务:start transaction,set autocommit=off
隔离级别
定义了事务和事务之间的隔离程度
多个连接开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性。
不考虑隔离性可能引发:
- 脏读:当一个事务读取另一个事务尚未提交的修改
- 不可重复读:同一查询在同一事务中多个进行,由于其它提交事务所做的修改或删除,每次返回不同的结果集
- 幻读:同一查询在统一事务中多次进行,由于其它提交事务所做的插入操作,每次返回不同的结果集
- 加锁:一个事务还未提交,另外的事务不可以操作该表
mysql
-- 查看当前mysql隔离级别
select @@tx_isolation;
-- 查看系统当前隔离级别
select @@global.tx_isolation;
-- 设置当前会话隔离级别
set session transaction isolation level 隔离级别
-- 设置系统隔离级别
set global transaction isolation level 隔离级别
mysql一般默认使用repeatable read隔离级别
在my.ini可以设置默认隔离级别
transaction-isolation=隔离级别
事务的ACID
- 原子性:事务是一个不可分割的工作单位,事务的操作要么都发生,要么都不发生
- 一致性:事务必须使数据库从一个一致性状态变到另一个一致性状态
- 隔离性:多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- 持久性:一个事务一旦被提交,它对数据库中数据的改变就是永久性的接下来即使数据库发生故障也不应该对其有任何影响
表类型和存储引擎
表类型由存储引擎决定,主要包括myisam、innodb、memory等等
MySQL数据表主要支持六种类型,分别是:CSV、Memory、ARCHIVE、MRG MYISAM、MYISAM、InnOBDB
事务安全性:innodb(支持事务)
非事务安全性:除了innodb
存储类型选择
- 需要事务,innodb
- 不需要事务,只需要基本的CRUD,myisam
- memory将数据存储在内存中,不需要IO操作速度极快。mysql重启之后数据丢失(经典用法:用户在线状态)
修改存储引擎alter table 表名 engine = 存储引擎
视图
有时候信息是个人重要信息,不希望这些被查找到 =》这就用到视图
视图是一个虚拟表,其内容由查询来定义,也包含列,数据来自对应的真实表(基表)
视图可以修改基表的数据,基表的改变也会影响到视图的数据
使用
mysql
create view 视图名 as select 字段名 from 表名 -- 创建视图
desc 视图名 -- 查看视图
show create view 视图名 -- 查看视图创建的指令
drop view 视图名1,视图名2... -- 删除视图
alter view 视图名 as select语句 -- 修改视图结构
-- CRUD和表一样
- 创建视图之后,对应视图的只有一个frm文件,并没有数据文件
- 视图和基表的数据是可以相互影响的
- 视图中还可以再使用视图,数据依旧来自基表
实践
- 安全,一些表的字段是要求保密的
- 性能
- 灵活
用户管理和权限管理
用户管理
mysql的用户都存储在mysql的user表中
- host:允许登录的ip
- user:用户名
- authentication_string:密码,password()加密之后的结果
mysql
-- 创建用户
create user '用户名'@'允许登录的位置' identified by '密码'
-- 删除用户
drop user '用户名'@'允许登录的位置'
-- 修改密码 修改自己的密码是允许的 修改别人的密码是需要权限的
set password = password("密码") -- 修改自己的密码
set password for '用户名'@'允许登录的位置' = password("密码") -- 修改别人的密码
权限管理
mysql
-- 授权
grant 权限列表 on 库.对象名 to '用户名'@'允许登录的位置' [identified by 密码]
"
说明
grant select on xxx
grant select,create,delete on xxx
grant all on -- 表示赋予该用户在该对象上的所有权限
库.对象名
*.* 表示本系统中所有数据库的所有对象(表 视图 存储过程)
库.* 表示某个数据库的所有对象
identified by 密码
如果用户存在 就是修改该用户的密码
如果用户不存在 就是创建该用户
"
-- 回收
revoke 权限列表 on 库.对象名 from '用户名'@'允许登录的位置'
-- 如果权限没有生效 使用 flush privileges
操作
mysql
CREATE user dd@127.0.0.1 IDENTIFIED by '111111'; -- 创建用户 默认只能看到默认系统数据库
"创建一个数据库 一个表 并且插入一条消息 此时dd这个用户还是看不到"
create DATABASE testdb;
use testdb;
CREATE TABLE news(id int PRIMARY KEY,content VARCHAR(32));
insert into news values(1,"北京新闻");
"给dd用户增加对testdb.news查看和添加的权限 此时dd用户可以看到这个数据库的表了"
GRANT SELECT,INSERT ON testdb.news to dd@127.0.0.1;
"增加一个权限"
GRANT UPDATE ON testdb.news to dd@127.0.0.1;
-- 修改密码
set PASSWORD FOR duyun@127.0.0.1 = PASSWORD('111111');
"回收update权限"
REVOKE UPDATE ON testdb.news FROM dd@127.0.0.1
一些其他细节
- 在创建用户的时候,没有指定host默认是% 代表着所有的ip都有连接权限
- 也可以这样
cretae user xxx@192.168.1.%
代表着属于该网段的ip都可以连接 - 删除用户的时候如果host不是%,那么需要指定;否则不用指定