1.实体与数据库

  1.1实体对象:客观存在的事物都是实体

  1.2实体数据的存储要求:必须按照一定的分类和存储规律

  1.3数据库:专门用于存储实体信息的数据集合

2.实体存储基本单元

  2.1数据表(实体集合):实体信息存储的基本单元,同类实体存放在同一个表中

  2.2   行(一条记录):实体

          列(标题,字段):属性

3.不同实体(学员表、班级表、成绩表)的存储

  数据库包括数据表、存储过程、视图、函数等这些操作对象

  表是不同类型的实体集合

  存储方法:不同实体存放在不同的数据表中

  数据库:由大量数据、表间关系、以及各种数据操作对象组合成的一个数据集合

  数据库不是一个简单的数据组合场所

4.数据库管理系统

  DBMS(DataBase Management System):说白了就是诸如SQLServer2008软件本身

  DBMS是一个由用户使用的数据库管理软件,让用户完成对数据库数据的处理。

  DBMS功能:创建数据库和操作数据库

5.应用程序

  应用程序是根据用户需求开发的具有业务逻辑的管理软件:说白了就是C#写的可以增查删改的软件

  应用程序发送操作命令给数据库服务器;数据库服务器响应并提供查询结果给应用程序客户端。

  应用程序作用:向数据库发送请求、并显示响应结果

  应用程序要求:美观、操作简单方便、能够按照业务需求完成数据处理

6.如何学习数据库

  6.1学习标准的SQL语言

    SQL(Structed Query Language:结构化查询语言)

    使用SQL语言可以完成所有数据库的操作

    应用程序通过SQL语言和数据库交互

  6.2针对特定的DBMS(例如SQLServer)学习管理数据库

    数据导入、导出

    数据备份、还原

    数据库性能改进

  6.3将DML嵌入高级开发语言编写应用程序

    基于客户端/服务器端(C/S)的桌面应用

    基于浏览器/服务器(B/S)的web应用

7.SQL与T-SQL

  7.1 T-SQL概念

    T-SQL=Transact-SQL

    T-SQL是SQL的加强版

    对功能进行了扩充:如变量说明、流程控制、功能函数

  7.2 T-SQL的组成

    7.2.1DDL:数据定义语言

      ——用来建立数据库、数据库对象和定义列

      ——Create Table、Drop Table...

    7.2.2DML:数据库操作语言

      ——查询、插入、删除和修改数据库中的数据

      ——Select、Insert、Update、Delete...

    7.2.3DCL:数据控制语言

      ——用来控制存取许可、存取权限等

         ——Grant、Revoke...

    7.2.4变量说明、流程控制、功能函数

      ——定义变量、判断、分支、循环结构等

      ——日期函数、数学函数、字符函数、系统函数等

8.数据库服务

  8.1SQL Server(MSSQLServer)

    运行在服务器端的应用程序,提供数据的存储、处理和事务等

    在使用DBMS客户端之前必须首先打开该服务

  8.2打开与关闭

    电脑应用——服务(可以用右键“我的电脑”、管理、服务和应用程序、服务、找到SQL Server——MSSQKLSERVER)启停

  8.3日志文件太如何清除

    8.3.1数据库右键属性——>>选项——>>恢复模式——>>由完整切换为简单

 

     8.3.2数据库右键任务——>>收缩——>>文件——>>文件类型选择日志——>>收缩类型选择第二个——>>将MB数更改2MB——>>确定

  9.客户端连接到服务器

  9.1关于客户端、服务器的说明

    客户端:数据库管理系统(DBMS)或C#写的应用程序

    服务器端:安装的数据库服务(数据库管理的核心程序)

    两者关系:客户端和服务器端可以安装的时候完全分离开,一个服务器端可以被多个客户端连接,并为其提供服务。

  9.2使用windows登陆方式

    Windows登陆方式只能登陆本地

    只要能登陆windows操作系统就可以登陆数据库服务器

    9.2.1服务器名称:根据需求可以是服务器IP地址或服务器名称

    9.2.2服务器名称:格式是服务器名称\数据库实例名称,例如192.168.1.102\MES

    9.2.3身份验证:选择windows身份验证

10.数据库登陆常见错误

  10.1本地连接解决办法步骤:检查数据库服务是否启动

               检查数据库服务器名称或IP地址是否正确(注意命名示例和默认实例,应该是安装时候选项,有的时候“.”不一定能连得上)

  10.2局域网或外网连接步骤:服务器是否允许远程控制

               服务是否启动、IP地址和端口号是否正确

               是否有防火墙拦截

               能否ping通

               数据库本身问题检查

  10.3如果使用IP地址和端口号连接(服务器名称:127.0.0.1,1433)

    IP地址为本地地址,端口号默认1433

    可以打开Sql Server Configuration Manager,SQL Server网络配置,MSSQLSERVER的协议,TCP/IP属性查找,TCP/IP必须已启用,修改端口号之后要对MSSQLSERVER服务重新启用

11.安装数据库的实例配置

  实例就是数据库的名称

  SQL2000时一台服务器默认情况下最多有16个实例

  选择“默认实例”:就是计算机寄存器的名称

  如果装了SQL Server2008,当时用的默认实例,想再装2012,就不能再使用默认实例了。

12.企业管理器与查询分析器

  查询分析器里面有SQL语句,是学习的重点。

13.SQL Server验证登陆

  13.1修改服务器身份验证方式:服务器右键选择属性——安全性——修改为混合验证方式

  13.2修改sa(数据库超级管理员)登录密码:安全性——登录名——sa——右键属性——选择“常规”,然后修改密码;

  13.3开启sa账户:安全性——sa——右键属性——常规最下方状态——选择“授予”和“启用”

  13.4重新启动数据库服务:右键选择服务器——重新启动

