#if exists如果存在结果集就执行,if是where条件如果为true就执行
DROP TABLE IF EXISTS itcast_class;
#创建表格
CREATE TABLE itcast_class(
class_id INT PRIMARY KEY AUTO_INCREMENT,
class_name VARCHAR(10) NOT NULL DEFAULT ''
)CHARACTER SET utf8;
#添加字段
ALTER TABLE itcast_class ADD stu_id INT;
#删除字段
ALTER TABLE itcast_class DROP COLUMN stu_id;
#添加数据
INSERT INTO itcast_class VALUES(NULL,'班级四');
#修改数据
UPDATE itcast_class SET stu_id = 1 WHERE stu_id IS NULL;
#查询表格
SELECT * FROM itcast_class;
#查询表结构
SHOW CREATE TABLE itcast_class;
CREATE TABLE itcast_student(
stu_id INT PRIMARY KEY AUTO_INCREMENT,
stu_name VARCHAR(10) NOT NULL,
class_id INT,
#创建外键,一般项目不会使用外键,只会做逻辑关联
FOREIGN KEY (class_id) REFERENCES itcast_class (class_id)
)CHARACTER SET utf8;
INSERT INTO itcast_student VALUES(NULL,'赵六',4);
SELECT * FROM itcast_student;
CREATE TABLE itcast_teacher(
teacher_id INT PRIMARY KEY AUTO_INCREMENT,
teacher_name VARCHAR(10) NOT NULL,
teacher_days INT NOT NULL#上课天数
)CHARACTER SET utf8;
CREATE TABLE itcast_cla_tea(
id INT PRIMARY KEY AUTO_INCREMENT,
class_id INT NOT NULL,
teacher_id INT NOT NULL
)CHARACTER SET utf8;
SELECT * FROM itcast_cla_tea;
SELECT * FROM itcast_teacher;
#存储引擎即是表类型,类型不同,存储数据的速度会有影响,默认InnoDb,唯一支持外键的引擎,在mysql安装目录下的
#my.ini文件中配置
#basedir = "D:\ProgramFiles\Mysql"
# datadir = .....
#datadir = "D:\ProgramFiles\Mysql\data"
# 数据库引擎
#default-storage-engine=INNODB
# 设置mysql编码
#character_set_server=utf8
# 设置mysql字符集
#collation-server=utf8_general_ci
#分组和排序
SELECT * FROM itcast_student GROUP BY class_id ORDER BY stu_id DESC;
SELECT * FROM itcast_student ORDER BY class_id,stu_id DESC;
#limit,限制查询条数,即分页,他有两个条件,offset偏移量,即起始索引,默认是0,row_count查询总记录数,即长度
SELECT * FROM itcast_student LIMIT 0,4;
#distinct去掉重复记录,注:重复值是你查询的所有字段是否相同,而不是某一个字段
#与之相对的是all,默认
#数据库日志系统用的较多,一个错误多次发生。
SELECT DISTINCT * FROM itcast_student;
#union联合查询,将多条select查询结果集合并 注:union操作的结果集如果有重复数据,那么会消除,类似distinct
#union all会查询所有
#子语句order by排序时
#配合limit才会生效,union在做子语句时,会对没有limit子句的order by失效(优化)
(SELECT * FROM itcast_student WHERE class_id = 1 ORDER BY stu_id DESC LIMIT 1)
UNION
(SELECT * FROM itcast_student WHERE class_id = 3 ORDER BY stu_id DESC LIMIT 1)
#子查询
SELECT * FROM itcast_teacher WHERE teacher_days = (SELECT MAX(teacher_days) FROM itcast_teacher);
#带过班级三的老师带过那些班级?
SELECT * FROM itcast_class WHERE class_id IN (
SELECT class_id FROM itcast_cla_tea WHERE teacher_id IN(
SELECT teacher_id FROM itcast_cla_tea WHERE class_id =
(SELECT class_id FROM itcast_class WHERE class_name = '班级三')));
#和in同样的运算符any,all,some和any一样,只是国外为了兼顾他们的程序员理解和出现的语法
#=any()和in一样
#!=any()不等同于not in,在实际开发中很少用,因为只要这个值和集合中任意一个数不相等即会查出,一般都会查出所有
#=all()等于集合中所有,一般一个值都查不出
#!=all()值和集合中的任意一个都不相等,查出集合外的所有值
#行子查询 select * from 表名 where (字段1,字段2...) = (select (字段1,字段2...)from 表名);
#表子查询
SELECT * FROM (SELECT * FROM itcast_student WHERE stu_id > 20) AS temp WHERE stu_name LIKE '李%';
#表名查询
SHOW TABLES;
#exists是否存在
SELECT * FROM itcast_class AS cla WHERE EXISTS;
(SELECT * FROM itcast_cla_tea WHERE cla.class_id = class_id);
CREATE TABLE join_teacher(
id INT PRIMARY KEY AUTO_INCREMENT,
t_name VARCHAR(20),
gender ENUM('male','female','secret')#性别,使用枚举类型
)ENGINE INNODB CHARACTER SET utf8;
INSERT INTO join_teacher VALUES
(1,'韩星','male'),
(2,'李白','female'),
(3,'韩非子','secret'),
('4','孙武','male');
SELECT * FROM join_teacher;
CREATE TABLE join_class(
id INT PRIMARY KEY AUTO_INCREMENT,
c_name CHAR(5),
room CHAR(3)
)ENGINE INNODB CHARACTER SET utf8;
#修改字段类型
ALTER TABLE join_class MODIFY COLUMN c_name CHAR(7);
SHOW CREATE TABLE join_class;
INSERT INTO join_class VALUES
(1,'php0115','207'),
(2,'php0228','104'),
(3,'php0331','102'),
(4,'php0505','202');
SELECT * FROM join_class;
CREATE TABLE join_teacher_class(
id INT PRIMARY KEY AUTO_INCREMENT,
t_id INT,
c_id INT,
days TINYINT,
begin_date DATE,
end_date DATE
)ENGINE INNODB CHARACTER SET utf8;
INSERT INTO join_teacher_class VALUES
(1,1,1,15,'2013-01-15','2013-02-20'),
(2,1,2,18,'2013-02-28','2013-03-30'),
(3,1,3,22,'2013-03-31','2013-05-05'),
(4,2,1,20,'2013-02-22','2013-03-25'),
(5,2,2,22,'2013-03-31','2013-04-29'),
(6,3,1,15,'2013-03-27','2013-04-18'),
(7,1,1,15,'2013-04-19','2013-05-01'),
(8,3,3,15,'2013-05-28','2013-06-15'),
(9,2,1,5,'2013-05-04','2013-05-15');
SELECT * FROM join_teacher_class;
#内连接,连接数据不存在则不会出现
SELECT t.t_name,t_c.days FROM join_teacher AS t INNER JOIN join_teacher_class AS t_c
ON t.id = t_c.t_id;
#交叉连接,即笛卡尔积
SELECT t.t_name,t_c.days FROM join_teacher AS t CROSS JOIN join_teacher_class AS t_c;
#on和where都是条件筛选,但是on是在数据形成链接时判断,不通过就不连接,而where是数据形成笛卡尔积后判断筛选
#简单说on是判断后形成新表,where是新表形成后判断,逻辑含义不一样
SELECT t.t_name,t_c.days FROM join_teacher AS t INNER JOIN join_teacher_class AS t_c
ON t.id = t_c.t_id WHERE t_c.days>15;
#using快捷语法,这里只做语法测试,即两张表的id会自动匹配,实际中会和一张表的外键匹配,而他们的字段必须相同
SELECT t.t_name,t_c.days FROM join_teacher AS t INNER JOIN join_teacher_class AS t_c
USING(id);
#外连接,连接数据不存在也会以空出现
SELECT t.t_name,t_c.days FROM join_teacher AS t LEFT OUTER JOIN join_teacher_class AS t_c
ON t.id = t_c.t_id
SELECT t.t_name,t_c.days FROM join_teacher AS t RIGHT OUTER JOIN join_teacher_class AS t_c
ON t.id = t_c.t_id
#自然连接NATURAL,它会自己找相同的字段如id匹配,分内外
SELECT * FROM join_teacher NATURAL JOIN join_teacher_class;
#查询数据导入硬盘,存数据备份
#默认字段之间用'\t',行之间用'\d'
SELECT NULL,stu_name,class_id INTO OUTFILE 'C:/Users/Administrator/Desktop/itcast_student' FROM itcast_student;
#导入数据
LOAD DATA INFILE 'C:/Users/Administrator/Desktop/itcast_student' INTO TABLE itcast_student;
#修改默认分隔
SELECT * INTO OUTFILE 'C:/Users/Administrator/Desktop/itcast_student'
FIELDS TERMINATED BY '\t' ENCLOSED BY '\''#字段分隔
LINES TERMINATED BY '\n' STARTING BY 'start:'#行分隔
FROM itcast_student;
#二进制导出
#测试几次,好像只能导出一条没有分隔的数据
SELECT * INTO DUMPFILE 'C:/Users/Administrator/Desktop/itcast_student' FROM itcast_student LIMIT 1;
#不同插入
INSERT INTO itcast_student SET stu_name = '王夫子',class_id = 2;
#当插入主键冲突时可以改为修改
INSERT INTO itcast_student VALUES(2,'麻子',2)
ON DUPLICATE KEY UPDATE
stu_name='麻子',class_id=2;
#REPLACE==ON DUPLICATE KEY UPDATE
REPLACE INTO itcast_student VALUES(3,'流云',3);
#查询插入*蠕虫复制
INSERT INTO itcast_student(stu_name,class_id) SELECT stu_name,class_id FROM itcast_student;
SELECT * FROM itcast_student;
DESC itcast_student;
SELECT * FROM itcast_student;
SELECT * FROM itcast_class;
SELECT * FROM itcast_cla_tea;
#多表删除,删除一班相关所有的详细信息
SELECT * FROM
(SELECT c.*,t.stu_id,t.stu_name FROM itcast_class AS c JOIN itcast_student AS t
ON c.class_id = t.class_id WHERE c.class_name='班级一' )AS temp
JOIN itcast_cla_tea AS c_t ON temp.class_id = c_t.class_id;
SHOW CREATE TABLE itcast_student;
#删除外键,外键名称没有写时,系统默认:表名_ibfk_n(n代表第几个外键)
ALTER TABLE itcast_student DROP FOREIGN KEY itcast_student_ibfk_1;
#两张表删除
DELETE FROM itcast_class,itcast_student USING
itcast_class JOIN itcast_student
ON itcast_class.class_id = itcast_student.class_id WHERE itcast_class.class_name='班级一'
SELECT * FROM
(SELECT c.*,t.stu_id,t.stu_name FROM itcast_class AS c JOIN itcast_student AS t
ON c.class_id = t.class_id WHERE c.class_name='班级二' )AS temp
JOIN itcast_cla_tea AS c_t ON temp.class_id = c_t.class_id;
#三张表删除
DELETE FROM itcast_class,itcast_student,itcast_cla_tea USING
itcast_class JOIN itcast_student
ON itcast_class.class_id = itcast_student.class_id JOIN itcast_cla_tea
ON itcast_cla_tea.class_id = itcast_class.class_id
WHERE itcast_class.class_name='班级二'
#TRUNCATE删除表,创建表,不会记录原来表的信息,最典型的是索引从零开始
#delete逐行删除,保存原表的一些信息,比如索引不变
#多表更新
UPDATE tab1 JOIN tab2 ON tab1.a = tab2.a SET tab1.b = '',tab2.c='' WHERE tab1.id='';
#备份还原
#1,最简单的方法是直接到mysql文件夹中找到对应表数据(frm),表结构(myd),表存储引擎(myi)三个文件打包
#需要时将他们解压到指定的数据目录下
#注:默认innodb存储引擎下的表执行该方法,使用show tables可以看到该表名,但是不能使用
#2,备份:直接在cmd中的mysqld.exe中执行 mysqldump -uroot -p test > C:/Users/Administrator/Desktop/test.sql
#还原:source C:/Users/Administrator/Desktop/test.sql或者直接执行sql文件中的sql命令
#而在sqlYong编辑器中在最为方便简单,直接在工具选项中执行相应操作就好
#s视图
CREATE TABLE info_teacher(
id INT PRIMARY KEY AUTO_INCREMENT,
t_name VARCHAR(10),
salary DECIMAL(10,2)
);
INSERT INTO info_teacher VALUES
(NULL,'孔子',100.45),
(NULL,'老子',200.10),
(NULL,'离子',155.44);
SELECT * FROM info_teacher;
CREATE VIEW v_teacher AS SELECT id,t_name FROM info_teacher;
INSERT INTO v_teacher VALUES(NULL,'宏利');
SELECT * FROM v_teacher;
#视图的理解,即是查询语句的封装,简化一些复杂业务逻辑
#内部执行过程有两种,1,合并执行方式,即查询中套用子查询
#2,临时表,将视图作为临时表,然后操作它
#事务
CREATE TABLE zj_School(
id INT PRIMARY KEY AUTO_INCREMENT,
cz_money DECIMAL(10,2) COMMENT '班费'
)ENGINE INNODB CHARACTER SET utf8;
INSERT INTO zj_School VALUES(NULL,1250);
SELECT * FROM zj_School;
CREATE TABLE zj_Student(
id INT PRIMARY KEY AUTO_INCREMENT,
stu_money DECIMAL(10,2) COMMENT '生活费'
)ENGINE INNODB CHARACTER SET utf8;
INSERT INTO zj_Student VALUES(NULL,5000);
SELECT * FROM zj_Student;
#班费30
UPDATE zj_Student SET stu_money = stu_money - 30 WHERE id = 1;
UPDATE zj_School SET cz_money = cz_money + 30 WHERE id = 1;
#是否提交
SET autocommit = 1;
SHOW VARIABLES LIKE 'autocommit';
#成功commit
#失败rollback一般不用这种方式操作事务,会影响别的操作
#开启事务
START TRANSACTION;
#提交
COMMIT;
#事务在innodb或者DBD两种存储引擎中生效
#1,原子性,即同时成功或者同时失败
#2,一致性,你在一个数据库连接里开启了事务,若是没有进行操作,可以在其他连接中操作,但是,一旦你在
#开启事务的连接中操作了某张表而没有提交,此时无法再其他连接中操作该表
#3,隔离性,事务之间不会相互影响
#4,持久性,一旦提交,永久生效(ACID事务特点)
#触发器
#Create trigger 名字 事件 执行代码
#触发不包括查询,即事件关键字三种insert,delete,update,执行时机两种After,before,组合一起共六种事件
#old和new获取事件操作的数据
#insert不能使用old
#delete不能使用new
#1,触发器不能同名
#2,目前mysql只支持一类事件设置一个触发器
CREATE TRIGGER pay_cost AFTER UPDATE ON zj_student
FOR EACH ROW
UPDATE zj_school SET cz_money = cz_money + 20;
UPDATE zj_student SET stu_money = stu_money - 40 WHERE id = 1;
SHOW CREATE TRIGGER pay_cost;
DROP TRIGGER pay_cost;
CREATE TRIGGER pay_cost AFTER UPDATE ON zj_student
FOR EACH ROW
UPDATE zj_school SET cz_money = cz_money + (old.stu_money - new.stu_money);
#如果多条sql语句,需要使用特殊字符
DELIMITER $$
CREATE TRIGGER ruxue AFTER INSERT ON zj_student
FOR EACH ROW
BEGIN
UPDATE zj_school SET stu_count = stu_count+1;
UPDATE zj_school SET stu_money = stu_money+20;
END
$$
DELIMITER;
#sql编程
SELECT NOW();
SHOW VARIABLES LIKE 'char%';
#定义变量set 变量名 = 变量值;为了区分系统和自定义变量,需要在变量前加上@
SET @who = '李想';
SELECT @who;
#into注入
SELECT 10,20,30 INTO @a,@b,@c;#该方式可以查询注入
SELECT @who := '小李';#赋值
SELECT @who = '大李';#判断语句
#变量有效期:连接中断,作用域:用户定义是全局,函数内部是局部
SELECT @a,@b,@c;
SELECT RAND();#1到0之间的随机数,mysql各种内置函数自己百度了解
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP());
SELECT NOW();
SELECT LENGTH('sdbasjd');
SELECT LENGTH('字节数');#utf8三字节
SELECT CHAR_LENGTH('字符数');
SELECT SUBSTRING('中国好声音',3,3);#位置从1开始
SELECT LPAD('1',4,'0');#补足位数,从左边开始
SELECT RPAD('2',3,'0');#右边开始
SELECT MD5('1');#加密函数
SELECT PASSWORD('1');
#自定义函数(存储函数)create function 函数名(参数列表) 返回值类型 函数体
DELIMITER $$
CREATE FUNCTION sayHello() RETURNS VARCHAR(20)
BEGIN
RETURN 'Hello World!';
END
$$
DELIMITER;
SELECT sayHello();
#sql中的流程控制
DELIMITER $$
CREATE FUNCTION fun1() RETURNS VARCHAR(20)
BEGIN
IF HOUR(NOW()) > 18 THEN
RETURN '晚';
ELSE
RETURN '早';
END IF;
END
$$
DELIMITER;
SELECT fun1();
DROP FUNCTION IF EXISTS fun2;
DELIMITER $$
CREATE FUNCTION fun2() RETURNS INT
BEGIN
SET @i = 1;
SET @sun = 0;
WHILE @i <= 10 DO
SET @sun = @sun + @i;
SET @i = @i + 1;
END WHILE;
RETURN @sun;
END
$$
DELIMITER;
SELECT fun2();
#循环提前终止,退出循环和java不同,不是由位置决定,而是由标签决定
#leave 相当于 break
#iterate 相当于 continue
DELIMITER $$
CREATE FUNCTION fun3() RETURNS INT
BEGIN
SET @i = 1;
SET @sun = 0;
w:WHILE @i <= 10 DO
IF @i = 5 THEN
LEAVE w;
END IF;
SET @sun = @sun + @i;
SET @i = @i + 1;
END WHILE w;
RETURN @sun;
END
$$
DELIMITER;
SELECT fun3();
DELIMITER $$
DROP FUNCTION IF EXISTS fun4;
CREATE FUNCTION fun4(u_name VARCHAR(10)) RETURNS VARCHAR(20)
BEGIN
RETURN CONCAT('hello',u_name);
END
$$
DELIMITER;
SELECT fun4('你好');
SHOW CREATE FUNCTION fun4;
#where和having一样,不过where条件作用于表,而having作用于查询后的结果集
SELECT * FROM itcast_student WHERE class_id = 3 HAVING stu_name = '流云';
#四大索引
#普通索引 (index)
#主键索引 (primary key)
#唯一索引 (unique)
#全文索引 (fulltext)