PRIMARY KEY 主键,不能重复,唯一确定一条记录(unique+not null)
表中的任何列都可以作为主键,只要它满足一下条件:
1、任意两行都不具有相同的主键值
2、每一行都必须具有一个主键值(主键列不允许空置NULL)
3、主键列中的值不允许修改或更新
主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)
AUTO INCREMENT 自动增长
varchar(10)char(10)区别
相同点:都可以最大放10个字符
不同点:char(10)不管输入的是多少都会占10个字符,例如输入名字“张三”只有两个字符
但是使用char(10)在数据库里面还是占10个字符的空间。
使用varchar(10)最大支持是10个字符,但是实际长度就是输入字符长度,例如输入名字“张三”只有两个字符
那么在varchar(10)里面就只占两个字符。
字段属性设置:
1、not null:不为空,表示该字段不能放“null”这个值。不写,则默认是可以为空
2、auto_increment: 设定int类型字段的值可以“自增长”,即其值无需“写入”,而会自动获得并增加
此属性必须随同 primary key 或 unique key 一起使用。primary key = unique key + not null
3、[primary] key: 设定为主键。是唯一键”加强”:不能重复并且不能使用null,并且可以作为确定任意一行数据的“关键值”,最常见的类似:where id=8;或where user_name ='zhangsan';
通常,每个表都应该有个主键,而且大多数表,喜欢使用一个id并自增长类型作为主键。
但:一个表只能设定一个主键。
4、unique [key]:设定为唯一键:表示该字段的所有行的值不可以重复(唯一性)。
Duplicate entry 'zhangsan' for key 'name' 如果出现重复值
5、defaut '默认值’: 设定一个字段在没有插入数据的时候自动使用的值。
6、comment'字段注释’
-- 列出所有数据库
SHOW DATABASES;
-- 创建数据库
CREATE DATABASE `ttt` DEFAULT CHARACTER SET `utf8`;
-- 删除数据库
DROP DATABASE ttt;
-- 数据库表的操作
-- 切换数据库
USE study;
-- 创建表
CREATE TABLE student(
`id` INT,
`name` char(10),
age INT,
gender char(1)
);
-- 查看所有表
SHOW TABLES;
-- 查看表结构
DESC student; -- description
DROP TABLE teacher;-- 删除表
-- 修改表结构
ALTER TABLE student ADD COLUMN address CHAR(10);-- 添加列
ALTER TABLE student DROP COLUMN address;-- 删除列
ALTER TABLE student CHANGE address addr CHAR(20) -- 修改列名
-- 修改表的名字
ALTER TABLE student RENAME TO stu;-- 修改表名
-- 基本的增删改查+创建表 查询类最重要
-- 数据库表的操作
CREATE TABLE student(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` char(10),
age INT,
gender char(1)
);
-- 查询语句
SELECT * FROM student
-- 插入数据
INSERT INTO student(name,age,gender) VALUES(1,"张三",18,'男')
INSERT INTO student(name,age,gender) VALUES(2,"李四",18,'男')
INSERT INTO student VALUES(1,'刘子',38,'男')
-- 一条sql插入多条数据
INSERT INTO student(name,age,gender) VALUES('六子',19,'男'),('七子',20,'女')
-- 修改操作
UPDATE student SET age=age+1 WHERE name='张三';
-- 删除操作
DELETE FROM student; -- 删除表中所有的数据
DELETE FROM student WHERE name='七子';
DELETE FROM student WHERE age=20;
DELETE FROM student WHERE id IN(1,6);
DELETE FROM student WHERE id=2 OR id=5;
TRUNCATE TABLE student;-- 清除表,id从0开始truncate
-- 查询语句
SELECT * FROM student
-- 查询时候添加常量列
SELECT id,name,age,gender,'java2501' FROM student;
SELECT id,name,age,gender,'java2501' AS '班级' FROM student;
SELECT id,name,age,gender AS '性别','java2501' AS '班级' FROM student;
SELECT id,name,age,gender '性别','java2501' AS '班级' FROM student; -- AS可以省略
-- 查询成绩和
SELECT id,name,(java+php) AS '总成绩' from student;
-- 查询时去掉重复数据
SELECT DISTINCT address from student; -- distinct
-- 条件查询where
SELECT * FROM student WHERE name='六子'
-- 逻辑条件:and(同时成立) or(只有一个成立)
SELECT * FROM student WHERE name='六子' AND address='青岛'
SELECT * FROM student WHERE name='六子' OR name='四子'
-- 比较运算: > < >= <= != 不等于也可以写成<>
SELECT * FROM student WHERE java>=70 AND java <=90
-- between and (等于>= and <=)
SELECT * FROM student WHERE java BETWEEN 70 AND 90;
-- 查询不是青岛的学生地址
SELECT * from student WHERE address !='青岛';
SELECT * from student WHERE address <>'青岛';
-- 空值null
SELECT * from student where address is NULL;
SELECT * from student where address is NOT NULL;
-- 聚合查找
-- 聚合查找函数sum(),avg(),min(),max(),count()
-- 统计学成php的总成绩
SELECT SUM(php) AS 'php总成绩' FROM student;
SELECT AVG(php) AS 'php平均成绩' FROM student;
SELECT MIN(php) AS 'php最低成绩' FROM student;
SELECT MAX(php) AS 'php最高成绩' FROM student;
SELECT COUNT(*) AS '总人数' FROM student ;
-- 查询排序 desc 降序 asc升序
SELECT * from student ORDER BY php;
SELECT * from student ORDER BY php ASC;
SELECT * from student ORDER BY php DESC;
SELECT * from student ORDER BY php ASC,java DESC; -- 根据php升序排列,如果成绩相同,再降序排列
-- 分组查询男女的人数
-- 要求:查询男女分别有多少人
SELECT gender AS '性别',COUNT(*) AS '人数' FROM student GROUP BY gender;
-- 分组之后的条件用having
SELECT gender AS '性别',COUNT(*) AS '人数' FROM student GROUP BY gender HAVING COUNT(*)>1;
CREATE TABLE teacher(
id INT PRIMARY KEY AUTO_INCREMENT,
name CHAR(10) NOT NULL,
age INT COMMENT '年龄',-- 备注
address CHAR(10) DEFAULT '中国', -- 默认值
UNIQUE KEY(name)
);
TRUNCATE teacher;
SELECT * FROM teacher
学生表、班级表、课程表、班级课程表
一对一、一对多、多对多
CREATE TABLE student(
id int PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) NOT NULL,
age INT,
gender CHAR(1),
banji_id INT,
FOREIGN KEY(banji_id) REFERENCES banji(id)
);
-- 班级课程表
CREATE TABLE banji_course(
banji_id INT,
course_id INT,
PRIMARY KEY(banji_id,course_id),-- 联合主键
FOREIGN KEY(banji_id) REFERENCES banji(id),-- banji_id即使联合主键又是外键
FOREIGN KEY(course_id) REFERENCES course(id)
);
-- 多表连接
CREATE TABLE banji(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) NOT NULL
);
INSERT INTO banji(name) VALUES('java1807'),('java1812')
CREATE TABLE student(
id int PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) NOT NULL,
age INT,
gender CHAR(1),
banji_id INT,
FOREIGN KEY(banji_id) REFERENCES banji(id)
);
INSERT INTO student(name,age,gender,banji_id)
VALUES ('张三',20,'男',1),('李四',21,'男',2),('王五',20,'女',1);
SELECT * FROM student
-- 课程表
CREATE TABLE course(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) NOT NULL,
credit INT COMMENT '学分'
);
SELECT* FROM course;
INSERT INTO course(name,credit) VALUES('java',5),('UI',4),('H5',4);
SELECT* FROM course;
-- 班级课程表
CREATE TABLE banji_course(
banji_id INT,
course_id INT,
PRIMARY KEY(banji_id,course_id),-- 联合主键
FOREIGN KEY(banji_id) REFERENCES banji(id),-- banji_id即使联合主键又是外键
FOREIGN KEY(course_id) REFERENCES course(id)
);
INSERT INTO banji_course(banji_id,course_id) VALUES(1,1),(1,3),(2,1),(2,2),(2,3);
SELECT * FROM banji_course;
-- 子查询:嵌套查询一个查询语句结果是另一个查询语句的条件
-- 查询班级是Java1812班所有学生信息
SELECT * from banji;
SELECT id FROM banji WHERE name='java1812'
SELECT * FROM student WHERE banji_id=(SELECT id FROM banji WHERE name='java1812');
-- 班级是java1807班或者java1812班所有学生信息
SELECT id FROM banji WHERE name='java1807' OR name='java1812'; -- 1或2
SELECT * FROM student WHERE banji_id IN (1,2)
SELECT * FROM student WHERE banji_id IN(SELECT id FROM banji WHERE name='java1807' OR name='java1812');
-- 查询班级id 班级姓名,班级人数
SELECT id,name,(SELECT COUNT(*) FROM student WHERE student.banji_id = banji.id) AS 'total_count'
FROM banji
笛卡尔积
由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将时第一个表中的行数乘以第二个表中的行数。通俗的说就是查询所得的结果行数是两张表行数的乘积。
等值连接
笛卡尔积给个条件
SELECT * from student,banji;
-- 等值连接
SELECT * from student,banji WHERE student.banji_id = banji.id;
等值连接和内连接的效果一样,但是开发中建议使用内连接
-- 内连接
SELECT * FROM student as stu INNER JOIN banji AS bj WHERE stu.banji_id = bj.id;
SELECT bj.id,bj.name,COUNT(*) FROM banji as bj INNER JOIN student AS stu ON bj.id=stu.banji_id GROUP BY stu.banji_id;
-- 内连接学生姓名 班级名称 课程名称 学分
SELECT s.`name` AS '学生姓名',b.`name` AS '班级名称',c.`name` AS '课程名称',c.credit AS '学分' FROM student AS s INNER JOIN banji AS b
ON s.banji_id=b.id INNER JOIN banji_course AS bj
ON b.id=bj.banji_id INNER JOIN course AS c ON bj.course_id = c.id
inner join on 只有左右两个表有关联的才查询出来
left join on 左表中都显示出来,右表没有显示空
right join on 右表都显示,左表没有显示空
语法形式:字段 like"要查找字符
说明:
3语法:like"%关键字%
--以张开头
SELECT * FROM student WHERE name LIKE '张%';
SELECT * FROM student WHERE name LIKE '张_';--以张开头,而且名字是两个字
SELECT * FROM student WHERE name LIKE '%张%';--名字里面只要有张就可以
注意: NULL
通配符%看起来像是可以匹配任何东西,但有个例外,这就是NULL,
SELECT * FROM student WHERE name LIKE '%';
不会匹配name为NULL的行
注意
SQL的通配符很有用,但这种功能是有代价的,即通配符搜索要消耗更长的处理时间,使用通配符的技巧:
1、不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
2.在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始处"%张。把通配符置于开始处,搜索起来是最慢的。