14.数据库分类

  14.1系统数据库

    14.1.1master:保存所有数据库的信息(系统登录、配置设置、已连接的Server等),不要随意更改,它是数据库的数据库,类似于银行系统中的中国人民银行

    14.1.2model:创建新用户数据库的模板数据库

    14.1.3msdb:用来保存数据库备份、SQL Agent信息、DTS程序包、SQLServer任务等信息

    14.1.4tempdb:存有临时对象,例如临时表格和存储过程

  14.用户数据库:一般就是自己或者用户创建的数据库

15.用户数据库文件组成=数据库文件+日志文件

  15.1数据文件:.mdf(主数据文件)或.ndf(次要数据文件)

  15.2日志文件:  .ldf

  一个数据库必须、且只能包含一个mdf,但可以有多个ndf和ldf(至少有一个)

16.创建数据库 

use master
go
--创建数据库
create database StudentManageDB
on primary
(
    name='StudentManageDB_data',--数据库文件的逻辑文件名
    filename='D:\DB\StudentManageDB_data.mdf',--数据库物理文件名(绝对路径)
    size=10MB,--数据库文件初始大小
    filegrowth=5MB--数据文件增长量
)
log on
(
    name='StudentManageDB_log',
    filename='D:\DB\StudentManageDB_log.ldf',--通常是逻辑名后加扩展名
    size=5MB,
    filegrowth=2MB
)
go
--go...go之间是一个执行整体,create必须是一个执行块的第一句
--所以create前面有个go,到哪里结束,在其后面再来个go
SQL语句创建数据库
use master
go
--创建数据库
create database StudentManageDB
on primary
(
    name='StudentManageDB_data',--数据库文件的逻辑文件名
    filename='D:\DB\StudentManageDB_data.mdf',--数据库物理文件名(绝对路径)
    size=10MB,--数据库文件初始大小
    filegrowth=5MB--数据文件增长量
)
,
(
    name='StudentManageDB_data1',
    filename='D:\DB\StudentManageDB_data1.ndf',--创建次要数据文件
    size=2MB,
    filegrowth=1MB
)
log on
(
    name='StudentManageDB_log',
    filename='D:\DB\StudentManageDB_log.ldf',--通常是逻辑名后加扩展名
    size=5MB,
    filegrowth=2MB
)
,
(
    name='StudentManageDB_log1',
    filename='D:\DB\StudentManageDB_log1.ldf',
    size=5MB,
    filegrowth=2MB
)
go
--go...go之间是一个执行整体,create必须是一个执行块的第一句
--所以create前面有个go,到哪里结束,在其后面再来个go
SQL语句创建多个数据库
use master
go
--exists()语句:检测是否存在StudentManageDB数据库,如果存在,则删除
if exists(select * from sysdatabases where name='StudentManageDB')
drop database StudentManageDB   
--drop:删除数据库,drop删除后数据库将不可恢复!使用需谨慎
go
--创建数据库
create database StudentManageDB
on primary
(
    name='StudentManageDB_data',--数据库文件的逻辑文件名
    filename='D:\DB\StudentManageDB_data.mdf',--数据库物理文件名(绝对路径)
    size=10MB,--数据库文件初始大小
    filegrowth=5MB--数据文件增长量
)
,
(
    name='StudentManageDB_data1',
    filename='D:\DB\StudentManageDB_data1.ndf',--创建次要数据文件
    size=2MB,
    filegrowth=1MB
)
log on
(
    name='StudentManageDB_log',
    filename='D:\DB\StudentManageDB_log.ldf',--通常是逻辑名后加扩展名
    size=5MB,
    filegrowth=2MB
)
,
(
    name='StudentManageDB_log1',
    filename='D:\DB\StudentManageDB_log1.ldf',
    size=5MB,
    filegrowth=2MB
)
go
--go...go之间是一个执行整体,create必须是一个执行块的第一句
--所以create前面有个go,到哪里结束,在其后面再来个go
SQL语句创建多个数据库,创建前判断是否存在,如果存在则先删除后新建
select FileName from master..sysdatabases where name = 'student_database'
查看数据库保存路径

17.手动复制数据库文件(.mdf  .ndf  .ldf)

  17.1【第一步】在计算机服务中先停止SQL Sever(MSSQLSERVER)服务

  17.2【第二步】以管理员身份复制粘贴文件

18.分离与附加数据库

  18.1分离数据库

    可以右键要分离的数据库——>>>任务——>>>分离——>>>打勾删除连接——>>>确定

    当数据库服务运行时,SQL2003及以下无法直接移动和复制数据库文件

    所谓分离数据库就是将正在使用的数据库文件解除服务的限制

    exec  sp_detach_db @dbname=数据库名称

  18.2附加数据库

    可以右键”数据库“——>>>附加——>>>选择好路径,选择要附加的mdf文件——>>>确定

    附加数据库就是将指定位置的数据库文件加入到数据库服务中运行

    数据库只有附加后,用户才能通过DBMS操作数据

    exec  sp_attach_db @dbname=数据库名称,

    @filename1=数据库主文件物理文件路径,

    @filename2=数据库日志文件物理文件文件路径

--分离数据库
exec sp_detach_db @dbname=StudentManageDB
--附加数据库方法1
exec sp_attach_db @dbname=StudentManageDB,
@filename1='D:\DB\StudentManageDB_data_mdf',
@filename2='D:\DB\StudentManageDB_log.ldf',
--附加数据库方法2
exec sp_attach_db StudentManageDB,
'D:\DB\StudentManageDB_data.mdf',
'D:\DB\StudentManageDB_log.ldf'
分离与附加数据库

