MySQL基础操作

文章目录

      • 配置操作
          • 连接`mysql`
          • 添加新用户
          • 修改用户密码
          • 修改用户的权限
          • 查看用户的权限
          • 删除用户
      • 数据库操作
          • 创建数据库
          • 修改数据库
          • 删除数据库
      • 数据引擎
          • 查看`mysql`已经提供什么引擎
          • 查看`mysql`当前默认引擎
          • 修改数据库临时的默认存储引擎
      • 数据表操作
          • 创建表
          • 修改表名
          • 修改数据表的字符编码
          • 查看数据表的定义
          • 备份和导入表
          • 清空表
          • 添加-修改-删除-重命名字段
          • 添加-删除主键和自增
          • 添加-删除外键约束
          • 添加数据
          • 删除数据
          • 修改数据
          • 查询数据
          • 排序
          • 内连接
          • 左连接
          • 右连接
          • where和having的区别
      • 事务
          • 开启事务
          • 回滚和提交
          • 基础使用
      • 存储过程
          • 创建存储过程
          • 基本使用
          • 删除存储过程
      • 自定义函数
          • 创建语法
          • 基本使用
          • 删除函数
      • 视图
          • 基本使用
          • 查看视图配置
          • 删除视图

配置操作

连接mysql
sql -h 127.0.0.1 -u root -p
#参数:
	# -h 主机 本地数据库可以不用写
	# -u 用户名
	# -p 密码
添加新用户
# 允许本地IP访问localhost,127.0.0.1
create user 'testuser'@'localhost' identified by 'testpassword';

# 允许外网IP访问
create user 'testuser'@'%' identified by 'testpassword';

# 刷新授权
flush privileges;
修改用户密码
# 修改用户密码
set password for 'testuser'@'localhost'=password('testpwd');
修改用户的权限
# 授予用户在本地服务器对该数据库的全部权限
# all可以替换成想要设置的权限 SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER 然后去掉privileges
grant all privileges on `dbCourse`.* to 'testuser'@'localhost' identified by 'password';

grant select,update,delete,alter on testuser.* to testuser@'localhost' identified by 'password';

# 授予用户通过外网IP对于该数据库的全部权限
grant all privileges on `dbCourse`.* to 'testuser'@'%' identified by 'password'; 
查看用户的权限
 show grants for 'testuser'@'localhost';
删除用户
drop user 'testuser'@'localhost';

数据库操作

创建数据库
# 创建dbCourse数据库, 设置默认字符集为utf8
create database dbCourse default charset=utf8;
修改数据库
# 修改数据库的字符集
alter database dbCourse default character set 'utf8';
# 查看数据库的声明定义
show create database dbCourse;
删除数据库
drop database dbCourse;
# 使用 if exists 用于防止当数据库不存在是发生错误
drop database if exists dbCourse;

数据引擎

查看mysql已经提供什么引擎
show engiens;
查看mysql当前默认引擎
show variables like '%storage_engine%';
修改数据库临时的默认存储引擎
# 当再次重启客户端时,默认存储引擎仍然是 InnoDB。
set default_storage_engine=MyISAM;

数据表操作

创建表
create table articles(
    -> id int(11) not null primary key auto_increment,
    -> title varchar(255) not null,
    -> content longtext not null # 这里的逗号不能要
    -> );
修改表名
# 修改表名
alter table mytable rename testtable;
修改数据表的字符编码
# 修改字符集
alter table mytable default character set 'gbk';
alter table mytable convert to character set 'utf8';
查看数据表的定义
# 查看数据库的声明定义
show create table mytable;
备份和导入表
# 要备份的标 students 备份的表为recover_student
CREATE TABLE backup_student SELECT * FROM students;
# 测试了, 主键和自增没有备份过去

# 将备份表的数据导入主表中
CREATE TABLE backup_stu SELECT * FROM stu;
TRUNCATE stu;
INSERT INTO stu SELECT * FROM backup_stu;
清空表
# 基本删除语句, 一条一条的删除, 速度会很慢
# 下次添加数据, id接着前面的数据来
DELETE FROM recover_student;

# 清空表
TRUNCATE users;
# 下次添加数据, id从1开始
添加-修改-删除-重命名字段
# 添加字段
# after id 指定的字段在哪个字段后面, 或者 first, 那么放在字段最前面
ALTER TABLE users ADD email VARCHAR(50) DEFAULT NULL AFTER id;

