表中数据的增加用insert into,修改update,删除delete这两个一般加上限定条件WHERE
DQL中NULL不能用“==” 等运算符判读,需要使用IS/IS NOT
where与hanving限定的区别,在分组查询中,where限定是在分组之前,不满足条件不参与分组,having限定是在分组之后,不满足条件不会被查询出来。
where 后不能进行聚合函数的判断,having可以
修改表,进行数据项约束:
alter table 表名 modify 列名 数据类型 NOT NULL;
mysql中,唯一约束限定的列的值可以有多个null
删除特例
删除主键约束:ALTER TABLE stu DROP PRIMARY KEY;
删除唯一约束:ALTER TABLE stu DROP INDEX 列名;
什么是SQL?
Structured Query Language:结构化查询语言
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
SQL通用语法
SQL分类
1) DDL(Data Definition Language)数据定义语言
用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
2) DML(Data Manipulation Language)数据操作语言
用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
3) DQL(Data Query Language)数据查询语言
用来查询数据库中表的记录(数据)。关键字:select, where 等
4) DCL(Data Control Language)数据控制语言(了解)
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等
create table student(
id int,
name varchar(32),
age int ,
score double(4,1),
birthday date,
insert_time timestamp
);
分类:
CREATE TABLE stu(
id INT,
NAME VARCHAR(20) NOT NULL -- name为非空
);
CREATE TABLE stu(
id INT,
phone_number VARCHAR(20) UNIQUE -- 添加了唯一约束
);
-- * 注意mysql中,唯一约束限定的列的值可以有多个null
create table stu(
id int primary key,-- 给id添加主键约束
name varchar(20)
);
sql create table 表名( .... 外键列 constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称) );
select * from 表名; -查询表中所有数据
语法:
select
字段列表,有几个显示几列
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
如果该字段为null后的替换值。
SELECT NAME,math,English,math+IFNULL(English,0) FROM student;
-- 查询年龄大于20岁
SELECT * FROM student WHERE age > 20;
-- 查询年龄等于20岁
SELECT * FROM student WHERE age = 20;
-- 查询年龄不等于20岁
SELECT * FROM student WHERE age != 20;
SELECT * FROM student WHERE age <> 20;
-- 查询年龄大于等于20 小于等于30
SELECT * FROM student WHERE age >= 20 && age <=30;
SELECT * FROM student WHERE age >= 20 AND age <=30;
SELECT * FROM student WHERE age BETWEEN 20 AND 30;
-- 查询年龄22岁,18岁,25岁的信息
SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25
SELECT * FROM student WHERE age IN (22,18,25);
-- 查询英语成绩为null
SELECT * FROM student WHERE english = NULL; -- 不对的。null值不能使用 = (!=) 判断
SELECT * FROM student WHERE english IS NULL;
-- 查询英语成绩不为null
SELECT * FROM student WHERE english IS NOT NULL;
-- 查询姓马的有哪些? like
SELECT * FROM student WHERE NAME LIKE '马%';
-- 查询姓名第二个字是化的人
SELECT * FROM student WHERE NAME LIKE "_化%";
-- 查询姓名是3个字的人
SELECT * FROM student WHERE NAME LIKE '___';
-- 查询姓名中包含德的人
SELECT * FROM student WHERE NAME LIKE '%德%';
默认升序:ASC
SELECT NAME FROM student
ORDER BY age ASC;
练习,先按数学成绩排,若成绩相同,再按英语成绩
SELECT NAME FROM student
ORDER BY math ASC,English ASC;
格式:Count(字段名)
SELECT COUNT(NAME) AS 人数
FROM student;
加上NULL的个数:1. 用非空字段主键 2.count(*) 3.如下
SELECT COUNT(IFNULL(NAME,0) AS 人数
FROM student;
练习:按照性别分组,分别查询男和女的人数,聚合函数的字段使用主确保非NULL
SELECT sex,COUNT(学号) AS 人数
FROM student
GROUP BY sex;
练习:选择满足条件的记录参与分组,由字段进行筛选,如下查询姓王男的人数和女的人数
SELECT sex,COUNT(学号) AS 人数
FROM student
WHERE name = "王"
GROUP BY sex;
HAVING练习:分别查询男和女分数在平均分以上的人数,且只显示人数于2的那一类
SELECT sex,COUNT(id) AS 人数
FROM student
WHERE score >(
SELECT AVG(score)
FROM student
)
GROUP BY sex HAVING COUNT(id) > 2;
语法:limit 开始的索引,每页查询的条数
练习:显示第一页,每页显示三条
SELECT * FROM student LIMIT 0,3;
索引位置=(当前页数码-1)*显示条数
显示第1,2,3条记录,3为显示条数
分页操作在不同语言中操作方式不一样
-- 查询所有员工信息和对应的部门信息
SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
-- 查询员工表的名称,性别。部门表的名称
SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
-- 用别名
SELECT
t1.name, -- 员工表的姓名
t1.gender,-- 员工表的性别
t2.name -- 部门表的名称
FROM
emp t1, -- 别名t1
dept t2t1 -- 别名t2
WHERE
t1.`dept_id` = t2.`id`;
SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;
SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`;
sql -- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称 SELECT t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`; -- 其中t1为左表,t2为右表
SELECT *
FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;
-- 查询工资最高的员工信息
-- 1 查询最高的工资是多少 9000
SELECT MAX(salary) FROM emp;
-- 2 查询员工信息,并且工资等于9000的
SELECT * FROM emp WHERE emp.`salary` = 9000;
-- 一条sql就完成这个操作。子查询
SELECT * FROM emp WHERE emp.`salary` = (SELECT MA (salary) FROM emp);
-- 查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
-- 查询'财务部'和'市场部'所有的员工信息
SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;
-- 子查询
SELECT *
FROM emp
WHERE dept_id IN
(SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');
-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
-- 子查询
SELECT *
FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
WHERE t1.id = t2.dept_id;
-- 普通内连接
SELECT * FROM emp t1,dept t2
WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` > '2011-11-11'
修改用户密码:
-- 第一种
UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';
UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';
-- 第二种
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');
查询用户:
-- 1. 切换到mysql数据库
USE myql;
-- 2. 查询user表
SELECT * FROM USER;
-- 查询权限
SHOW GRANTS FOR '用户名'@'主机名';
SHOW GRANTS FOR 'lisi'@'%';
-- 授予权限,权限列表有SELECT,DELETE,UPDATE
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
-- 若授予所有权限,则为ALL
-- 给张三用户授予所有权限,在任意数据库任意表(*.*)上
GRANT ALL ON *.* TO 'zhangsan'@'localhost';
-- 撤销权限:
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
-- 撤销修改权限
REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';
-- 创建一张账户表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
-- 添加数据
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
-- 张三给李四转账 500 元
-- 0. 开启事务
START TRANSACTION;
-- 1. 张三账户 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 2. 李四账户 +500
-- 若在这出错了...会回滚
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
-- 发现执行没有问题,提交事务,若没有提交事务会自动回滚
COMMIT;
-- 发现出问题了,回滚事务
ROLLBACK;
演示:
-- 设置隔离级别
set global transaction isolation level read uncommitted;
-- 打开两个窗口开启事务,第一个窗口update修改数据,另一个窗口查询读到未提交(commit)的数据(数据改变),出现脏读
-- 然后再第一个事务rollback(转账撤销),另一个窗口再查询发现数据还原,即不可重复度问题
-- 解决脏读方案:
set global transaction isolation level read committed;
-- 第一个窗口修改了数据,第二个窗口查询发现数据没有改变
-- 此时第一个窗口commit,第二个窗口查询发现数据改变,同一个事务查询的数据不一样出现不可重复读问题
-- 解决脏读和不可重复读问题
set global transaction isolation level repeatable read;
-- 第一个窗口的事务提交改变,不影响第二个窗口事务的数据查询,只有在第二个窗口也提交事务后,方可正确查询数据
-- 开启事务
start transaction;
-- 转账操作
update account set balance = balance - 500 where id = 1;
update account set balance = balance + 500 where id = 2;
-- 创建旅游线路分类表 tab_category
-- cid 旅游线路分类主键,自动增长
-- cname 旅游线路分类名称非空,唯一,字符串 100
CREATE TABLE tab_category (
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(100) NOT NULL UNIQUE
);
-- 创建旅游线路表 tab_route
/*
rid 旅游线路主键,自动增长
rname 旅游线路名称非空,唯一,字符串 100
price 价格
rdate 上架时间,日期类型
cid 外键,所属分类
*/
CREATE TABLE tab_route(
rid INT PRIMARY KEY AUTO_INCREMENT,
rname VARCHAR(100) NOT NULL UNIQUE,
price DOUBLE,
rdate DATE,
cid INT,
FOREIGN KEY (cid) REFERENCES tab_category(cid)
);
/*创建用户表 tab_user
uid 用户主键,自增长
username 用户名长度 100,唯一,非空
password 密码长度 30,非空
name 真实姓名长度 100
birthday 生日
sex 性别,定长字符串 1
telephone 手机号,字符串 11
email 邮箱,字符串长度 100
*/
CREATE TABLE tab_user (
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) UNIQUE NOT NULL,
PASSWORD VARCHAR(30) NOT NULL,
NAME VARCHAR(100),
birthday DATE,
sex CHAR(1) DEFAULT '男',
telephone VARCHAR(11),
email VARCHAR(100)
);
/*
创建收藏表 tab_favorite
rid 旅游线路 id,外键
date 收藏时间
uid 用户 id,外键
rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏 个线路两次
*/
CREATE TABLE tab_favorite (
rid INT, -- 线路id
DATE DATETIME,
uid INT, -- 用户id
-- 创建复合主键
PRIMARY KEY(rid,uid), -- 联合主键
FOREIGN KEY (rid) REFERENCES tab_route(rid),
FOREIGN KEY(uid) REFERENCES tab_user(uid)
);
具体实现如下
元数据
经1NF规范后 -保证了原子性
经2NF规范后 -消除部分依赖(拆分表)
经3NF规范后 -消除传递依赖(继续拆分)
原文:https://www.cnblogs.com/huxiaobai/p/11743326.html