19.SQL Server数据类型

  19.1文本类型:字符数据包含任意字母、符号或数字字符的组合

    char:固定长度的非Unicode字符数据,最大长度为8000个字符

    varchar:可变长度的非Unicode数据,最大长度为8000个字符

    text:存储文本信息,最大长度为2的31次方-1(21亿)个字符

    nchar:固定长度的Unicode数据,最大长度为4000个字符

    nvarchar:可变长度的Unicode数据,最大长度为4000个字符

    ntext:存储可变长度的长文本,2的30次方-1(10亿)个字符

    Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案

    注意:带n的数据类型长度是不带n的两倍。比如nchar(1)和char(2)长度相同

   19.2整数类型

    bigint占:用8个字节,可表示范围:-263~263-1之间的整数

    int:占用4个字节,可表示范围:-231~231之间的整数

    smallint:占用2个字节,可表示范围:-215~215之间的整数

    tinyint占用1个字节,可表示范围:0~255之间的整数

  19.3精确数字类型

    decimal:-1038~1038-1之间的固定精度和小数位的数字

    numeric:功能等同于decimal

    写法decimal(整数,小数)和numeric(整数,小数)

    默认:如果不指定位数,默认18位整数,0位小数

  19.4近似数字(浮点)类型

    float[(n)]表示范围:-1.79E+308~1.79E+308(1.79*10308)

    n表示精度,在1-53之间取值,当n在1-24之间时,精度为7位有效数字,占用4个字节;当n在25-53之间时,精度为15位有效数字,占用8个字节

    real表示范围:-3.4E+38~3.4+38占用4个字节存储空间,相当于float(24)

  19.5日期类型

    datetime:允许的范围1753-1-1至9999-1-1

    smalldatetime:允许的范围1900-1-1至2079-6-6

    时间精度不同:datetime精确到0.03秒,smalldatetime精确到1分钟

    格式说明:分隔符数字方式2013-08-20或08/20/2013

           纯数字方式:08201013

         英文数字方式:Aug 20,2013

    注意问题:日期在使用的使用需要使用单引号(‘   ’)括起来

  19.6货币类型

    money:货币数值介于-263与263-1之间,精确到货币单位的千分之一

    smallmoney:货币数据介于-214748.3648与214748.3648之间,精确到货币单位的千分之十

  19.7位单位

    bit:表示“是/否”类型的数据(0,1/true、false)

  19.8二进制类型

    binary:固定长度的二进制数据,最大长度为8000个字节

    vbinary:可变长度的二进制数据,其最大长度为8000个字节

    image:可变长度的二进制数据,其最大长度为231个字节

    应用场合:可存储图片

20.创建数据表

  20.1建表的语法  

create table 表名
(
  字段1  数据类型  列的特征,
  字段2  数据类型  列的特征,
  ......
  字段n  数据类型  列的特征
)
go
建表的语法

  20.2列的特征

    20.2.1是否为空(null)

    在输入数据时,数据库的列允许为空可不输入数据,否则必须输入。列是否为空要紧跟数据库设计的具体要求决定,对于关键列必须禁止为空

    20.2.2是否是标识列(自动编号)

    20.2.3是否有默认值

    如果数据表的某列在用户不输入数据的时候,希望提供一个默认的内容,比如用户不输入地址时,则默认“地址不详”

    20.2.4是否为主键

    主键是实体的唯一标识,保证实体不被重复。一个数据表必须有主键才有意义,否则刷新和删除实体都可能会出现异常

21.标识列的特殊说明

  21.1标识列使用的意义

  有时一个数据表存储的实体很难找到不重复的列作为主键列,比如学员成绩表中存储着学生的成绩,则学号也很容易重复,其他列更无法做到不重复

  SQLServer提供了一个“标识列”,也叫“自动增长列”或“自动编号”,它本身没有任何具体意义,但我们也可以让它表示特定意义,比如学生成绩表中自动标识Id,不表示实体属性,但学生信息表中的StudentId也是标识列,但它表示学生实体属性(学号)

  21.2标识列的使用方法

    该列比必须是整数类型(int)

    标识种子:标识列的起始大小

    标识增量:标识列每次递增的(自动增加)值

  21.3注意问题

    有标识列的数据表被删除某一行时,数据库会将该行空缺,标识列不会自动填补

    标识列由系统自动维护,用户既不能自己输入数据,也不能修改数值

    标识列可以同时定义为主键,也可以不定义为主键,根据需求决定

22.批处理语句go...go

  go是批处理的标志,表示SQL Server将这些SQL语句编译为一个执行单元,提高执行效率。一般是将一些逻辑相关的业务操作语句放在同一个批中,这完全由业务需求和代码编写者决定

  go是SQL Server的批处理命名,只有代码编译器才能识别并处理,编辑其他应用程序就不能使用该命令。由于每个批处理之间是独立的,因此在一个批处理出现错误时,并不会影响其他批处理SQL代码的运行

  必须加go的几个地方:使用use后必须加go、判断语句必须加go、创建数据库(表)必须加go 

--【1】首先指定在哪一个数据库中创建数据表
use StudentManageDB
go
--新建表之前先判断表是否存在,如果存在则先删除
--【2】从系统表中判断数据表是否存在
if exists(select * from sysobjects where name='Students')
drop table Students
go
--创建学生信息表
create table Students
(
    --【3】定义数据表的特征
    StudentId int identity(10000,1),--学号 indentity表示标识列  10000起始值、1为自增量
    StudentName varchar(20) not null,--姓名
    Gender char(2) not null,--性别
    Birthday datetime not null,--出生日期
    StudentIdNo numeric(18,0)not null,--身份证号
    Age int not null,--年龄
    PhoneNumber varchar(50),--电话,允许为空
    StudentAddress varchar(500),--地址,允许为空
    ClassId int not null--班级外键
)
go
--【4】go表示创建结束
--创建班级表
if exists (select * from sysobjects where name='StudentClass')
drop table StudentClass
go
create table StudentClass
(
    ClassId int primary key,--班级编号
    ClassName varchar(20) not null--班级名称
)
go
--创建成绩表
if exists(select *from sysobjects where name='ScoreList')
drop table ScoreList
go
create table ScoreList
(
    Id int identity(1,1) primary key,--Id 标识列又是主键
    StudentId int not null,--学号外键
    CSharp int null,--C#成绩
    SQLServer int null,--SQL成绩
    UpdateTime datetime not null--更新时间
)
go
--创建管理员表
if exists(select * from sysobjects where name='Admins')
drop table Admins
go
create table Admins
(
    LoginId int identity(1000,1) primary key,--管理员ID 标识列 主键
    LoginPwd varchar(20) not null,--登录密码
    AdminName varchar(20) not null--登录姓名
)
go
创建数据表

