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后面不能跟聚合函数, 因为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 |
+----+-----------+----------+
参数模式
参数模式: IN gname VARCHAR(50)
– 默认是IN
– IN: 该参数可以作为输入, 也就是该参数作为传入值
– OUT: 该参数可以作为输出, 也就是该参数可以作为返回值
– INTOUT: 该参数既可以作为输入又可以作为输出, 也就是该参数既需要传入值, 又可以返回值
分隔符
DELIMITER $
在命令行的, 每一句的结尾都是分号, 如果在都条语句的使用, 并且每一行都包含一个分号, 那么sql就会自动执行, 那么就需要自定义一下分隔符, 到了指定的位置才自动执行, 而不是一看到分号就执行
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);
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;
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
一条sql的函数
CREATE FUNCTION simple_func() RETURNS INT RETURN 666;
SELECT simple_func();
有参数, 有返回值
-- 无参数, 有返回值
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;