一、内容简介
情景:
创建学生表(Students)、课程表(Courses)、选课表(Electives),用来保存学生信息、课程信息、学生选课信息以其课程成绩。
学生表中包含:学生编号ID、学号Num、学生姓名Name、学生性别Sex、学生年龄Age,把学生的编号ID做为学生表的主键。
课程表中包含:课程ID、课程编号Num、课程名字Name,把课程的编号ID做为课程表的主键。
选课表中包含:学生编号SID、课程编号CID、课程分数,选课表中的主键为学生编号SID和课程编号CID的联合主键。其中选课表中学生编号SID为学生表中的学生编号ID的外键,选课表中课程编号SID为课程表中的课程编号ID的外键。(课程分数在课程开始之前设置为NULL,在课程结束之后可以自行填写)。
解决:
(1)、创建学生表
(2)、创建课程表
(3)、创建选课表
(4)、学生表课程表录入学生信息和课程信息的数据(注册10名同学,开设3门课程)
(5)、选课表中录入学生选课数据(注册的10名学生分别都选择开设的课程)
(6)、课程结束之后录入学生课程成绩
(7)、循环插入数据(理解循环的概念)
补充知识:
(8)、数据库基本编程-1:查询数据:简单查询、模糊查询
二、详细信息
(1)、创建学生表
use myData;--新建查询之前一定要注意当前数据库是否为所需查询的数据库 create table Students ( ID int identity(0,1) not null --为什么不用学号作为主键,而声明了一个没有业务意义整数作为主键呢? ,Num varchar(16) not null --把学号设置成为字符串,因为有的学校学号编码中含有英文字母 ,Name nvarchar(24) not null --nvarchar()表示的数据类型为汉字,存储占用两个字节。varchar()中存储全为英文,存储中用一个字节。 ,Sex bit null --bit型只存储一位数据取值为0和1 ,Age tinyint null --tinyint型存储0到255的整数数据,存储大小为1字节 constraint PK_Students primary key clustered(ID) );1、主键一般设置为 int类型、自增长、不允许为空值。
添加sql server中数据类型:varchar nvarchar
2、一张表中一个主键可以直接在列的后面定义(不推荐),如上表达式在所有数据类型定义之后进行定义(标准的格式)。
联合主键作为表的主键:
constraint PK_students primary key clustered(ID,Num)3、答第一行ID定义的问题: 用整数作为主键,因为整数比较大小速度快,可以提高检索数据的性能,并且不会降低写数据的性能。而字符串比较大小速度慢,性能消耗不确定,与两个因素有关:一、两个字符串中最短的字符串,二、字符串中的内容。
4、E-R图:实体关系图 实体 属性(补充具体知识)
(2)、创建课程表:
create table Courses ( ID int identity(0,1) not null ,Num varchar(24) not null ,Name nvarchar(32) not null constraint PK_Courses primary key clustered(ID) );
(3)、创建选课表:
create table Electives ( [SID] int not null ,CID int not null ,Scoring decimal(5,2) null --总共存储5位数字,2位存储小数 ,constraint PK_Electives primary key([SID],CID) --联合主键 ,constraint FK_Electives_Students foreign key([SID]) references Students(ID)--外键 ,constraint FK_Electives_Courses foreign key([CID]) references Courses(ID)--外键 );1、微软SQL server中转义系统关键字利用符号"["、"]"
2、主外键关系:参照完整性约束,外键表中的外键值必须在对应的主键表中存在。
主表 从表(明细表) 主从关系
3、Pk、fk等所有的意义
4、关系模型
(4)、学生表课程表录入学生信息和课程信息的数据(注册10名同学,开设3门课程):
学生信息单个插入:
insert into Students(Num,Name,Sex,Age) values('001','张三01',0,21); insert into Students(Num,Name,Sex,Age) values('002','张三02',0,21);
1、CRUD:creat read update delete 增删改查
学生信息批量插入:
insert into Students(Num,Name,Sex,Age) select '003' as Num,'张三03' Name,0 Sex,20 Age union all --求同构集合的并集 select '003' Num,'张三04' Name,0 Sex,20 Age union all --其中as可以省略 select '003' Num,'张三05' Name,0 Sex,20 Age union all select '003' Num,'张三06' Name,0 Sex,20 Age union all select '003' Num,'张三07' Name,0 Sex,20 Age union all select '003' Num,'张三08' Name,0 Sex,20 Age union all select '003' Num,'张三09' Name,0 Sex,20 Age union all select '003' Num,'张三10' Name,0 Sex,20 Age2、求同构集合并集:union或union all
union all 求并但不去重行,性能较高
union 求并去除重复的行,消耗性能
3、逐个插入当本次插入出错是上一个操作是成功的。
批量插入只有两个结果要么成功要么失败
课程信息插入:
insert into Courses(Num,Name) select '001' as Num,'javaSE' union all select '001' as Num,'javaME' union all select '001' as Num,'javaEE'
(5)、选课表中录入学生选课数据(注册的10名学生分别都选择开设的课程):
insert into Electives([SID],CID) select a.ID as SID,b.ID CID from Students as a,Courses b --注意这句话Students as a,Courses b; order by a.ID,b.ID desc; --sql server中默认的排序为asc
1、笛卡尔积:
2、批量插入:一个执行语句插入多条数据
(6)、课程结束之后录入学生课程成绩:批量评分
update Electives set Scoring=cast(rand()*100 as decimal(5,2)); --插了30次只是每次的种子是一样的,只算一次操作
1、cast()类型转换
2、convert(decimal(5,2),rand()*100)
3、微软数据库中生成不同的随机数(每次提供不同的种子):rand(check(newid()))
(7)、循环插入数据(理解循环的概念)
方法一:
declare @count int; --声明变量以@开始,数据类型为int declare @t table(Ordinal int identity(0,1),[SID] int,CID int); --声明数据类型为table的变量(表变量) --这里的Ordinal相当于学生表中的ID(不是学号Num) insert into @t (SID,CID) select [SID],CID from dbo.Electives; --向我们创建表变量中插入数据 set @count=@@ROWCOUNT;--set赋值操作,@@为全局变量且@@ROWCOUNT是上一条语句的执行次数 declare @i int; --声明循环变量 set @i=0; --初始循环变量 while @i<@count begin --可以在begin和end中写入多条语句,若只有一条则不需要 declare @sid int,@cid int; select @sid=SID,@cid=CID from @t --使用变量要带上@符号? where Ordinal=@i; update Electives set Scoring=CAST(RAND(CHECKSUM(NEWID()))*100 as decimal(5,2)) where SID=@sid and CID=@cid; set @i=@i+1; end
方法二:
declare @count int; declare @t table(Ordinal int,[SID] int,CID int); --改变了自增长 insert into @t (Ordinal,SID,CID) select ROW_NUMBER() over (order by SID,CID)-1,SID,CID from Electives;--改变了这一句 set @count=@@ROWCOUNT;--set赋值操作,@@为全局变量且@@ROWCOUNT是上一条语句的执行次数 declare @i int; --声明循环变量 set @i=0; --初始循环变量 while @i<@count begin --可以在begin和end中写入多条语句,若只有一条则不需要 declare @sid int,@cid int; select @sid=SID,@cid=CID from @t --使用变量要带上@符号? where Ordinal=@i; update Electives set Scoring=CAST(RAND(CHECKSUM(NEWID()))*100 as decimal(5,2)) where SID=@sid and CID=@cid; set @i=@i+1; --步长计算是循环终止 end
1、@:一个@符号为自己定义的局部变量
@@:两个@@为全局变量
2、@@ROWCOUNT的值表示的是离该语句最近的上一条语句的执行次数。
3、declare声明变量可以一次声明多个以逗号隔开,但是声明表变量的时候有且只能声明一个。
4、能辨别临时表与表变量的区别?
(8)、数据库基本编程:查询数据:简单查询、模糊查询
简单查询:
select ID,Num,Name,Sex,Age from Students where Name='张三0';
推荐select语句即使是选择所有的列都应该写出所有的列名,因为*符号在数据库中转为所有列名也是需要时间的。
模糊查询:
declare @a int,@b int; set @a=7; set @b=1; select @a/@b,@a*1.0/@b,@a%@b; -- + - * SQRT(@a) 都可以运算 select '123'+'abc',UNICODE('中国'),UPPER('abc'),RIGHT('abcd',2) ,RTRIM(LTRIM(' 123 ')),LEN('abcd'),REVERSE('abcd'); declare @s nvarchar(24) set @s='{0}喜欢{1}'; select REPLACE(REPLACE(@s,'{0}','小张'),'{1}','睡觉'); select Charindex('爱','爱我中华',-1),SUBSTRING('abcdef',103,2),DATALENGTH('张abc三');
2、数据库中的判等与赋值符号是一致的。
3、@a/@b为整除运算。(像哪边取整?)
left(),right()从左边或者右边选取数据
trim(),rtrim(),ltirm 去除空格(左右边)
len()求字符串的长度
reverse()字符串反转
charindex()检查字符串中特定字符的个数
substring() 选取子串
datalength()求字符或者字符串长度的函数
4、能够使用集合批量运算操作的,不使用循环
能够使用循环的不使用游标
三、今日总结
1、b+数b-数可以理解数据裤优化,理解b+,b-树
2、对数据库的操作尽量用代码来进行操作,这样一来可以增加代码量,还有可以增加自己的逻辑性。(各种创建的东西需要考虑)
3、嘴中说出的话要经过大脑思考,这样才具有逻辑性。