23.插入实体(

  23.1插入实行(数据行)语法

    insert [into] <表名> [列名] values <值列表>

    []内容可写可不写但建议必写;<>内容必写

   23.2注意事项

    列名个数=对应值的个数

    非值类型的数据,必须放在单引号内

    数据值的类型必须与定义的字段类型一致

24.查询实体(

  查询语法

  select <列名> from <源表名> [where<查询条件>]

  *表示查询所有字段

25.T-SQL中的运算符

运算符 含义
= 等于
> 大于
< 小于
>= 大于或等于
<= 小于或等于
<> 不等于
!

  eg.   select Student,StudentName from Studens where Age>=22

26.更新实体(

  语法:  Update <表名> set <列名=更新值> [where <更新条件>]

  update Students set StudentAddress='南京路99号',PhoneNumber=‘123456’ where StudentId=10001

  使用update语句时,一定要注意where条件的配合使用

27.删除实体(

  delete from <表名> [where <删除条件>]

  truncate table <表名>  --清空数据表

  使用删除语句时,一定要注意where条件的配合使用

  delete删除数据时,要求该记录不能被外键引用,删除后标识列继续增长

  truncate删除数据时,要求删除的表不能有外键约束,删除后重新条件数据,删除后标识列重新编排

  truncate比delete执行速度快,而且使用的系统资源和事务日志资源更少

use StudentManageDB
go
--
insert into Students(StudentName,Gender,Birthday,Age,StudentIdNo,
PhoneNumber,StudentAddress,ClassId)
values ('杨三少','','1992-08-17',21,1234567890,'098-6767656','河南路988号',4)
go
--
select * from Students
select StudentId,StudentName from Students
go
--
update Students set StudentAddress='南京路1号',PhoneNumber='123456'where StudentId=10000
go
--
delete from Students where StudentId=10004--可删除指定一条记录
truncate table Students--清空整个数据表,之后标识列重新计数
go
增删改查

28.数据完整性

  能确保存储在数据库中数据的准确性和一致性

  28.1实体完整性(行)

    例如一个数据表中必须有一列属于主键(例如学生序号,查询时也主要是根据学号查询),学生的身份证号也是唯一的,要设置唯一约束

    方法:主键约束、标识列、唯一约束

    28.1.1主键约束与唯一约束

      添加约束的基本语法

      alter table 表名 add constraint 约束名 约束类型 (选择添加约束的列名)

      alter:部分修改

    28.1.2约束名的取名规则推荐采用:约束类型_约束字段

      主键(Primary Key)约束:如  pk_StudentId

      唯一(Unique Key)约束:如  uq_StudentIdNo

use StudentManageDB
go
--创建“主键”约束 primary key
if exists(select * from sysobjects where name='pk_StudentId')
alter table Students drop constraint pk_StudentId
alter table Students add constraint pk_StudentId primary key(StudentId)
go
--创建唯一约束 unique key
if exists(select * from sysobjects where name='uq_StudentIdNo')
alter table Students drop constraint uq_StudentIdNo
alter table Students add constraint uq_StudentIdNo unique(StudentIdNo)
go
主键约束与唯一约束

  28.2域完整性(列)

    保证实体属性值符合规范要求

    方法:检查约束(例如年龄必须在20~40年龄范围内)、限制数据类型、默认值、非空约束

    约束名的取名规则

    检查(Check Key)约束:如ck_Age,检查可以限制某一属性值,例如年龄必须在18至25范围内、输入密码长度必须大于6等

    默认(Default Key)约束:如df_StudentAddress,例如当不输入具体的地址时,默认“地址不详”

use StudentManageDB
go
--创建检查约束(年龄必须在18到25中间)
if exists(select * from sysobjects where name='ck_Age')
alter table Students drop constraint ck_Age
alter table Students add constraint ck_Age check(Age between 18 and 25)
go
truncate table Students
go
--创建检查约束(手机号必须是11位)
if exists(select * from sysobjects where name='ck_PhoneNumber')
alter table Students drop constraint ck_PhoneNumber
alter table Students add constraint ck_PhoneNumber check(len(PhoneNumber)=11)
go
--创建默认约束
if exists(select * from sysobjects where name='df_StudentAddress')
alter table Students drop constraint df_StudentAddress
alter table Students add constraint df_StudentAddress default('地址不详') for StudentAddress
go
--使用默认约束插入数据1
insert into Students(StudentName,Gender,Birthday,Age,StudentIdNo,PhoneNumber,StudentAddress,ClassId)
values('刘三','','1989-12-30',22,2983765091827,'13838456789',default,3)
go
--使用默认约束插入数据2
insert into Students(StudentName,Gender,Birthday,Age,StudentIdNo,PhoneNumber,ClassId)
values('杨一','','1991-8-5',21,11928373464527,'12345678654',2)
go
select * from Students
go
检查约束与默认约束

  28.3引用完整性

    保证两表中相同属性值的一致性。例如学生表中的学生的班级编号必须是班级表中的值

    约束方法:外键约束

    外键约束的取名规则:  外键(Foreign Key)约束:如 FK_ClassId

    如果实现已存在数据要添加外键,必须保证学生信息表中所有学生的班级已存在于班级表中的班级ID中,才可以添加外键成功

use StudentManageDB
go
--创建外键约束
if exists(select * from sysobjects where name='fk_classId')
alter table Students drop constraint fk_classId
alter table Students add constraint fk_classId foreign key(ClassId)references StudentClass(ClassId)
go
select * from Students
go 
insert into StudentClass(ClassId,ClassName)values (3,'C#2班')
insert into StudentClass(ClassId,ClassName)values(2,'SQL1班')
select * from StudentClass
go
外键约束

29.数据完整性总结

  29.1实体完整性(右键“索引/键”)

    能够唯一标识表中的每一条记录

    实现方式:主键(primary key),唯一键(unique key),标识列(identity)

  29.2域完整性(右键“CHECK约束”)

    表中特定列数据的有效性,确保不会输入无效的值

    实现方式:数据类型限制,缺省值(default),非空值(not null)

  29.3引用完整性(右键“关系”)

    维护表间数据的有效性、完整性

    实现方式:建立外键,关联另一表的主键(foreign key)

30.数据表的使用总结

  30.1主键的使用

    最少性原则:尽量选择单个键作为主键

    稳定性原则:尽量选择数值更新少的列作为主键

  30.2外键使用

    要求数据类型、数据长度必须于对应的主键表字段完全一致

    添加数据时,要首先添加主键表,再添加外键表

    删除数据时,要首先删除外键表数据(Students),再删除主键表数据(SyudentClass)

  30.3完整性数据库创建步骤

    建数据库——>>>建数据表——>>>主键约束——>>>域完整性约束——>>>外键约束

  30.4插入数据的过程

    验证主键、主外键关系、检查约束......——>>>插入数据成功 

--指向当前要使用的数据库
use master
go
--判断当前数据库是否存在
if exists (select * from sysdatabases where name='SMDB')
drop database SMDB --删除数据库
go
--创建数据库
create database SMDB
on primary
(
    --数据库文件的逻辑名
    name='SMDB_data',
    --数据库物理文件名(绝对路径)
    filename='F:\DB\SMDB_data.mdf',
    --数据库文件初始大小
    size=10MB,
    --数据文件增长量
    filegrowth=1MB
)
--创建日志文件
log on
(
    name='SMDB_log',
    filename='F:\DB\SMDB_log.ldf',
    size=2MB,
    filegrowth=1MB
)
go
--创建学员信息数据表
use SMDB
go
if exists (select * from sysobjects where name='Students')
drop table Students
go
create table Students
(
    StudentId int identity(100000,1) ,
    StudentName varchar(20) not null,
    Gender char(2)  not null,
    Birthday smalldatetime  not null,
    StudentIdNo numeric(18,0) not null,--身份证号
    CardNo  varchar(20) not null,--考勤卡号
    StuImage text null,--学员照片
    Age int not null,
    PhoneNumber varchar(50),
    StudentAddress varchar(500),
    ClassId int not null  --班级外键
)
go
--创建班级表
if exists(select * from sysobjects where name='StudentClass')
drop table StudentClass
go
create table StudentClass
(
    ClassId int primary key,
    ClassName varchar(20) not null
)
go
--创建成绩表
if exists(select * from sysobjects where name='ScoreList')
drop table ScoreList
go
create table ScoreList
(
    Id int identity(1,1) primary key,
    StudentId int not null,
    CSharp int null,
    SQLServerDB int null,
    UpdateTime smalldatetime not null
)
go
--创建考勤表
if exists(select * from sysobjects where name='Attendance')
drop table Attendance
create table Attendance
(
    Id int identity(100000,1) primary key,--标识列
    CardNo varchar(20) not null,--学员卡号
    DTime smalldatetime not null --打卡时间
)
go
--创建管理员用户表
if exists(select * from sysobjects where name='Admins')
drop table Admins
create table Admins
(
    LoginId int identity(1000,1) primary key,
    LoginPwd varchar(20) not null,
    AdminName varchar(20) not null
)
go

--创建数据表的各种约束
use SMDB
go
--创建“主键”约束primary key
if exists(select * from sysobjects where name='pk_StudentId')
alter table Students drop constraint pk_StudentId

alter table Students
add constraint pk_StudentId primary key (StudentId)

--创建检查约束check
if exists(select * from sysobjects where name='ck_Age')
alter table Students drop constraint ck_Age
alter table Students
add constraint ck_Age check (Age between 18 and 35) 

--创建唯一约束unique
if exists(select * from sysobjects where name='uq_StudentIdNo')
alter table Students drop constraint uq_StudentIdNo
alter table Students
add constraint uq_StudentIdNo unique (StudentIdNo)

if exists(select * from sysobjects where name='uq_CardNo')
alter table Students drop constraint uq_CardNo
alter table Students
add constraint uq_CardNo unique (CardNo)

--创建身份证的长度检查约束
if exists(select * from sysobjects where name='ck_StudentIdNo')
alter table Students drop constraint ck_StudentIdNo
alter table Students
add constraint ck_StudentIdNo check (len(StudentIdNo)=18)

--创建默认约束 
if exists(select * from sysobjects where name='df_StudentAddress')
alter table Students drop constraint df_StudentAddress
alter table Students 
add constraint df_StudentAddress default ('地址不详' ) for StudentAddress

if exists(select * from sysobjects where name='df_UpdateTime')
alter table ScoreList drop constraint df_UpdateTime
alter table ScoreList 
add constraint df_UpdateTime default (getdate() ) for UpdateTime

if exists(select * from sysobjects where name='df_DTime')
alter table Attendance drop constraint df_DTime
alter table Attendance 
add constraint df_DTime default (getdate() ) for DTime

--创建外键约束
if exists(select * from sysobjects where name='fk_classId')
alter table Students drop constraint fk_classId
alter table Students
add constraint fk_classId foreign key (ClassId) references StudentClass(ClassId)

if exists(select * from sysobjects where name='fk_StudentId')
alter table ScoreList drop constraint fk_StudentId
alter table ScoreList
add constraint fk_StudentId foreign key(StudentId) references Students(StudentId)

-------------------------------------------插入数据--------------------------------------
use SMDB
go

--插入班级数据
insert into StudentClass(ClassId,ClassName) values(1,'软件1班')
insert into StudentClass(ClassId,ClassName) values(2,'软件2班')
insert into StudentClass(ClassId,ClassName) values(3,'计算机1班')
insert into StudentClass(ClassId,ClassName) values(4,'计算机2班')
insert into StudentClass(ClassId,ClassName) values(5,'网络1班')
insert into StudentClass(ClassId,ClassName) values(6,'网络2班')

--插入学员信息
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('王小虎','','1989-08-07',22,120223198908071111,'0004018766','022-22222222','天津市南开区红磡公寓5-5-102',1)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('贺小张','','1989-05-06',22,120223198905062426,'0006394426','022-33333333','天津市河北区王串场58号',2)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('马小李','','1990-02-07',21,120223199002078915,'0006073516','022-44444444','天津市红桥区丁字沽曙光路79号',4)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('冯小强','','1987-05-12',24,130223198705125167,'0006254540','022-55555555',default,2)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('杜小丽','','1986-05-08',25,130223198605081528,'0006403803','022-66666666','河北衡水路北道69号',1)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('王俊桥','','1987-07-18',24,130223198707182235,'0006404372','022-77777777',default,1)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('张永利','','1988-09-28',24,130223198909282235,'0006092947','022-88888888','河北保定市风华道12号',3)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('李铭','','1987-01-18',24,130223198701182257,'0006294564','022-99999999','河北邢台市幸福路5号',1)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('宁俊燕','','1987-06-15',24,130223198706152211,'0006092450','022-11111111',default,3)
insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('刘玲玲','','1989-08-19',24,130223198908192235,'0006069457','022-11111222',default,4)
         
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('王小军','','1986-05-08',25,130224198605081528,'0006403820','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('刘小丽','','1986-05-08',25,130225198605081528,'0006403821','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('张慧鑫','','1986-05-08',25,130226198605081528,'0006403822','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('李素云','','1986-05-08',25,130227198605081528,'0006403823','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('赵小金','','1986-05-08',25,130228198605081528,'0006403824','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('王浩宇','','1986-05-08',25,130229198605081528,'0006403825','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('崔永鑫','','1986-05-08',25,130222198605081528,'0006403826','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('包丽云','','1986-05-08',25,130220198605081528,'0006403827','022-66666666','河北衡水路北道69号',1)
         
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('孙丽媛','','1986-05-08',25,130228198605081530,'0006403854','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('郝志云','','1986-05-08',25,130229198605081531,'0006403855','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('王保华','','1986-05-08',25,130222198605081532,'0006403856','022-66666666','河北衡水路北道69号',1)
         insert into Students (StudentName,Gender,Birthday,Age,StudentIdNo,CardNo,PhoneNumber,StudentAddress,ClassId)
         values('李丽颖','','1986-05-08',25,130220198605081544,'0006403857','022-66666666','河北衡水路北道69号',1)         
         
--插入成绩信息
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100000,60,78)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100001,55,88)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100002,90,58)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100003,88,75)

insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100004,62,88)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100006,52,80)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100007,91,66)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100009,78,35)

insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100000,60,78)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100001,55,88)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100002,90,58)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100003,88,75)

insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100004,62,88)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100006,52,80)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100007,91,66)
insert into ScoreList (StudentId,CSharp,SQLServerDB)values(100009,78,35)

--插入管理员信息
insert into Admins (LoginPwd,AdminName) values(123456,'王晓军')
insert into Admins (LoginPwd,AdminName) values(123456,'张明丽')

--树形菜单表
if exists(select * from sysobjects where name='MenuList')
drop table MenuList
create table MenuList
(
     MenuId int identity(100,1) primary key,  
     MenuName varchar(50) ,--菜单名称,
     MenuCode varchar(50),--菜单编码
     ParentId int --所属的类别(上一级的菜单编号)
)
go

--创建树形菜单表
if exists(select * from sysobjects where name='Menulist')
drop table MenuList
go
create table MenuList
(
    MenuId int identity(100,1) primary key,--菜单编号
    MenuName varchar(50) ,--菜单名称
    MenuCode varchar(50),--菜单编码(用来保存窗体的name)
    ParentId  int --父类编号(上一级菜单编号,递归必备)
)
go

--插入树形菜单数据

--插入一级菜单
insert into MenuList (MenuName,MenuCode,ParentId) values('系统管理','',0)  --100
insert into MenuList (MenuName,MenuCode,ParentId) values('学员管理','',0)  --101
insert into MenuList (MenuName,MenuCode,ParentId) values('成绩管理','',0)  --102
insert into MenuList (MenuName,MenuCode,ParentId) values('考勤管理','',0)  --103
insert into MenuList (MenuName,MenuCode,ParentId) values('系统帮助','',0)  --104
--插入二级菜单
insert into MenuList (MenuName,MenuCode,ParentId) values('密码修改','ModifyPwd',100)  

