在数据中,建表处理是很常见且很实用的方法。
1:N
N:N
三种方式。
1对1的方式
示例:一夫一妻
思考:在一个表中保存着所有人的信息。有男有女,要求查询出所有的夫妻,即一男一女。
注意下面:王五是光棍不应该能查询出来。
CREATE TABLE person(
id INT,
NAME VARCHAR(10),
sex CHAR(1),
wife INT,
husband INT
);
INSERT INTO person VALUES(1,'小花','0',0,3);
INSERT INTO person VALUES(2,'玉芬','0',0,4);
INSERT INTO person VALUES(3,'张三','1',1,0);
INSERT INTO person VALUES(4,'李四','1',2,0);
INSERT INTO person VALUES(5,'王五','1',0,0);
//一对一关系的操作:查出每对夫妻的姓名
CREATE VIEW w AS SELECT * FROM person WHERE sex='0';
CREATE VIEW m AS SELECT * FROM person WHERE sex='1';
//不利用表与表之间的关系
SELECT w.NAME AS 妻子, m.NAME AS 丈夫 FROM w,m WHERE w.husband=m.id AND m.wife=w.id;
//现在更先进的方式:利用表间的关系
SELECT w.NAME AS 妻子, m.NAME AS 丈夫 FROM w INNER JOIN m ON w.husband=m.id AND m.wife=w.id;
1对多的方式
1对多,多对1。
一个人可以拥有多辆汽车,要求查询出某人所拥有的所有汽车。
根据范式的要求,应该设计两张表,分别表示人的信息和汽车的信息。
//步骤1:画E-R图
//步骤2:分别建实体表,并给多方的表添加外键约束
CREATE TABLE person2(
id VARCHAR(32) PRIMARY KEY,
pname VARCHAR(30),
sex CHAR(1)
);
CREATE TABLE car(
id VARCHAR(32) PRIMARY KEY,
cname VARCHAR(30),
price NUMERIC(10,2),
pid VARCHAR(32),
CONSTRAINT car_fk FOREIGN KEY(pid) REFERENCES person2(id)
);
DROP TABLE car;
//步骤3:为两个表添加测试数据
//实体表1
INSERT INTO person2(id,pname,sex) VALUES('P001','Jack','1');
INSERT INTO person2(id,pname,sex) VALUES('P002','Tom','1');
INSERT INTO person2(id,pname,sex) VALUES('P003','Rose','0');
INSERT INTO person2(id,pname,sex) VALUES('P004','Mary','0');
INSERT INTO person2(id,pname,sex) VALUES('P005','Mike','1');
SELECT * FROM person2;
////实体表2
INSERT INTO car(id,cname,price,pid) VALUES('C001','BMW',123.5,'P001');
INSERT INTO car(id,cname,price,pid) VALUES('C002','Benz',123.5,'P001');
INSERT INTO car(id,cname,price,pid) VALUES('C003','BMW',223.5,'P001');
INSERT INTO car(id,cname,price,pid) VALUES('C011','BMW',83.5,'P003');
INSERT INTO car(id,cname,price,pid) VALUES('C012','Benz',100,'P003');
INSERT INTO car(id,cname,price,pid) VALUES('C013','Audi',223.5,'P003');
INSERT INTO car(id,cname,price,pid) VALUES('C021','BMW',88.5,'P004');
INSERT INTO car(id,cname,price,pid) VALUES('C022','QQ',10,'P004');
INSERT INTO car(id,cname,price,pid) VALUES('C023','Audi',73,'P005');
INSERT INTO car(id,cname,price) VALUES('C033','Audi',1000);
/查询:哪些人有什么样的车 (用"表名.列名"的形式访问列,如果列名不重复,可以省略表名)
//利用一方的主键和“多方”的外键进行关联
SELECT person2.pname,car.cname FROM person2,car WHERE person2.id=car.pid;
//查询Jack有什么车
SELECT person2.pname,car.cname FROM person2,car WHERE person2.id=car.pid AND person2.pname='Jack' ;
//查询哪些人有两辆以上的车
SELECT person2.pname,COUNT(pname) AS 车数量 FROM person2,car WHERE person2.id=car.pid GROUP BY pname HAVING COUNT(pname)>=2 ORDER BY 车数量;
SELECT * FROM person2 WHERE id IN ( SELECT pid FROM car GROUP BY pid HAVING COUNT(pid)>=2 );
//查询哪些人没有车
SELECT * FROM person2 WHERE id NOT IN( SELECT pid FROM car );
多对多
多对多:
一个人可以拥有多种角色,如某人,即是父亲、又是儿子、又是丈夫。而同时这三个角色又可以给其他所有的人。
要求查询出即是父亲、又是儿子、又是丈夫的所有人。
查询出所有人拥有的所有角色。
还有学生选课系统都是多对多的情况
具体的实现方法在最后的比笔记中贴出来
三种方式:
“DELIMITER$$”这句是为了让解析器把“$$”当作结束标志(否则默认是把“;“号当作结束标记),这样存储过程中的语句结束符";"就不会当作过程的结束标记。
DELIMITER$$
CREATE PROCEDURE p1()
BEGIN
SELECT * FROM stud;
INSERT INTO stud(id,sname,age,score,dept) VALUES(1014,'刘三丰',33,55,'通信学院');
END$$
DELIMITER; //把结束标记还原回来
CALL p1(); //调用存储过程p1
//带参数的存储过程
DELIMITER$$
CREATE PROCEDURE p2(IN id INT, IN nm VARCHAR(30) )
BEGIN
INSERT INTO stud(id,sname) VALUES(id,nm);
END$$
DELIMITER ;
DROP PROCEDURE p2;
CALL p2(1015,'吊丝');
//有返回值的存储过程----参数与变量问题( @变量名 ,一个@为用户变量,两个@即 @@为全局的系统变量 )
DELIMITER$$
CREATE PROCEDURE p3(IN id INT, IN nm VARCHAR(30), OUT num INT )
BEGIN
INSERT INTO stud(id,sname) VALUES(id,nm);
SELECT COUNT(*) INTO num FROM stud;
END$$
DELIMITER ;
CALL p3(1016,'无名',@aa);
SELECT @aa; //输出变量aa的值
mysql查询默认是不区分大小写的 如:
select * from table_name where a like 'a%'
select * from table_name where a like 'A%'
select * from table_name where a like 'a%'
select * from table_name where a like 'A%'
效果是一样的。
要让mysql查询区分大小写,可以:
select * from table_name where binary a like 'a%'
select * from table_name where binary a like 'A%'
select * from table_name where binary a like 'a%'
select * from table_name where binary a like 'A%'
也可以在建表时,加以标识
create table table_name(
a varchar(20) binary
)
※事务处理
START TRANSACTION
DELETE FROM stud WHERE id=1015;
DELETE FROM stud WHERE id=1014;
SELECT * FROM stud;
ROLLBACK / COMMIT;