1 指明外键: 2 1 :1 3 两个表中的主键都可以当成外键 4 1 :N 5 在 "多" 的实体表中新增加一个字段,该字段是 "一" 实体表的主键 6 M : N 7 拆成两个1 :N的关系 8 在 "多" 的实体表中新增加一个字段,该字段是 "一" 实体表的主键、 9 10 逻辑模型---->用SQL实现数据库 11 create database yr; 12 13 use yr; 14 在students表中增加两个限制; 15 1.not null非空限制 16 2.primary key 主键限制 17 create table students( 18 -> s_id int not null primary key, 19 -> name varchar(20), 20 -> gender varchar(20), 21 -> age int, 22 -> address varchar(50) 23 -> ); 24 25 create table teachers( 26 -> name varchar(20) not null primary key, 27 -> gender varchar(20), 28 -> rank varchar(20) 29 -> ); 30 rank 级别 31 gender 性别 32 33 create table textbooks( 34 -> ISBN varchar(20) not null primary key, 35 -> name varchar(20), 36 -> auther varchar(20), 37 -> publisher varchar(20) 38 -> ); 39 author 作者 40 publisher 出版社 41 textbook 教材 42 43 create table courses( 44 -> c_id int not null primary key, 45 -> name varchar(20), 46 -> credit int, 47 -> instructor varchar(20), 48 -> ISBN varchar(20), 49 -> foreign key(instructor) references teachers(name), 50 -> foreign key(ISBN) references textbooks(ISBN) 51 -> ); 52 instructor 授课教师 53 credit 学分 54 references 关联 55 foreign key 外键 56 57 create table registration( 58 -> s_id int not null, 59 -> c_id int not null, 60 -> term varchar(20), 61 -> grade decimal(4,1), 62 -> primary key(s_id,c_id), 63 -> foreign key(s_id) references students(s_id), 64 -> foreign key(c_id) references courses(c_id) ); 65 66 insert into students values(1,"Ann","F",21,"beijing"); 67 68 insert into textbooks values("00000","Intro to SQL","Yang","Renmin Press"); 69 70 insert into teachers values("Yang","F","Instructor"); 71 72 insert into courses values("1","Databases",3,"Yang","00000"); 73 74 insert into registration values(1,1,201711,93.0); 75 76 insert into students values(2,"Bob","M",23,NULL); 77 错误的 s_id是主键不能重复 78 insert into students values(2,"ob","M",23,NULL); 79 ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' 提示2重复 80 81 注意:SQL中,空值是null 82 83 思考题:************ 84 1.查询students表中,地址为空的学生信息 85 select * from students where address is null;[当为null的时候不能用=必须使用is] 86 2.查询students表中,地址不为空的学生信息 87 select * from students where address is not null; 88 89 演示foreign key限制错误: 90 insert into courses values("2","python",3,"wei","10000");[老师的值一定是teacher表中应该有的老师,如果没有报错,这个外键是teachers中的主键] 91 92 insert into teachers values("Wei","M","Instructor"); 93 94 insert into textbooks values("10000","Intro to python","Guido","Beijing Press"); 95 96 规范化: 97 第一范式: 98 1.消除重复的行和列 99 2.定义主键,唯一标识所有记录 100 3.所有其他字段必须直接或间接的依赖于主键 101 4.所有字段必须只包含一个值 102 5.每个字段中的所有值必须是相同的数据类型 103 第二范式: 104 1.表必须处于1NF中 105 2.所有非键值必须完全函数依赖于主键 106 3.当主键为复合键时,必须删除部分依赖 107 108 高级SQL: 109 create table orde( 110 -> o_id int not null, 111 -> o_name varchar(50), 112 -> date datetime, 113 -> c_id int, 114 -> amount decimal(10,2) 115 -> ); 116 117 118 insert into orde values(100,"computer","2011-11-1 12:34:56",1,8800); 119 insert into orde values 120 (101,"iphone","2011-10-10 15:20:56",3,6600), 121 (103,"ipad","2017-9-13 09:34:45",4,450), 122 (104,"pen","2016-10-18 15:20:56",3,6600), 123 (105,"iphone","2015-11-10 16:20:56",5,6000), 124 (106,"ipad","2014-09-12 14:20:56",2,10000); 125 126 joins 127 利用两个表中共同含有的列的相同值来连接 128 129 select 列名 from 第一个表,第二个表 130 where 第一个表.列名 = 第二个表.列名 131 132 select id,name,salary,o_name,amount from customers,orde where customers.id =orde.c_id; 133 134 select id,name,salary,o_name,amount from customers,orde;[就变成笛卡尔积了就是两个表格的所有组合] 135 136 练习; 137 打印出顾客消费额度超过其工资的人员名单和工资信息以及消费额度 138 select id,name,salary,amount from customers,orde where (customers.salary < orde.amount)and(customers.id =orde.c_id); 139 140 子查询;嵌入到另一个select语句中的select语句 141 142 select 列名或者表达式 from 表名 where 表达式 比较操作符{all|any}(子查询语句);[子查询语句一定是select语句] 143 1.返回单值的子查询 144 select * from customers where customers.id =(select c_id from orde where o_id=100); 145 等同于 146 select c.id,c.name,c.age,c.address,c.salary from customers as c,orde as o where c.id = o.c_id and o.o_id=100; 147 148 select c.id,c.name,c.age,c.address,c.salary from customers as c[这个是重命名相当于customers=c],orde as o where c.id = o.c_id and o.o_id=100; 149 150 2.返回多值的子查询 151 select * from customers where customers.id in (1,2,3); 152 153 select * from customers where customers.id in (select c_id from orde where amount>5000); 154 [顾客的身份的id在所有订单消费大于5000的c_id中 ] 155 练习: 156 选出地址在北京或者上海的顾客,该顾客消费7000元 157 select * from customers where customers.id in (select c_id from orde where amount>7000 ) and(address="beijing" or "shanghai" ); 158 159 子查询与聚合函数配套练习:************ 160 选择消费最少的顾客信息 161 select * from customers where customers.id =(select c_id from orde where amount=(select min(amount) from orde)); 162 select * from customers where customers.id =(select c_id from orde order by amount asc limit 1); 163 打印出orde表中amount的最小值 164 select min(amount) from orde; 165 select c_id from orde where amount=450; 166 167 选择工资salary最少的顾客的信息 168 select * from customers where salary= (select min(salary) from customers); 169 170 all/any和子查询的用法 171 select * from customers where age > any(24,25,27); 172 select * from customers where age > all(24,25,27); 173 174 insert 语句嵌套子查询: 175 insert into 表名[列名1,列名2,....列名n] values(value1,value2,....valuen); 176 177 insert into 表名[列名1,列名2,....列名n] select [列名1,列名2,....列名n] from 表名 [where 条件]; 178 179 create table customers_1( 180 -> id int, 181 -> name varchar(20), 182 -> age int, 183 -> address char(25), 184 -> salary decimal(18,2) 185 -> ); 186 187 insert into customers_1 select * from customers where id in (select c_id from orde where amount>8000); 188 insert into customers_1 select * from customers where id[customers的客户id号] in (select c_id from orde where amount>8000); 189 190 update[更改]语句的嵌套查询 191 192 update 表名 set 列名=新的值 where 列名 操作符(select 列名 from 表名 [where 条件]); 193 示例: 194 update customers set salary =salary*1.5 where age in (select age from customers_1 where age>=20); 195 196 练习: 197 1.把customers表中工资小于所有顾客的平均消费的人的工资提高一倍 198 select * from customers where id in( select c_id from orde where amount= (select avg(amount) from orde) <= customers.salary); 199 先找出数据然后在如下进行修改 200 update customers set salary =salary*1.5 where id in( select c_id from orde where amount= (select avg(amount) from orde) <= customers.salary); 201 update customers set salary =salary*1.5 where salary>=(select avg(amount) from orde); 202 2.把customers表中的新数据,按照工资由大到小排序[不用where,where是加条件用的] 203 select * from customers order by salary desc; 204 205 3.求出customers表中各个城市的人的平均工资 206 select address,avg(salary) from customers group by address; 207 208 4.求出customers表中消费额度大于全体顾客的平均工资的顾客的全部信息 209 select * from customers where salary in (salary=select avg(salary) from customers) <(select amount from orde); 210 select * from customers where salary =(select avg(salary) from customers) <orde.amount; 211 212 select * from customers where customers.id in (select c_id from orde where amount<(select avg(salary) from orde)); 213 5.列出工资高于平均消费额的客户的总个数 214 select count(*) from customers where salary>(select avg(amount) from orde);