# 修改字段
ALTER TABLE users MODIFY username VARCHAR(50) NOT NULL DEFAULT 'testuser';

# 删除字段
alter table users drop email;

# 字段重命名
ALTER TABLE users CHANGE `username` `name` VARCHAR(100) NOT NULL; 
添加-删除主键和自增
# 添加主键
ALTER TABLE backup_users ADD PRIMARY KEY (id);

# 删除主键
# 如果主键字段有自增就会报错, 所以想要删除自增
ALTER TABLE backup_users DROP PRIMARY KEY;

# 添加自增
ALTER TABLE backup_users MODIFY id INT NOT NULL AUTO_INCREMENT;

#删除自增
ALTER TABLE backup_users MODIFY id INT NOT NULL;
添加-删除外键约束
CONSTRAINT package_constraint FOREIGN KEY (`pid`) REFERENCES `package`(`id`)

alter table selection add constraint FK_Reference_1 foreign key(course) references course (id) 
添加数据
# 一次添加一条数据
insert into `stu` (`id`, `name`, `class_id`) values('1','user1','1');

# 一次添加多条数据
insert into stu_course (sid, cid) values(1, 2),(1, 4),(2, 4), (3, 2), (3, 3),(4, 1);
删除数据
# 删除指定数据
DELETE FROM stu WHERE id = 5;
# 删除指定的多条数据
DELETE FROM stu WHERE id IN (6, 7, 8);
修改数据
# 修改一条数据
UPDATE stu SET `name` = 'chenjiang' WHERE id = 4;
查询数据
SELECT * FROM stu;
排序
-- 排序是对已经查询出来的结果再进行排序, 而不是先排序后查询, 所以要将order by 放在 where 后面
-- DESC倒序, ASC升序
SELECT * FROM stu WHERE id > 2 ORDER BY id DESC;
内连接
create table stu(
    `id` int not null primary key auto_increment,
    `name` varchar(50) not null,
    `class_id` int
);
insert into `stu` (`id`, `name`, `class_id`) values('1','user1','1');
insert into `stu` (`id`, `name`, `class_id`) values('2','user2','3');
insert into `stu` (`id`, `name`, `class_id`) values('3','user3','4');
insert into `stu` (`id`, `name`, `class_id`) values('4','user4',NULL);
insert into `stu` (`id`, `name`, `class_id`) values('5','user5',NULL);

CREATE TABLE class(
    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    `cname` VARCHAR(50) NOT NULL
);
insert into `class` (`id`, `cname`) values('1','PHP');
insert into `class` (`id`, `cname`) values('2','Javascript');
insert into `class` (`id`, `cname`) values('3','Python');
insert into `class` (`id`, `cname`) values('4','Java');

CREATE TABLE stu_course(
    `sid` INT comment '学生id',
    `cid` int comment '课程id'
);
insert into stu_course (sid, cid) values(1, 2),(1, 4),(2, 4), (3, 2), (3, 3),(4, 1);

-- 将两张表一一对应的数据才会显示出来
SELECT * FROM stu AS s 
INNER JOIN class AS c
ON s.class_id = c.id;

    id  name    class_id      id  cname   
------  ------  --------  ------  --------
     1  user1          1       1  PHP     
     2  user2          3       3  Python  
     3  user3          4       4  Java    
     

-- 多对多查询, 一个学生选了多个课程, 一个课程被多个选
-- 每次内连接的结果, 就当成一张新表, 然后用这张新表继续内连接其他表
SELECT s.name AS stu_name, c.name AS course_name FROM stu AS s
INNER JOIN stu_course AS sc
ON s.`id` = sc.`sid`
INNER JOIN course AS c
ON sc.`cid` = c.`id`;

stu_name  course_name  
--------  -------------
user1     课程2      
user1     课程4      
user2     课程4      
user3     课程2      
user3     课程3      
user4     课程1   

-- 找到选了大于等于2门课程的学生
SELECT s.name, COUNT(*) AS total FROM stu AS s
INNER JOIN stu_course AS sc
ON s.`id` = sc.`sid`
INNER JOIN class AS c
ON sc.`cid` = c.id
GROUP BY s.`id`
HAVING total >= 2;

