SQL 数据库系统中,表是数据库操作最基本的单元。数据库库中的所有数据都存储在表中。
表承载了真正的数据。
一个数据库中最多可以包含20亿张表。
一个表最多1024列。
每行最大字节数为8060
在表的创建、维护和删除,这三种操作,表的创建最为复杂!通常在生产环境中,定义填写表的书写规范是一件重要的事情,例如序号不能有重复,年龄字段内不能有负数、手机号码长度必须为11位,邮箱地址必须合法等要素。这就需要一些元素来限制,下面详细介绍~
主键 确保数据唯一
在SQL server2014数据库系统中,表通常具有包含唯一标识表中每一行值得一列或一组列,这样的一列或多列成为表的主键(PK).
用来唯一确定表中记录的标识符,其值不能为空,也不能重复。
一个表只能创建一个主键,并且自动建立聚集的索引,主键用于实现表的实体完整性,在创建或修改表时,可以通关关键字primary key 来创建主键。一个表中只能创建一个主键
在默认情况下,如图所示:这样创建的表是有问题的,在序号字段中是可以插入重复的值,这样就不能确保宠物信息表的完整性和不可重复性。
创建主键有三种方法
①添加主键的关键字
如图所示:添加主键可以控制序号不重复不为空。(这种方式不太推荐)这种方法的好处在于创建简单。
创建表完成之后,在表-->列,如图所示:会有一把锁的图标,代表了是主键。
在插入数据,尝试插入为空,如图所示:提示报错,证明设置主键后,值不能为空!
补全主键的值,如图所示:顺利插入
insert into taidi (SNO,sname,sex,sange) values(0001,'guibin','母',6)
再次插入序号字段相同的值,如图所示:提示报错,证明设置主键后不能有重复的的值。
这种方法的劣势在于,当你创建完主键后,你查看表中主键的名称过于复杂,后期编辑主键的时候调用这个名称是很麻烦的!
再分享第二种创建主键方法之前,需要介绍下索引的技术点!
索引工作模型
所谓的索引可以理解成目录,能够帮助我们快速找到想要的数据。
当数据众多的时候,在查询数据的时候(比如查序号,序号很多很多,339393)按顺序查询的话,从第一行开始查询的话,会花费很长时间!形成全文检索!
如图所示:索引的出现避免了所有字段的全文检索,只需要在索引目录区域中做一个字段的检索即可,索引目录的空间要比整张表空间小很多,速度上就会快很多!特别类似域架构中的活动目录。
索引类型
聚集索引:索引的顺序和真实数据的排列顺序是一致的!好比一本书的目录,书籍内容跟目录的顺序是一致的!聚集索引只能有一个!
非聚集索引:和聚集索引相比,索引目录中的数据和真实数据的顺序不一致!可以理解成英语词典中最后的单词表(以什么什么字母开头去查询,但是查询的单词不一定在整个数据内容中显示的顺序和自己想的一样!)非聚集索引多个可以成有多个!以各种维度去查询数据。(跟唯一键有关)。
②用聚集索引创建主键方法
相比主键关键字的方法,在创建完主键后,如图所示:能看到定义主键的名称也非常简洁
--创建主键,方法2
use aimiDB
create table taidi02
(
--定义索引名字
SNO int constraint PK_SNO primary key ClusterED(SNO),
sname char(10),
SEX char(2),
sange tinyint,
)
在创建完主键后同时也创建了聚集索引!
③聚集索引后置的方法
--创建主键,方法3
create table taidi03
(
--定义聚集索引
SNO int,
sname char(10),
SEX char(2),
sange tinyint,
constraint PK1_SNO primary key ClusterED(SNO)
)
如图所示:效果是一样的,只不过把定义主键和索引的名字往后挪,非常适合复合主键
复合主键的应用,在我创建的寄存表的架构中,定义狗的ID和序列号都为唯一,利用索引后置定义主键的方法可以完成:
--复合式主键定义
create table jicun
(
SNO int,
dogID int,
DepositDate Smalldatetime,
collarDate Smalldatetime,
constraint PK_jicun primary key clusterED(SNO,dogID)
)
如图所示:红框处并不表示表中创建两个主键,而是这两个字段组合在一起是一个主键。(别忘了,主键只能创建一个且不能有重复名称!)
唯一键-确保数据的唯一
在sql中,可以通过unique关键字来指定数据列的唯一性,多用于,姓名,联系电话等关键数据
用于指定一个字段或多个字段组合值是具有唯一性,以防止字段中有重复的值。
和Primary key的区别:
1>主键一个表只能一个,unique(唯一键)最多为249个。
2>主键的值不能为空,而unique可以有一行为空,不能有第二个。
3>主键默认情况下创建聚集索引,而unique默认创建非聚集索引。
在生产环境中,有些字段必须唯一!例如表的结构中,手机号和Email地址必须唯一且不可重复!如图所示:针对手机号码字段定义unique。(注意,我定义的手机号码字段长度为10,生产环境中为11)
--唯一键演示
create table weiyi
(
--定义聚集索引后置方法
SNO int,
sname char(10),
SEX char(2),
sange tinyint,
--定义唯一键盘,前置方式
stuMobileNo Char(10),constraint UQ_Mobile unique NonClusterED(stuMobileNO),
stuEmailADD Varchar(50),
constraint PK2_SNO primary key ClusterED(SNO)
)
如图所示:唯一键的图标是蓝色的小钥匙,而且索引方式是非聚集。
除了唯一键的前置方式,还有后置方式,如图所示:注意在红框处用,号分隔
唯一键原则认证
执行表中插入一条数据,如图所示:
插入数据后,查询数据情况:
下面我开始对唯一键的一些使用注意点分享
验证Unique可以为空
如图所示:插入一条不带有手机号字段的数据到表中。
--验证unique可以为空
insert into weiyi(SNO,sname,SEX,sange,stuEmailADD)
values(00011,'yanxiao','女',32,'1880000008@163.com')
查询数据:论证可以为空
验证unique不能有第二个null~
--验证unique不可以为重复出现null
insert into weiyi(SNO,sname,SEX,sange,stuEmailADD)
values(00012,'yanxiao1','女',29,'1880000008@163.com')
当然,在生产环境中,可以不然唯一键有能成为空值的办法。
验证unique不能重复
--验证unique不能重复
insert into weiyi(SNO,sname,SEX,sange,stuMobileNo,stuEmailADD)
values(00012,'xuanxiao','男',26,'1880000008','1320000008@163.com')
查询唯一键信息:
select * from sys.objects where type='UQ'
检查约束--check
约束(Constraint)是SQL server提供的自动保持数据库完整性的一种方法,通过对数据库中数据设置某种约束条件来保证数据的完整性!
检查约束是对相应字段输入值设置检查条件,以限制输入值满足某些条件。
比如:性别只能填写男或者女,年龄必须大于某些值(0或18),手机号必须要11位数字,邮箱地址要满足@的后缀格式等。
在SQL server中,有六种类型的约束!
1.主关键字约束
2.外关键字约束
3.唯一性约束
4.检查约束
5默认约束
6.空值约束
--约束年龄,前置演示
sange tinyint constraint C_sange check(sange>18)
如图所示:统一后置方式演示约束的功能,这里我创建了一个yueshu的表,针对性别、年龄、手机号、邮箱做了一定的规范。
create table yueshu
(
--定义聚集索引后置方法
SNO int,
sname char(10),
SEX char(2),
sange tinyint,
stuMobileNo Char(11) Not null,
stuEmailADD Varchar(50) Not null,
constraint PK3_SNO primary key ClusterED(SNO),
--约束键后置
constraint C_SEX check (SEX IN ('男','女')),
constraint C_sange check (sange>18),
constraint C_MobileNO check (stuMobileNO
like '[1][3456789][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
--通配符约束邮箱
constraint C_Email check (stuEmailADD Like '%_[@]%_[.]_%'),
--唯一键后置
constraint UQ_Mobile01 unique NonClusterED(stuMobileNO),
constraint UQ_Email01 unique NonClusterED(stuEmailADD)
)
SQL的通配符
% 表示匹配多个字符,也能匹配0个字符。
_ 表示匹配一个字符。
[]的意思在于任意一个字符
图中,能看到约束了4个值!
可以修改约束值的大小:
默认值
默认值是指定在插入操作中如果没有提供输入值的时候,系统自动指定的值。
1>一个字段只能指定一个默认值。
2>如果定义的默认值长于其对应字段的允许长度,在输入到列表中的默认值将被截断。
3>不能对数据类型为 timestamp(时间戳)的列或具有identity(身份)属性的列创建默认值定义。
缺省的默认值用法
在涉及表的结构时,例如,宠物寄存表中,在寄存的寄养时间上就是到店的时间,当店员往系统做寄养手续时(当前系统时间)可以认为是起始时间!就可以设定默认值。
--查看默认的时间的sql语句:
Select Getdate ()
执行以下sql语句,对表的默认值进行设定
创建jicun1表,主键为序号,寄存和取走的时间分别设置默认值,而取走的时间我定义为3个月(这里设定3个月为最长时间)
create table jicun1
(
SNO int,
dogID int,
--日期型
DepositDate Smalldatetime Default GetDate(),
collarDate Smalldatetime Default GetDate()+ 90,
constraint PK_jicun1 primary key clusterED(SNO,dogID)
)
当店员插入这一条记录时,这条数据并没有指定哪个字段为默认值,默认情况下就可以填上默认值的!
insert into jicun1 (SNO,DogID) values(70002,72)
这里查看到:相应的领取时间也会别显示出来!
代理键
用一个函数来表示进行数据的递增,如图所示:
8001代表的是第一行插入的值,1表示递变量。可以理解成帮你默认的按照序列号顺序插入后面的数据。
--代理键用法
create table jicun2
(
SNO int Identity(8001,1),
Sname char(10)
)
insert into jicun2 (Sname)values ('dubin')
insert into jicun2 (sname)values ('bomei')
insert into jicun2 (sname)values ('lachang')
insert into jicun2 (sname)values ('hashiqi')
如图所示:这个代理键会帮按照你设定+1递增后面的插入数据的SNO字段!
代理键的注意用法
当我删除某一行数据时,在使用代理键语句字段,我删除8002这行数据后再次插入后续的数据还会按照删除后的8002顺序继续递增吗?
delete from jicun2 where sname='bomei'
再次执行插入原先的数据
insert into jicun2 (sname)values ('bomei')
查看jicun2表,发现8002这个序列号的数据没有被填充,反而8005填充上了,顺序被打乱!
执行插入指定序列号、姓名的SQL语句:
insert into jicun2(SNO,Sname) values(8002,'yingniu')
如图所示:定义成代理键后不能进行随意插入,会提示dentity的值为Off。设置成ON就可以随意插入了~
设置IDENTITY为on
set identity_insert jicun2 ON
再次执行:
insert into jicun2(SNO,Sname) values(8002,'yingniu')
如图所示:成功执行
如图所示:再次查询,8002虽然被成功插入,但是之前8005占用了8002的那一行,因此排到了后面。
我们可以用SQL语句来顺序显示
select * from jicun2 order by SNO
注意的是,这里仅仅是显示,物理上还是删除一行数据后,后面数据将会排序上!
外键 -- Foreign key
外键用于联结两个表的数据,用来保证数据的完整性。
如果在foreign key 约束的列中输入非Null值,则此值必须在背引用列中存在;
foreign key约束仅能引用位于同一服务器上的同一数据库的表。
foreign key约束可引用同一表中的其他列,此行称之为自引用。
列级foreign key 约束只能列出一个引用列。此列的数据类型必须与定义约束的数据类型相同。‘’
foregin key 约束只能引用所引用表的 primary key 或 unique 约束中的列或所引用表上unique index中的列。
一个表中最多有32个外键,临时表不能有外键。
其中这个SNO序列号是唯一的且不可随便输入,并且要在A表中存在!当B表中插入一条数据,必须跟A表中的sno字段进行校验,形成外键!
外键创建方法
在aimiDB下,创建两张表 Abiao--Bbiao
Bbiao中创建外键字段为SNO,如图所示:
create table Abiao
(
SNO INT,
Sname char(10),
--将sno定义成主键
constraint PK_SNOa Primary key clusterED(SNO)
)
create table Bbiao
(
--外键的关键字
这里注意:外键的字段在原先的表中至少是唯一键盘或者主键。任何值和null做运算也都是Null,后期会详细介绍。
SNO int constraint FK_SNO Foreign key (SNO) references Abiao(SNO),
DogID INT,
DepositDate Smalldatetime Default GetDate(),
collarDate Smalldatetime Default GetDate()+ 180
)
创建好两张表之后,往表A中插入一些数据:
insert into Abiao values (75001,'erha')
insert into Abiao values (75002,'alasijia')
insert into Abiao values (75003,'langqing')
insert into Abiao values (75004,'xuenarui')
再次往B表中插入一些数据---这一条可以再A表中查询到,执行成功,
insert into Bbiao (SNO,DogID) Values (75003,2019070501)
但是有一条数据是在A表中查询不到的,因此提示报错:
insert into Bbiao (SNO,DogID) Values (65320,2019070501)