MySQL详细操作

一、用户管理

-- 创建用户
create user "用户名"@"IP地址" identified by "密码";
create user "pd"@"192.168.1.1" identified by "123456";
create user "pd"@"192.168.%" identified by "123456";
create user "pd"@"%" identified by "123456";

-- 删除用户
drop user "用户名"@"IP地址";

-- 修改用户
rename user "用户名"@"IP地址" to "新用户名"@"IP地址";

-- 修改密码(5.7版本)
update mysql.user set authentication_string=password("新密码") where user="用户名";
flush privileges;  # 刷新权限

PS:用户权限相关数据保存在mysql数据库的user表中,所以也可以直接对其进行操作(不建议)。
    查看所有用户和IP地址
        select user,host from user;
View Code

忘记密码

在忘记root密码的时候,可以这样:
 
# 1.首先打开cmd窗口,关闭mysql服务
net stop mysql
 
# 2.然后跳过权限检查,启动mysql,输入命令
mysqld --skip-grant-tables
 
# 3.重新打开一个新的cmd窗口,启动客户端(已跳过权限检查,可以直接登录)
mysql
 
# 4.直接进来,修改密码
update mysql.user set authentication_string=password("新密码") where user="root";

# 5.刷新权限
flush privileges;
View Code

二、授权管理

-- 查看权限
    show grants for "用户名"@"IP地址";

-- 授权
    grant 权限 on 数据库名.表名 to "用户名"@"IP地址";
    grant select,insert,update on db.tb to "pd"@"%";
    grant all privileges on db.tb to "pd"@"%";

-- 取消权限
    revoke 权限 on 数据库名.表名 from "用户"@"IP地址";
View Code

关于权限

关于权限
    all privileges          除grant外的所有权限
    select                  仅查权限
    select,insert           查和插入权限
    ...
    usage                   无访问权限
    alter                   使用alter table
    alter routine           使用alter procedure和drop procedure
    create                  使用create table
    create routine          使用create procedure
    create temporary tables 使用create temporary tables
    create user             使用create user、drop user、rename user和revoke  all privileges
    create view             使用create view
    delete                  使用delete
    drop                    使用drop table
    execute                 使用call和存储过程
    file                    使用select into outfile 和 load data infile
    grant option            使用grant 和 revoke
    index                   使用index
    insert                  使用insert
    lock tables             使用lock table
    process                 使用show full processlist
    select                  使用select
    show databases          使用show databases
    show view               使用show view
    update                  使用update
    reload                  使用flush
    shutdown                使用mysqladmin shutdown(关闭MySQL)
    super                   使用change master、kill、logs、purge、master和set global;还允许mysqladmin调试登陆
    replication client      服务器位置的访问
    replication slave       由复制从属使用
关于权限

关于用户和IP

"用户名"@"IP地址"      用户只能在该IP下才能访问
"用户名"@"192.168.%"     用户只能在该IP段下才能访问(通配符%表示任意)
"用户名"@"%"             用户可以在任意IP下访问(默认IP地址为%)

三、数据库操作

数据库名.*        -- 数据库中的所有表
数据库名.表名    -- 指定数据库中的某张表
数据库名.存储过程   -- 指定数据库中的存储过程
*.*               -- 所有数据库
-- 显示数据库
show databases;

-- 创建数据库 create database 数据库名 default charset utf8; create database 数据库名 default charset gbk; -- 删除数据库 drop database 数据库名; -- 使用数据库 use 数据库名; -- 查询当前操作所在的数据库名称 select database(); -- 显示当前使用的数据库中所有表 show tables;

四、MySQL数据类型

# bit[(m)]
    二进制位(101001),m表示二进制位的长度(1-64),默认m=1
    
# tinyint[(m)][unsigned][zerofill]
    小整数,数据类型用于保存一些范围的整数数值范围
        有符号:-128 ~ 127
        无符号:0 ~ 255
        特别的:MySQL中无布尔值,使用tinyint(1)构造