insert into MenuList (MenuName,MenuCode,ParentId) values('添加学员','AddStudent',101)  
insert into MenuList (MenuName,MenuCode,ParentId) values('批量导入学员','ImportData',101)  
insert into MenuList (MenuName,MenuCode,ParentId) values('学员信息管理','StudentManage',101) 

insert into MenuList (MenuName,MenuCode,ParentId) values('成绩查询与分析','ScoreManage',102)  
insert into MenuList (MenuName,MenuCode,ParentId) values('成绩快速查询','ScoreQuery',102)  

insert into MenuList (MenuName,MenuCode,ParentId) values('考勤打卡','Attendance',103)  
insert into MenuList (MenuName,MenuCode,ParentId) values('考勤查询','AttendanceQuery',103)  

--删除学员信息
--delete from Students 

--truncate table Students --删除全部数据以后,自动标识列重新编号

--显示学员信息和班级信息
select * from Students
select * from StudentClass
select * from ScoreList
select * from Admins
select * from Attendance
select * from MenuList
SQL语言创建一个完整的数据库

31.查询基本语法构成

  四部分:  查询内容  select StudentId,StudentName,Gender

        查询对象  from Students

        过滤条件  where Gender='男'

        结果排序  order by StudentId DESC

  【查询内容】可用“*”表示所有内容,也可以只查询一列或几列,当查询几列时中间用“,”隔开列名

  【查询对象】就是从哪一张表中查询

  【过滤条件】可有有无  where <条件表达式1 and 条件表达式2>

  【结果排序 】ASC DESC