name     total  
------  --------
user1          2
user3          2
左连接
-- 将左表的数据全部显示出来
SELECT * FROM stu AS s 
LEFT JOIN class AS c
ON s.class_id = c.id;

    id  name    class_id      id  cname   
------  ------  --------  ------  --------
     1  user1          1       1  PHP     
     2  user2          3       3  Python  
     3  user3          4       4  Java    
     4  user4     (NULL)  (NULL)  (NULL)  
     5  user5     (NULL)  (NULL)  (NULL)  
右连接
-- 将右表的数据全部显示出来
SELECT * FROM stu AS s 
RIGHT JOIN class AS c
ON s.class_id = c.id;

    id  name    class_id      id  cname       
------  ------  --------  ------  ------------
     1  user1          1       1  PHP         
     2  user2          3       3  Python      
     3  user3          4       4  Java        
(NULL)  (NULL)    (NULL)       2  Javascript  
where和having的区别
# where后面不能跟聚合函数, 因为where执行顺序大于聚合函数

# where子句的作用是在对查询结果进行分组之前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数, 使用where条件显示特定的行.

# having 子句的作用是筛选买主条件的组, 即在分组之后过滤数据, 条件中经常包含聚组函数, 使用having条件显示特定的组, 也可以使用多个分组标准进行分组.

# 不会出错
SELECT `name`, `salary` FROM emp WHERE `deptNo` = 2;
# 出错
SELECT `name`, `salary` FROM emp HAVING `deptNo` = 2;
# 因为前面并没有筛选出deptno字段 他会先查询出所有的记录到内存,形成了一个表,在对表进行操作,这是只能操作表中的字段,也就是select中有的字段。

事务

开启事务
# 两种方式
BEGIN;
START TRANSACTION;
回滚和提交
ROLLBACK; -- 撤销上一次的操作
COMMIT; -- 真正的提交, 如果没有操作, 只能当前终端才能看到修改的数据
基础使用
-- 一个终端开启事务, 进行操作
-- 另一个终端也需要开启事务

-- 第一台终端
START TRANSACTION;
INSERT INTO stu (`name`) VALUES('lucy');
SELECT * FROM stu;
ROLLBACK;
-- COMMIT;

    id  name       class_id  
------  ---------  ----------
     1  user1               1
     2  user2               3
     3  user3               4
     4  chenjiang      (NULL)
    18  lucy           (NULL)
    

-- 另外一台终端
BEGIN;
SELECT * FROM stu; -- 因为上面还有commit,所以下面这个事务无法接收到上面改变的
+----+-----------+----------+
| id | name      | class_id |
+----+-----------+----------+
|  1 | user1     |        1 |
|  2 | user2     |        3 |
|  3 | user3     |        4 |
|  4 | chenjiang |     NULL |
+----+-----------+----------+

存储过程

  1. 参数模式

    参数模式: IN gname VARCHAR(50)

    – 默认是IN
    – IN: 该参数可以作为输入, 也就是该参数作为传入值
    – OUT: 该参数可以作为输出, 也就是该参数可以作为返回值
    – INTOUT: 该参数既可以作为输入又可以作为输出, 也就是该参数既需要传入值, 又可以返回值

  2. 分隔符

    DELIMITER $

    在命令行的, 每一句的结尾都是分号, 如果在都条语句的使用, 并且每一行都包含一个分号, 那么sql就会自动执行, 那么就需要自定义一下分隔符, 到了指定的位置才自动执行, 而不是一看到分号就执行

创建存储过程
  1. IN

    -- 定义分隔符
    DELIMITER $
    CREATE PROCEDURE procedure_1(IN gname VARCHAR(50))
    BEGIN
        SELECT goodsname, price FROM `order` WHERE goodsname = gname;
    END $
    -- 还原分隔符, 如果不还原, 那么后面的语句全部都是$结尾, 而不是分号
    DELIMITER ;
    -- 第一种
    CALL procedure_1('chenjiang'); -- 调用存储过程
    -- 第二种, 动态参数
    SET @gname = 'chenjiang'; -- 设置全局变量, 这一行也要执行
    CALL procedure_1(@gname);
    
  2. OUT

    -- 定义分隔符
    DELIMITER $
    CREATE PROCEDURE procedure_2(IN gname VARCHAR(50), OUT num INT)
    BEGIN
        -- into 赋值
        SELECT COUNT(*) INTO num 
        FROM `order` 
        WHERE goodsname = gname;
    END $
    -- 还原分隔符, 如果不还原, 那么后面的语句全部都是$结尾, 而不是分号
    DELIMITER ;
    SET @gname = 'chenjiang';
    CALL procedure_2(@gname, @num); -- 调用存储过程
    SELECT @num;
    
  3. INOUT

    -- 定义分隔符
    DELIMITER $
    CREATE PROCEDURE procedure_3(INOUT num INT)
    BEGIN
      SET num = num * 2;
    END $
    -- 还原分隔符, 如果不还原, 那么后面的语句全部都是$结尾, 而不是分号
    DELIMITER ;
    SET @num = 10;
    CALL procedure_3(@num); -- 调用存储过程
    SELECT @num;
    