# int[(m)][unsigned][zerofill]
    整数,数据类型用于保存一些范围的整数数值范围
        有符号:-2147483648 ~ 2147483647
        无符号:0 ~ 4294967295
        特别的:整数类型中的m仅用于显示,对存储范围无限制。例如:int(5),当插入数据2时,select时数据显示为:00002
        
# big[(m)][unsigned][zerofill]
    大整数,数据类型用于保存一些范围的整数数值范围
        有符号:-9223372036854775808 ~ 9223372036854775807
        无符号:0 ~ 18446744073709551615

# decimal[(m[,d])][unsigned][zerofill]
    准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。
        特别的:对于精确数值计算时需要用此类型
            decaimal能够存储精确值的原因在于其内部按照字符串存储
            
# float[(m,d)][unsigned][zerofill]
    单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数
        无符号:
            -3.402823466E+38 to -1.175494351E-38,
            0
            1.175494351E-38 to 3.402823466E+38
        有符号:
            0
            1.175494351E-38 to 3.402823466E+38
        特别的:###数值越大,越不准确###

# double[(m,d)][unsigned][zerofill]
    双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数
        无符号:
            -1.7976931348623157E+308 to -2.2250738585072014E-308
            0
            2.2250738585072014E-308 to 1.7976931348623157E+308
        有符号:
            0
            2.2250738585072014E-308 to 1.7976931348623157E+308
        特别的:###数值越大,越不准确###
        
# char(m)
    char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度
        PS: 即使数据小于m长度,也会占用m长度
    
# varchar(m)
    varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允
    许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中
        PS:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可
           以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡

# text
    text数据类型用于保存变长的大字符串,可以组多到65535(2**16 − 1)个字符
    
# mediumtext
    一个text列,最大长度为16777215(2**24 - 1)个字符
    
# longtext
    一个text列,最大长度为4294967295(2**32 - 1)个字符

# enum
    枚举类型:enum列最多可包含65535个不同的元素
    示例:
        create table shirts(
            name char(32),
            size enum("x-small","small","medium","large","x-large")
        )engine=innodb default charset=utf8;
        
        insert shirts(name, size) values("dress shirt","large"),("t-shirt","medium"),("polo shirt","small");
        
# set
    集合类型:set列最多可包含64个不同的成员
    示例:
        create table myset(col set("a","b","c","d"));
        
        insert into myset(col) values("a,d"),("d,a"),("a,d,a"),("a,d,d"),("d,a,d");
        
# data
    YYYY-MM-DD,例如:2018-08-10
    
# time
    HH:MM:SS,例如:11:11:11

# datetime
    YYYY-MM-DD HH:MM:SS,例如:2018-08-10 11:11:11
    
# year
    YYYY,例如:2018
    
# timestamp
    YYYY-MM-DD HH:MM:SS,例如:2018-08-10 11:11:11
View Code

参考

五、数据表操作

创建表

-- 示例
create table t1(
  id int not null auto_increment primary key,
  name char(10) not null unique,
  age int null
)engine=innodb default charset=utf8;

PS:
not null:表示此列不能为空

auto_increment:表示自增长,默认每次增长+1
注意:自增长只能添加在主键或者唯一索引字段上

primary key:表示主键(唯一且不为空)
engine=innodb:表示指定当前表的存储引擎
default charset=utf8:设置表的默认编码集

创建表的示例:

-- 是否为空
    null        -- 可空,非字符串
    not null    -- 不可空

----------------------------------------------------------------------------
-- 默认值
    创建字段时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值
    create table tb(
      name char(10) not null default 0
    );

----------------------------------------------------------------------------
-- 自增
    如果为某列设置自增列,插入数据时无需设置此列,默认将自增(表中只能有一个自增列)
    create table tb(
        id int not null auto_increment primary key
    );
    或者
    create table tb(
        id int not null auto_increment,
        index(id)
    );
    ----------------------------------------
    -- 注意:对于自增列,必须是索引(含主键);对于自增可以设置步长和起始值,如下:
        基于会话级别:修改仅对此次登录有效(一次登录就表示一次会话)
            show session variables like "auto_inc%";    查看全局变量
            set session auto_increment_increment=2;     设置步长
            set session auto_increment_offset=10;       设置起始值(一般不用)
        基于全局级别:永久有效
            show global variables like "auto_inc%";     查看全局变量
            set global auto_increment_increment=2;      设置步长