32.使用as和=修改列名,使用+合并多列

use StudentManageDB
go
--使用as列名称在前修改名在后,使用=修改名在前列名称在后
select StudentName as 姓名,Gender as 性别,出生日期=birthday
from Students where Gender=''
go
使用as或=修改列名称
select 姓名=StudentName,地址和电话=StudentAddress+‘(’+PhoneNumber+')'
from Students where Gender=''
使用+合并多列

  使用+连接的注意事项

    +连接的数据类型必须兼容

    +连接字符串,结果为字符串数据的拼接

    +连接数值型,结果为数值型数据的和

33.检测为空的行

select * from ScoreList where SQLScore is null
检测为空的行

34.常量列

select StudentName,Gender,所在学校=‘北京大学’
from students where Gender='' and Age>=23
常量列

35.限制行数

select top 5 StudentName,Gender,Birthday
from Students
显示固定行数
select top 20 percent StudentName,Gender,Birthday
from Students
返回百分之多少行

36.升序和降序排列

select StudentId,CSharp as C#,DB=SQLServerDB
from ScoreList where Csharp>80
order by CSharp ASC
升序排列ASC
select StudentId,(CSharp+5) as C#,DB=SQLServerDB
from ScoreList where (CSharp+5)>90
order by CSharp DESC
--对C#的成绩统一加上5分
降序DESC和改变输出增加一常量
select StudentId,CSharp as C#,DB=SQLServerDB
from ScoreList
order by SQLServerDB DESC,CShsrp DESC
--先按DB降序排序,如果出现DB成绩一样,再按C#降序排列
多重降序排列

37.模糊查询

  37.1  like

    使用like查询,字段中的内容并不一定要与查询内容为安全一致,只要字段中包含这些内容即可,‘%’表示通配符

select StudentName,StudentAddress from Students
where StudentAddress like '天津%'   --查询出所有学生中天津的,地址是以‘天津’开头

select StudentName,StudentAddress from Students
where StudentName like '%小%'  --查询出所有学生中名字带‘小’字的
like模糊查询

  37.2  between

    把某一字段中的值在特定范围内的记录查询出来,可查询整形等值类型和日期类型

    使用between时包含两个临界点的值,相当于“>=”和“<=”

select * from ScoreList
where CSharp between 80 and 90
    
select StudentName,Birthday from Students
where Birthday between '1997-1-1' and '1999-12-31'
between...and...

  37.3  in

    把某一字段中内容与所列出的查询内容列表匹配的记录查询出来

select StudentName,Birthday,Age from Students
where Age in (21,22,23)

select StudentName,Birthday,Age from Students
where StudentName in ('杨三少','李四宝','王大庆') 
in是否在某一数组中

38.聚合函数

  38.1对某一列求和、对满足条件的记录总数求和

select SUM(SCharp) as C#总成绩 from ScoreList
对一列求和
select 总人数=COUNT(*) from Students
返回满足条件的总数

  38.2求最大值、最小值、平均值

select MAX(CSharp) as C#最高分,MIN(CSharp) as C#最低分,C#平均分=AVG(CSharp)
from ScoreList
最大值、最小值、平均值

 39.多表查询

  39.1内连接查询(inner join ... on ...)

    查询的结果是两个源表中严格满足连接条件的记录连接

    两个表中公有数据的查询

    两个表中具有主外键关系,才可以实现内连接查询

    需要注意的问题:

      需要连接的表(可以是Students,也可以是ScoreList)

      两个表连接的条件(主外键  Students.StudentId=ScoreList.StudentId)

      两个表相同的字段,必须说明来自哪个表

    多表连接查询:只需要使用inner join将多个表按连接条件连接即可

use StudentManageDB
go
--
select Students.StudentId,C#成绩=CSharp,StudentName as 学生姓名,学生班级=ClassName
from Students
inner join ScoreList on Students.StudentId=ScoreList.StudentId
inner join StudentClass on Students.ClassId=StudentClass.ClassId
where CSharp>70
order by CSharp ASC
多表查询内连接
 1 use StudentManageDB
 2 go
 3 --Stu等同于Student Score等同于ScoreList Class等同于StudentClass
 4 select Stu.StudentId,C#成绩=CSharp,StudentName as 学生姓名,学生班级=ClassName
 5 from  Students Stu 
 6 inner join StudentClass Class on Stu.ClassId=Class.ClassId 
 7 inner join ScoreList Score on Stu.StudentId=Score.StudentId
 8 where CSharp>70
 9 order by CSharp ASC
10 --Students学生表  StudentClass班级表   ScoreList成绩表
多表查询内连接-简略表名

  39.2左外连接查询(left outer join...on...)

    查询的结果包括两个表所有满足连接条件的记录,以及左表所有不满足条件的其他记录。这些不满足的左表记录,在结果的右边位置,会全部跳上null值

    换句话说,就是左表中的要统统显示,与左表有连接的右表没有对应实体(字段)的话,该字段为NULL

select Students.StudentId,StudentName as 学生姓名,性别=Gender,C#成绩=CSharp
from Students  --会显示Students表内所有符合条件的记录  Students表为左表  ScoreList表为右表
left outer join ScoreList on ScoreList.StudentId=Students.StudentId
where Gender=''
多表查询左连接

   39.3右外连接查询(right outer join...on...)

select Students.StudentId,StudentName as 学生姓名,Gender as 性别,ClassName as 班级
from Students
right outer join StudentClass on StudentClass.ClassId=Students.ClassId
多表查询右连接

40.group by分组

  搜集数据行到各个组中,统计函数为各个组计算统计值

select 班级=StudentClass.ClassName,人数=COUNT(*),C#平均分=AVG(CSharp),SQL平均分=AVG(SQLServer)
from Students
inner join StudentClass on Students.ClassId=StudentClass.ClassId
inner join ScoreList on Students.StudentId=Scorelist.StudentId
group by ClassName
Group By分组

41.having分组统计筛选

  41.1分组统计筛选

  eg.统计出C#平均分大于70的班级

  使用having而不能使用where

select 班级=StudentClass.ClassName,人数=COUNT(*),C#平均分=AVG(CSharp),SQL平均分=AVG(SQLServer)
from Students
inner join StudentClass on Students.ClassId=StudentClass.ClassId
inner join ScoreList on Students.StudentId=Scorelist.StudentId
group by ClassName
having AVG(CSharp)>70 and AVG(SQLServer)>70
having对分组结果进一步筛选

  41.2在分组结果中,去掉不符合搜索条件的各组数据行

--查询成绩表中重复的学生ID
select StudentId from ScoreList group by StudentId having COUNT(*)>1
--查询成绩表中重复的学生信息
select * from ScoreList
where StudentId in(select StudentId from ScoreList group by StudentId having COUNT(*)>1)
order by StudentId 
having得到重复数据

     where——>>>group by——>>>having

42.数据库的设计

  42.1需求分析

    通过向客户调研,了解客户的实际需求

    总结分析客户所需要的管理系统,究竟要保存、要处理哪些数据

  以学员管理系统开发为背景,分析系统的基本功能:

  1. 学员信息管理模块:数据库中存放着学员的个人信息;需要对学员信息进行管理
  2. 学员成绩管理模块:数据库中保存每次学员的考试成绩;需要对考试成绩进行分析
  3. 学员班级管理模块:数据库中保存着学员的班级信息
  4. 课程管理模块:数据库中存放课程信息

  42.2表示对象(实体)并设计对象的属性

    对象(实体)映射为数据库中的数据表

    对象属性映射为数据表的字段

    对象应该有唯一的标识(ID)

学员信息: 成绩信息: 班级信息: 课程信息:
学号<ID> 学号 班级名称 课程编号<ID>
姓名 课程编号 班级编号<ID> 课程名称
性别 成绩   学分
出生日期 考试日期    
联系电话 <ID>    
家庭住址      
所在班级      

  注意:

  1. 需要设计多少个实体,取决于需求分析结果,以及设计人员的其他考虑
  2. 对于实体的多少,以及实体属性的确定,需要设计人员不断地根据需要修改
  3. 实体必须有唯一地标识,如果当前实体属性没有能够作为标识的,需要添加ID
  4. 实体设计的好坏,关系到后续系统的修改,应当力求做到完善

  42.3确定对象之间的映射关系

    对象之间通过外键映射关系,减少数据冗余

    对象之间的映射关系是通过对象唯一标识建立的

    常见的映射关系有一对一、一对多、多对多

            

43.数据库设计合理性检验

  43.1数据不能冗余

    不能存在同样的数据实体,否则删除、更新时会出现异常

  43.2数据库三范式原则

    范式:是具有最小冗余的表结构

  1. 第一范式:目标是确保每列的原子性(即不可再分的最小数据单元),但地址、姓名有时分开使用。住址=城市+区域,姓名=姓+名
  2. 第二范式:要求每个表只描述一个实体的属性。如果一个关系满足第一范式,并且除了主键以外的其他列,都和主键列相关,则满足第二范式
  3. 第三范式:要求实体各属性之间不能具有直接的依赖关系。如果一个关系满足第二范式,除了主键列外,其他列之间都不具有直接的依赖关系,则满足第三范式

    应用第二、第三范式时,为了保证实体之间存在必要的关系,往往需要将独立的实体和当前实体通过外键关联起来

  规范化以后使用Viso软件创建数据库模型

44.三范式与数据库性能

  44.1第三范式的应用后数据库的变化

    1. 使得实体被最大限度地分割成若干个小实体
    2. 实体增多,同时实体之间地关系变得复杂,数据分布在多个表中
    3. 数据的查询和统计将变得复杂,多表连接查询会适当降低查询性能      

  44.2为了满足某种商业目的,数据库性能比规范化数据库更重要(实际需求>科学设计)

    1. 在给定地表中添加额外的字段,可大量减少需要从中搜索信息所需时间
    2. eg.高考成绩按三段式应该是 语数外+理综,四个列,实际应用时插入“总分”,该列其实冗余

  44.3进行规范化的同时,还需要综合考虑数据库的性能

    1. 三范式与数据库的性能要根据实际要求权衡
    2. 根据实际需求增加或减少冗余列