基本使用
 -- 自定义函数, 随机指定数量的字符串
DELIMITER $$
CREATE FUNCTION `rand_string` (size INT) RETURNS VARCHAR(100) CHARSET 'utf8'
BEGIN
    DECLARE str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    DECLARE return_str VARCHAR(100) DEFAULT '';
    DECLARE i INT DEFAULT 0;
    WHILE i < size DO
        SET return_str = CONCAT(return_str, SUBSTRING(str, FLOOR(RAND() * 62 + 1), 1));
        SET i = i + 1;
    END WHILE;
RETURN return_str;
END $$

-- 向数据表中插入指定数量的数据
DELIMITER $$
CREATE PROCEDURE `insert_order`(IN n INT)
BEGIN
    DECLARE i INT DEFAULT 1; -- 声明变量
    DECLARE goodsname VARCHAR(50) DEFAULT '';
    WHILE i < n DO
        SET goodsname = rand_string(45); -- 自定义函数, 随机指定数量的字符串
        INSERT INTO `order`(`goodsname`) VALUES(goodsname);
        SET i = i + 1; -- 没有i++  += 这两种写法
    END WHILE;
END $$
DELIMITER ;

CALL insert_order(100); -- 调用存储过程
删除存储过程
 DROP PROCEDURE procedure_3;
 -- 或者
 DROP PROCEDURE IF EXISTS procedure_3;

自定义函数

函数只会返回一个值,不允许返回一个结果集。函数强调返回值,所以函数不允许返回多个值的情况,即使是查询语句。

创建语法
create function 函数名(参数列表) returns 返回类型

begin
	函数体
end
基本使用
  1. 一条sql的函数

    CREATE FUNCTION simple_func() RETURNS INT RETURN 666;
    SELECT simple_func();
    
  2. 有参数, 有返回值

    -- 无参数, 有返回值
    DELIMITER $
    CREATE FUNCTION my_fun1(gname VARCHAR(50)) RETURNS DECIMAL(10, 2)
    BEGIN
        DECLARE single_price DECIMAL(10, 2);
        SELECT price INTO single_price  -- 变量赋值
        FROM `order`
        WHERE goodsname = gname;
        RETURN single_price;
    END $
    SET @gname = 'chenjiang' $
    SELECT my_fun1(@gname) $
    
删除函数
drop function 函数名;

视图

重用 SQL 语句。

简化复杂的 SQL 操作。创建视图之后可以方便地重用它而不必知道它的基本查询细节。

使用表的组成部分而不是整个表。

基本使用
-- 连接的表, 最后的select出来的不能有重复的列名
-- 例如: 这两张表都有id, 就会报错 Duplicate column name 'id'
-- 查看学生属于那个班级
CREATE VIEW my_view2
AS
SELECT s.name, c.cname
FROM `stu` AS s
LEFT JOIN `class` AS c
ON s.class_id = c.id;

SELECT * FROM my_view2 WHERE `name` = 'user1';

name    cname   
------  --------
user1   PHP     
查看视图配置
// 查看视图基本信息,如字段定义、字段数据类型、是否为空、是否为主外键、默认值和额外信息
DESCRIBE my_view2;

Field   Type         Null    Key     Default  Extra   
------  -----------  ------  ------  -------  --------
name    varchar(50)  NO              (NULL)           
cname   varchar(50)  YES             (NULL)           


// 查看视图的详细定义
SHOW CREATE VIEW my_view2;
删除视图
DROP VIEW my_view2;

你可能感兴趣的:(MySQL学习)