----------------------------------------------------------------------------
-- 普通索引
    create table tb(
       id int not null auto_increment primary key,
       name varchar(10) not null,
       index idx_name (name)  
    );

----------------------------------------------------------------------------
-- 唯一索引
    create table tb(
        xx int unique,
        oo int unique
    );
    ----------------------------------------
    -- 唯一索引作用:
        索引列的值必须唯一,允许有空值
        与主键索引区别:一种特殊的唯一索引,不允许有空值
----------------------------------------------------------------------------
-- 联合唯一索引
    create table tb(
        xx int,
        oo int,
        unique index 索引名 (xx, oo)  # 索引名可不写
    )
----------------------------------------------------------------------------
-- 主键
    一种特殊的唯一索引,不允许有空值,一个表只能有一个主键。如果主键使用单个列,则它的值必须唯一;如果是多列,则其组合必须唯一。
    create table tb(
        id int not null auto_increment primary key
    );
    或者
    create table tb(
        id int not null,
        num int not null,
        primary key (id, num)
    );
----------------------------------------------------------------------------    
-- 外键
    create table department(
        id int not null auto_increment primary key,
        name char(10)
    );

    create table userinfo(
        id int not null auto_increment primary key,
        name char(10),
        dept_id int,
        constraint fk_usr_dept foreign key (dept_id) references department(id)
    );
    ----------------------------------------
    create table tb1(
        id1 int not null auto_increment,
        id2 int not null,
        name varchar(32),
        primary key(id1,id2)
    );

    create table tb2(
        id1 int not null auto_increment primary key,
        id2 int not null,
        name varchar(32),
        constraint fk_tb2_tb1 foreign key (id1,id2) references tb1(id1,id2)
    );
View Code

删除表

drop table 表名;

清空表

-- 保留自增记录,下次添加数据接着上次id次数
delete from 表名;
-- 还原到原始状态 truncate table 表名;

修改表

表名、表字段

-- 修改表名称
rename table 旧表名 to 新表名;

-- 添加表字段
alter table 表名 add 字段名 类型 约束...;
例如:alter table student add age int not null default 18 after name;

-- 删除表字段
alter table 表名 drop column 字段名;

-- 修改表字段
方式1:alter table 表名 modify column 字段名 类型 是否为空 默认值...;
方式2:alter table 表名 change 旧字段名 新字段名 int not null default 0;
二者区别:
  modeify 只能改变字段的属性
  change 可以改变字段名和属性

自增

alter table 表名 auto_increment=20;

主键

-- 添加主键
alter table 表名 add primary key (字段名,"多个","隔开");

-- 移除主键
alter table 表名 drop primary key;

-- ps:如果主键为自增长,以上方式则不被允许执行,请先去掉主键自增长属性,然后再移除主键
alter table 表名 modify id int not null,drop primary key;

外键

-- 添加外键
alter table 从表名 add constraint 外键名 foreign key (从表字段名,可多个) references 主表(主表字段名,可多个);

-- 删除外键
alter table 表名 drop foreign key 外键名;

-- PS:如果外键设置后想修改,那么只能是先删除,再添加

定义外键的条件:

1)外键对应的字段数据类型保持一致,且被关联的字段(即references指定的另外一个表的字段)必须保证唯一

2)所有tables的存储引擎必须是InnoDB类型

3)外键约束的4种类型:restrict、no action、cascade、set null

-- restrict
同no action, 都是立即检查外键约束

-- no action
如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作  

-- cascade
在父表上update/delete记录时,同步update/delete掉子表的匹配记录 

-- set null
在父表上update/delete记录时,将子表上匹配记录的列设为null(要注意子表的外键列不能为not null

4)建议:

  • 如果需要外键约束,最好创建表同时创建外键约束
  • 如果需要设置级联关系,删除时最好设置为 set null

PS:

  • 插入数据时,先插入主表中的数据,再插入从表中的数据。
  • 删除数据时,先删除从表中的数据,再删除主表中的数据。

