2012 -02-26 SQL数据库
顺序---> 建库-建表-创建约束-插入-修改-删除-查询
数据库DataBase,不同的数据应该放到不同的数据库中
原因:1.便于对各个数据类别进行个性化管理(分布式部署)
2.避免命名冲突
3.安全性更高
1.数据库要做的工作:
a) 针对数据的修改维护方便(硬盘里)
b) 使用快捷的搜索算法,获取数据
c) 数据格式变化
d) 并发处理, 安全处理 数据完整性
2.DBMS(数据库管理系统)
a) 数据库文件--核心数据库服务--客户端软件(SQLServer)
3.SQL语句查询过程:
a) 客户端软件 先输入SQL语句
b) SQL服务器将SQL语句 交给查询分析器,分析SQL语句语法,,检查通过的语句交给查询优化器,进行优化代码,匹配已经写好的优化规则 集合, 生成查询树后,交给查询执行器到缓存管理器中查到有没有已经存在的数据,有的话直接返回,没有的话 直接到mdf文件中查找
4.数据库 表中的主外键:
手写SQL语句 ------定义主键用( primary key(主键名))
关联外键:----Foreign key 外键字段名 references 目标表名(被关联的字段名)
a) 主键:数据行的唯一标识, 不会出现重复数据的列才能当做主键.表都必须设置主键.
b) 业务主键 与 逻辑主键 . (建议使用逻辑主键)
i. 逻辑主键:使用没有任何意义的字段做主键,
ii. 业务主键:使用有业务意义的字段做主键, 比如:身份证号.
5.主外键的作用;
a) 解决并减少数据冗余问题
b) 方便维护-----> 便于修改数据信息.
c) 可以优化查询效率.(面试放在最后讲,举例)
6.主外键的关系:
两张表存在依赖数据时,就可以使用主外键来解决.其中将依赖列作为主键的就叫做:主键表. 另一个就叫做外键表. 外键表的外键列数据取自主键表的主键
7.主外键约束:
为了避免两张表的主外键 数据 出现不一致情况,需要建立主外键 约束关系.
作用: 当两张表数据修改时出现 主外键数据不一致,则报错,拒绝修改
8.分离/附加 数据库的方法
a) 关闭SQL服务器,然后拷贝
b) 分离数据库后---拷贝---附加数据库,找到mdf文件
c) 脱机/联机 数据库
9.char类型:当储存的数据 小于 长度时,会自动用空格来补充, 固定长度的非Unicode字符数据,最大为8000字符.
10.Nchar类型: 使用Unicode编码,任意字符都占两个字节.固定长度的Unicode数据
11.Varchar类型: 当储存的数据 小于长度时,不会自动用空格来补充.理论上可以节约空间.可变长度的非Unicode数据
12.Text类型: 存储 长文本信息(数据指针,指向所保存的数据, 2G).一般博客内容可以使用Text
13.Varchar(max) 会导致数据的保存和加载速度比较慢
14.Datetime类型: 储存日期时间数据,如果要 用代码类 标识一个具体时间要加单引号" --->'2012-02-02'.
15.数字类型 int smallint,float, real
16.货币数据类型: Money(C#中的double)
17.Bit 数据类型: 是/否 1:代表true 0:代表false
18.给数据库设计表结构时, 为每个表的列中的说明 进行备注(该列的含义)
19.注意:开启数据库服务器的方法:
Cmd-----开启 Sqlserver-----net start/stop mssqlserver
20.SQL语句中 字符串用 单引号,单等号处理.
21.SQL语句 除关键字与字符串值外, 大小写不敏感
22.DDL数据库定义语言 DML数据操作语言 DCL数据库控制语言
23.手动创建数据库
CREATE DATABASE 数据库名
ON [PRIMARY]
(
<数据文件参数> [,…n]
)
[LOG ON]
(
<日志文件参数> [,…n]
)
a) use 数据库名(帮我们选择所使用的数据库)
b) 创建数据库 create database HeiMaBlog
Create database TestSchool
on primary --默认就属于primary主文件组,可省略
(
name='TestSchool',--主数据文件的逻辑名
filename='F:\SQL数据库mdf文件夹\TestSchool_data.mdf',--文件路径
size=3mb,--主数据文件初始大小
maxsize=10mb,--主数据文件最大的值
filegrowth=1mb--主数据文件的增长率
)
log on--日志文件
(
name='TestSchool_log',
filename='F:\SQL数据库mdf文件夹\TestSchool_log.mdf',
size=3mb,
maxsize=15mb,
filegrowth=1mb
)
go
c) Go关键字并不是SQL语法的规范,而是我们MSSQLServer软件的关键字(go是批处理语句,当客户端遇到go语句时,将go之前的语句当做单独的批次,发到服务器运行,然后再运行go之后的SQL语句.)
d) 自增 Identtity(1,1)
1.数据插入
1--Insert into 表名(列名1,列名2) values(值1,值2)
不写列名的前提: 当要向表中新增的数据中,包含所有的 (没有默认值或自动增长的列除外) 的值
2--自动编号列不需要手动插入。当表id设置为自动增长列时 又想手动设置id的值,要在插入语句前 将手动设置打开【SET IDENTITY_INSERT 表名 ON 】,on的时候必须手动给值. On开启代表自定义标识
3--N前缀: N'字符串' ,在服务器上执行的代码中(例如存储过程和触发器中)显示的Unicode字符串常量 必须以大写字母N 为前缀. 即使所用用的列已定义为Unicode类型,也应如此,否则可能导致不识别某些字符
2数据修改 update 优先级:Not > and > or
3.数据删除:
delete [from] 表名 where.... Delete只删除表数据,表还在 与drop 不同
a) 普通删除的时候,自增列的值不会清空.
4.Truncate + table +表名 删除表数据 表名---清空表里所有的行,同时重置自增列的值(从种子标量1开始计算)
a) Truncate语句非常高效.由于truncate操作采用按最小方式来记录日志,所以效率非常高,对于数百万条数据 使用truncate删除只要几秒,而使用delete则可能耗费几小时
b) 会把表中的自动编号重置为默认值
c) Truncate语句不触发delete触发器
5.Drop table 删除整个表结构
3.用户创建数据库及数据表的时候,其实就是把设置的数据(列的类型,列名等)都存入了系统表, 比如:我们select * from 表名 那么数据库会帮我们去系统表 , 根据表名查询出所有的列名,然后再查出对应的数据,效率比直接搜索 列名 要低
比如: 新增: insert into Users values()-->数据库会先帮我们去系统表查询该表的 自增字段的值(上一次新增生成的值),在此基础上+ 种子增量,求的当前要新增行的自增字段的值
约束: 保证数据的完整性(正确性)
数据库约束 是为了保证数据的完整性(正确性)而实现的一套机制.
0.非空约束,手动设置
1.主键约束(PK), primary key constraint 唯一 且 不为空
Alter table 表名 add constraint PK_表名 primary key(主键字段)
2.唯一约束(UQ),unique constraint 唯一,允许为空,但只能出现一次(鼠标右击--索引/键--添加--选择唯一键)
Alter table 表名 add constraint UQ_表名_字段名 unique(字段名)
3.默认约束(DF),设置列的默认值,就是默认约束(列属性里 对默认值进行设置)--在手写SQL语句字段后+ default '默认值'
Add constraint DF_表名_字段名 default('默认值') for 字段名
4.检查约束(CK), check constraint 范围以及格式限制 (设置限制表达式)
Add constraint CK_表名_字段名 check(约束范围)
5.外键约束(FK), foreign key constraint 表关系:保证外键值来源于主键
增加外键约束时, 设置级联更新, 级联删除
手写外键约束: Alter table 表名 add constraint FK_表名_字段名 foreign key(外键名) references 表名(主键名)
数据检索(查询)
1.select * from 表名 查询时,先到数据库系统表中, 查出表的所有列名,然后再根据列名查数据----限制结果集的 列
2. As 为 结果集的 列 取别名
3.Where 条件 根据条件查询,限制结果集的行.
----------Top语句--搜索结果集里的前N条 数据
1. 搜索普通的整数行: Select top 3 * from 表名
2. 搜索百分数: Select top 20 percent * from 表名 (只要出现小数就自动加一)--天花板
---------distinct关键字--针对查出的整个结果集 , 去除重复值
Select distinct age from 表名 求出不重复的age
Select distinct age,salary from 表名 求出age,salary组合不重复的(相当于将两个列的值 加在一起 不重复)
----------聚合函数(结果只有一个单元格)--------
1.聚合函数的结果集是单个值,没法与多个值的结果集结合
2.聚合函数可以和其他聚合函数的结果组合
3.Min(),max(),avg(),sum(),count()
4.Count()--结果集行数, 统计某一列的时候 会忽略表中的null值
5.avg(age) age列设置为int时,如果值是小数,也直接当整数算,不会自动加1(向下取整)
------between and 求两个值的区间,推荐使用----
Where between 18 and 20 删除 age为18 19 20 的列
-----in 关键字--------
1.Where id(1,4,6,7) 相当于 where id=1 or id=4 or id=6 or id=7
2.可以应用于 子查询, 当使用子查询配合in 关键字时,子查询的结果集必须只有一个列,而且 列的类型 必须和 条件列类型一致
--------模糊查询 like , 通配符 _ % [] ^----
--------not like--取like的反值
1._ : 单个任意字符
2.%: 任意长度,任意字符 where name like '%杨%'
3.[ ]: 代表取值范围中的一个字符 [a-z]:指所有的英文字母
4.^: 取非符 必须和[ ] 一起连用,一定要放到[ ]中 代表取非 [^a-z] .
5.要通配 _ ,%,[,^---->这些字符,[_],[%],[[],[^],
-------空值处理- is null 和 is not null------
1.数据库中null 表示 "不知道",与任何相关的都是不知道
2. Is null : 判断查询列中的值是不是null时,用is关键字---> name is null
3.Is not null : 查询非空值
4.Isnull(被判断的值,替换值)-->如果第一个参数为null,则使用第二个参数作为返回值,否则返回第一个参数.
--------排序order by 列名-------------
1.order by 列名 默认为升序(asc), 降序为desc
2.Order by age desc, id asc 多条件排序,当age中有相等的值,那这些行在按升序排列
3.Order by 语句必须放到 where语句之后,一般放在所有语句后,就是先让其他语句进行筛选,最后在进行下排序.
-------分组-group by 查询的是组的信息,不牵扯 个人信息---------------
1.根据年龄统计,各个年龄段的人数
Select count(*), age from Teacher group by age
2.强调---分组的结果是组的信息,与表中的单行信息无关
3.group by 分组后, 查询语句中 只能出现聚合函数 或者 分组的列
4.多条件分组: group by age, gender. 分组条件是age 和 gender 列的组合,只有当age和gender一样的值时,才分为一组.
-------having 语句 跟在group by语句之后---------
1.对分组后的信息 进行筛选的. 使用几乎与 where一样,也可以用 in....
--------类型转换函数---------------
1.cast(data as type): 将某个值 转成某个类型
Cast('123' as int ) --select cast(cast as int )将工资转成整型
Convert(int,'123') 类型转换(更强大)
------right() , left() 用来切割字符串
Right('abdfg',2) 从右边截取长度为2的字符串
Left('abcdef',3) 从左边截取长度为3的字符串
--------联合结果集 union(集合运算符)-------
1.合并结果集union用法:()
a) 要union的两个结果集的列数必须一致
b) 要链接的两个对应列的类型必须一致
c) 将多个结果集合并成一个结果集,去除重复值,,如果不想去除重复的话,用union all 链接
Select id,name,age from teacher
Union
Select id,name,age from student
2. 一次插入多行数据:
将T表中的数据 赋值到已经存在的T1表中
Insert into T1(id,name,gender,age)
Select *from T
把现有表的数据 插入到 新表(表不存在) ,将 oldTable表中的数据插入到新表newTable中
select * into newTable from oldTable
-------------字符串函数--------------------
1. len() : 计算字符串长度 len('aaaaa')
2. Datalength() : 获得字节的长度,Unicode代表2个字节
3. Lower() 转小写 upper() 转大写
4. Ltrim() : 去掉字符串左边的空格
5. Rtrim() : 去掉字符串右边的空格
6. Substring(原字符串, 从哪里开始截取, 所截取长度) ,索引从1开始计
----------------日期函数----------------
1.getdate() 获得当前日期时间
2.Dateadd(day, 10, getdate()) 修改日期(修改的部分-day,month,year, 增量,要新增的时间)
3.Datediff(day, '2011-02-26','2011-03-26') 求两个日期的差值
4.Datepart(day, getdate()) 获得日期的某个部分
a) Year() ,hour() ,day(),求时间的某个部分
开窗函数(应用于数据库分页技术): 只能出现在 select 或order by 子句中
1.row_number() over(order by 排序的列名)
2.Select row_number() over(order by ... desc) as rownum,+所要查询的列名
From 表名 ---查询出 排序后的结果集
3. 返回结果集中的 第三行到第五行
select * from
(
Select row_number() over(order by ... desc) as rownum,+所要查询的列名
) as table
Where table.rownum>=3 and table.rownum<=5