默认值

-- 修改字段默认值
alter table 表名 alter 字段名 set default 10;

-- 删除字段默认值
alter table 表名 alter 字段名 drop default;

复制表

-- 只复制表结构和表中数据
create table tb2 select * from tb1;
-- PS:主键自增、索引、触发器、外键 不会被复制
   
-- 只复制表结构
create table tb2 like tb1;
-- ps:数据、触发器、外键 不会被复制 

其他

-- 查看表结构
desc 表名;

-- 查看创建表信息
show create table 表名;

六、建立表与表之间的关系

一对一

# 一对一
两张表:微信号与电话号,一个微信号只能对应一个电话号
关联方式:foreign key + unique
create table phone_tb(
    id int auto_increment primary key,
    phone_num bigint(50) not null unique
)engine=innodb default charset=utf8;

create table wechat_tb(
    id int auto_increment primary key,
    wechat_name varchar(32) not null,
    phone_id int unique,  # 该字段一定要是唯一的
    constraint fk_wechat_phone foreign key(phone_id) references phone_tb(id)
)engine=innodb default charset=utf8;

insert into phone_tb(phone_num) values
    ("18820051111"),
    ("18820052222"),
    ("18820053333");

insert into wechat_tb(wechat_name,phone_id) values
    ("A",1),
    ("B",2),
    ("C",3);
View Code

一对多

# 一对多或称为多对一
两张表:班级与学生,一个班级可以对应多个学生,但一个学生只能对应一个班级
关联方式:foreign key
create table class(
    id int auto_increment primary key,
    name char(10) not null unique
)engine=innodb default charset=utf8;

create table student(
    id int auto_increment primary key,
    name char(10) not null unique,
    class_id int not null,
    constraint fk_stu_cla foreign key(class_id) references class(id)
)engine=innodb default charset=utf8;

insert into class(name) values
    ("高三1班"),
    ("高三2班"),
    ("高三3班");
    
insert into student(name,class_id) values
    ("A",1),
    ("B",1),
    ("C",2),
    ("D",2),
    ("E",3),
    ("F",3);
View Code

多对多

# 多对多
三张表:一个作者可以写多本书,一本书也可以是由多个作者写的
关联方式:foreign key + 第三张表
create table author(
    id int not null primary key auto_increment,
    name char(10)
)engine=innodb default charset=utf8;

create table book(
    id int not null primary key auto_increment,
    title char(16)
)engine=innodb default charset=utf8;

# 这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了
create table author2book(
    id int not null unique auto_increment,
    author_id int not null,
    book_id int not null,
    constraint fk_author foreign key(author_id) references author(id) on delete cascade on update cascade,
    constraint fk_book foreign key(book_id) references book(id) on delete cascade on update cascade,
    primary key(author_id, book_id)
)engine=innodb default charset=utf8;
View Code

七、表内容操作

插入数据(insert)

insert into 表名(字段名,字段名...) values(值,值...);
insert into 表名(字段名,字段名...) values(值,值...),(值,值...);
insert into 表名(字段名,字段名...) select 字段名,字段名... from 表名;

删除数据(delete)

-- 清空表
delete from 表名;         清空表,如果有自增主键,主键记录的值不会被删除
truncate table 表名;      清空表

-- 删除符合where后条件的数据
delete from 表名 where 条件;
delete from 表名 where id!=2;
delete from 表名 where id!=2 and name="pd";
delete from 表名 where id>=2 or name="pd";

truncate 和 delete 的区别?

  • truncate 在各种表上无论是大的还是小的都非常快。而 delete 操作会被表中数据量的大小影响其执行效率。
  • truncate 是一个DDL语言而 delete 是DML语句,向其他所有的DDL语言一样,他将被隐式提交,不能对 truncate 使用 rollback 命令。
  • truncate 不能触发触发器,delete 会触发触发器。
  • truncate 当表被清空后,表和表的索引和自增主键将重新设置成初始大小,而 delete 则不能。

更新操作(update)

update 表名 set 字段1="值" where 条件;
update 表名 set 字段1="值",字段2="值" where 条件;
update tb1 set name="pd" where id=1;

查询操作(select)

简单查询

select * from 表名;
select 字段名,字段名... from 表名;
select 字段名 as 自定义名 from 表名;  -- 显示出来的相应字段为自定义名

条件查询

select * from 表名 where age > 23;
select * from 表名 where age = 23;
select * from 表名 where age != 23;
select * from 表名 where age is null;
select * from 表名 where age is not null;

select * from 表名 where age = 23 or gender="男";
select * from 表名 where age = 23 and gender="男";

区间查询

select * from 表名 where id between 5 and 10;  -- 取id是5-10的值
等价于:
select * from 表名 where id>=5 and id<=10;

集合查询

select * from 表名 where id in (1,2,3);        -- 取id在括号内的值
select * from 表名 where id not in (1,2,3);
select * from 表名 where id in (select id from 表名);

模糊查询

-- 查询姓名以"张"字开头的
select * from 表名 where name like "张%";

-- 查询姓名以"张"字结尾的
select * from 表名 where name like "%张";

-- 查询name名称是三个字符的人
select * from 表名 where name like "___";

-- 查询name名称的第二个字符是"d"的人
select * from 表名 where name like "_d%";

-- 排除名字带a的学生
select * from 表名 where name not like "a%";  

排序查询

asc   升序,默认为升序
desc  降序
-- PS:order by要写在select语句末尾

select * from 表名 order by 字段名 asc;
select * from 表名 order by 字段名 desc;
select * from 表名 order by 字段名 asc,字段名 desc;

-- 强制中文排序
select * from 表名 order by convert(name using gbk);
-- PS:UTF8默认校对集是utf8_general_ci,它不是按照中文来的,你需要强制让MySQL按中文来排序。

聚合函数

聚合:  将分散的聚集到一起。
聚合函数: 对列进行操作,返回的结果是一个单一的值,除了 count 以外,都会忽略空值。

count:统计指定列不为NULL的记录行数;
  sum:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
  max:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
  min:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
  avg:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;

-- 格式
select 聚合函数(字段) from 表名;
 
-- 统计人员中最大年龄、最小年龄,平均年龄分别是多少
select max(age),min(age),avg(age) from 表名;

分组查询

-- 分组查询格式
select 被分组的字段 from 表名 group by 分组字段 [having 条件字段];
-- PS:分组查询可以与 聚合函数 组合使用。

select count(name),max(id) from 表名 group by name;

-- PS:如果要对聚合函数结果进行二次筛选,则必须使用having
select count(name),max(id) from 表名 group by name having max(id)>5;

where 与 having区别:

  • 执行优先级从高到低:where > group by > having
  • where 发生在分组 group by 之前,因而 where 中可以有任意字段,但是绝对不能使用聚合函数
  • having 发生在分组 group by 之后,因而 having 中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数

分页查询

好处:限制查询数据条数,提高查询效率。

select * from 表名 limit 5;           -- 取前5行
select * from 表名 limit 2,5;         -- 从3开始取,往后取5行;即3-7行的数据
select * from 表名 limit 5 offset 2;  -- 前2行不取,往后取5行;即3-7行的数据

连表查询

-- 无对应关系则不显示
select * from student,class where student.class_id=class.id; 

-- 无对应关系则不显示
select * from student inner join class on student.class_id=class.id;

-- student表所有显示,如果class表中无对应关系,则为null
select * from student left join class on student.class_id=class.id;

-- class表所有显示,如果student表中无对应关系,则为null
select * from student right join class on student.class_id=class.id;

-- 小结:inner join将出现null的一行不显示,left join左边全部显示,right join右边全部显示

-- 连多张表
    select * from score 
        left join student on score.student_id=student.id 
        left join course on score.course_id=course.id 
        left join class on student.class_id=class.id 
        left join teacher on course.teacher_id=teacher.id;

组合查询

-- 自动去重
    select 字段名 from 表A union select 字段名 from 表B;
-- 不去重
    select 字段名 from 表A union all select 字段名 from 表B;

 

posted @ 2018-10-08 22:35  就俗人一个  阅读(260)  评论(0编辑  收藏  举报