SQL Server教程 – T-SQL-DDL(Data Definition Language)


更新记录
转载请注明出处:https://www.cnblogs.com/cqpanda/p/16527432.html
2022年7月29日 发布。
2022年7月2日 从笔记迁移到博客。

系统数据库

概述

系统数据库是安装SQL Server实例时,系统默认创建的

数据库名称 描述
master 用户和配置信息等所有系统级信息
model 模板数据库
tempdb 临时数据库,保存临时数据
msdb 任务管理/计划任务

master数据库

master 数据库是SQL Server 2019中最重要的数据库,是整个数据库服务器的核心。用户不能直接修改该数据库,如果损坏了master数据库,那么整个SQL Server服务器将不能工作。该数据库中包含所有用户的登录信息、用户所在的组、所有系统的配置选项、服务器中本地数据库的名称和信息、SQL Server的初始化方式、AlwaysOn、数据库镜像、配置、登录、资源调控、端点等内容。应该定期备份master数据库。

注意:经常对master数据库进行备份。

model数据库

model 数据库是 SQL Server 2019中创建数据库的模板,如果用户希望创建的数据库有相同的初始化文件大小,则可以在model数据库中保存文件大小的信息;希望所有的数据库中都有一个相同的数据表,同样也可以将该数据表保存在 model 数据库中。因为将来创建的数据库都以 model数据库中的数据为模板,因此在修改model数据库之前要考虑到,任何对model数据库中数据的修改都将影响所有使用模板创建的数据库。

注意:如果没有model数据库,那么tempdb数据库也没有办法创建,因为每次SQL Server重启都会重建tempdb数据库,而新建数据库需要使用model数据库作为模板。

tempdb数据库

tempdb数据库是SQL Server中的一个临时数据库,用于存放临时对象或中间结果,SQL Server关闭后,该数据库中的内容将被清空,当重新启动服务器后,tempdb数据库又将被重建。

作用:临时数据库,保存临时数据

msdb数据库

msdb 数据库提供运行SQL Server Agent 工作的信息。SQL Server Agent是SQL Server中的一个Windows 服务,该服务用来运行制定的计划任务。计划任务其实是在SOL Server中定义的一个程序,该程序不需要干预即可自动开始执行。与tempdb和model 数据库一样,在使用SQL Server时也不要直接修改msdb数据库,SOL Server中的一些程序会自动使用该数据库。例如,当用户对数据进行存储或者备份时,msdb数据库会记录与这些任务相关的一些信息。

除了SQL Server代理数据外,还包括:

​ 服务代理(Service brokers)

​ 任务调度

​ 记录操作员的操作

​ 报警

​ 日志传送

​ SSIS包

​ 实用工具控制点(UCP)

​ 数据库邮件

​ 维护计划

resource数据库

这是一个隐藏的只读数据库

包含SQL Server中所有系统对象

主要用于改进SQL Server版本升级时的进程性能

distribution数据库

分发数据库

当实例配置为复制的分发者时,该库才存在

在配置复制之前,必须要完成此设置

数据库对象格式

格式

​ [服务器].[数据库].[架构名].[数据对象]

[Server].[database].[schema_name].object_name

除数据对象外,其他限定可以省略,但要保留点号,以下都是成立的:

server.database.schema_name.object_name
server.database..object_name
server…object_name
database.schema_name.object_name
database..object_name
schema_name.object_name
object_name

数据库组成

说明

数据库的存储结构分为:逻辑存储结构 和 物理存储结构

逻辑存储结构:

​ 说明数据库的抽象结构和支持的操作,一般程序员使用的界面

物理存储结构:

​ 数据库文件在磁盘中如何进行存储的结构

​ 包含数据库的数据结构和真实数据

以文件为存储单位,由数据库文件和日志文件组成

数据库物理存储结构

image

物理文件组成:
数据文件 和 日志文件

物理文件主要扩展名:

.mdf(Main Database File)

主数据文件
一个数据库有且只有一个
包含表、视图、存储过程之类的数据库对象

.ndf(Database File)

次数据文件
包含表、视图、存储过程之类的数据库对象
一个数据库可以有零个或多个

.ldf(Log Database File)
日志数据文件
日志文件包含用于支撑数据库事务恢复的信息
可以有一个或多个

文件组:
​ 主文件组:包含系统数据文件和没有分配给其他文件组的文件
​ 用户定义组:用户自定义的组

注意:
​ 每个文件只能属于一个组
​ 文件或文件组只能属于一个数据库
​ 数据和事务日志信息不能同属于一个文件或文件组
​ 日志文件不能作为文件组的一部分,日志和数据空间需要分开管理

默认数据库物理文件存储位置

C:/Program Files/Microsoft SQL Server/MSSQL10_50.MSSQLSERVER/MSSQL/DATA

创建数据库

创建数据库-使用SSMS

进入SSMS,点击创建数据库
image

设置参数-常规页
image

(1)数据库名称:输入 mytest作为数据库名称。
(2)所有者:这里可以指定任何一个拥有创建数据库权限的账户。此处为默认账户(default),即当前登录到SQL Server的账户。用户也可以修改此处的值,如果使用Windows系统身份验证登录,这里的值将会是系统用户ID;如果使用SQL Server 身份验证登录,这里的值将会是连接到服务器的ID.
(3)使用全文检索:如果想让数据库具有搜索特定内容的字段,需要选择此选项。
(4)逻辑名称:引用文件时使用的文件名。
(5)文件类型:表示该文件存放的内容,行数据表示这是一个数据库文件,其中存储了数据库中的数据:日志文件中记录的是用户对数据进行操作。
(6)文件组:为数据库中的文件指定文件组,可以指定的值为PRIMARY,数据库中必须有一个主文件组(PRIMARY).
(7)初始大小:该列下的两个值分别表示数据库文件的初始大小为8MB,日志文件的初始大
小为8MB.
(8)自动增长/最大大小:默认情况下,在增长时不限制文件的增长极限,即不限制文件增长,这样可以不必担心数据库的维护,但在数据库出现问题时磁盘空间可能会被完全占满。因此在应用时,要根据需要设置一个合理的文件增长的最大值。
(9)路径:数据库文件和日志文件的保存位置,默认的路径值为“C:/Program Files/Microsoft/SQL Server/MSSQL15.MSSQLSERVER/MSSQL/DATA”。如果要修改路径,单击路径右边带省略号的按钮,打开一个【定位文件夹】的对话框,选择想要保存数据的路径之后,单击【确认】按钮。
(10)添加按钮:添加多个数据文件或者日志文件,在单击【添加】按钮之后,将新增一行,在新增的【文件类型】列的下拉列表中可以选择文件类型,分别是【行数据】或者【日志】。
(11)删除按钮:删除指定的数据文件和日志文件。用鼠标选中想要删除的行,然后单击【删除】按钮,注意主数据文件不能被删除。

设置参数-选项页
image

(1)恢复模式
完整:允许发生错误时恢复数据库,在发生错误时,可以即时地使用事务日志恢复数据库。
大容量日志:当执行操作的数据量较大时,只记录该操作事件,并不记录插入的细节。例如,向数据库插入上万条记录数据,此时只记录了该插入操作,而对于每一行插入的内容并不记录。这种方式可以在执行某些操作时提高系统性能,但是当服务器出现问题时,只能恢复到最后一次备份的日志中的内容。
简单:每次备份数据库时清楚事务日志,该选项表示根据最后一次对数据库的备份进行恢复。
(2)兼容性级别
兼容性级别:是否允许建立一个兼容早期版本的数据库,如要兼容早期版本的 SQL Server,
则新版本中的一些功能将不能使用。

创建数据库-使用T-SQL

官方语法说明:
image

参数说明:
database_name:数据库名称,不能与SQL Server中现有的数据库实例名称相冲突,名称中最多可以包含128个字符。
ON:指定显示定义用来存储数据库中数据的磁盘文件。
PRIMARY:指定关联的<filespec>列表定义的主文件,在主文件组<filespec>项中指定的第一个文件将生成主文件,一个数据库只能有一个主文件。如果没有指定PRIMARY,那么CREATE DATABASE 语句中列出的第一个文件将成为主文件。
LOG ON:指定用来存储数据库日志的日志文件。LOGON后跟以逗号分隔的用以定义日志文件的 项列表。如果没有指定LOGON,将自动创建一个日志文件,其大小为该数据库的所有数据文件大小总和的25%或512KB,取两者之中的较大者。
NAME:指定文件的逻辑名称。在指定 FILENAME时,需要使用NAME,除非指定 FOR ATTACH 子句之一。无法将FILESTREAM文件组命名为PRIMARY.
FILENAME:指定创建文件时由操作系统使用的路径和文件名,执行 CREATE DATABASE语句前,指定的路径必须存在。
SIZE:指定数据库文件的初始大小,如果没有为主文件提供size,数据库引擎将使用 model 数据库中的主文件的大小。
MAXSIZE: max_size:指定文件可增大到最大大小。可以使用KB、MB、GB和TB作为后缀,默认值为MB.max_size是整数值。如果不指定max_size,则文件将不断增长直至磁盘被占满。UNLIMITED表示文件一直增长到磁盘装满。
FILEGROWTH:指定文件的自动增量。文件的FILEGROWTH设置不能超过MAXSIZE设置。该值可以MB、KB、GB、TB或百分比(%)为单位指定,默认值为MB.如果指定%,则增量大小为发生增长时文件大小的指定百分比。值为0时表明自动增长被设置为关闭,不允许增加空间。
注意:数据库名最长128个字符。
注意:NAME字段,数据库的逻辑名,必须是唯一的。
注意:PRIMARY关键字是可选的,如果没有指定,则第一个数据库文件为主文件。
注意:SIZE和MAXSIZE和FILEGROWTH支持MB、GB、TB为单位,默认不写为MB。
注意:SIZE和MAXSIZE和FILEGROWTH支持使用UNLIMITED,表示无限制。
注意:FILEGROWTH支持%和0,%表示按比例增长,0表示不允许增长。

实例:

CREATE DATABASE [数据库名]
ON PRIMARY
(
    NAME = panda_test,
    FILENAME = N'D:/panda_test.mdf',
    SIZE = 10MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 10MB
),
(
    NAME = panda_test_2,
    FILENAME = N'D:/panda_test_2.ndf',
    SIZE = 10MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 10%
)
LOG ON
(
    NAME = panda_test_log,
    FILENAME = N'D:/panda_test_log.ldf',
    SIZE = 2MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 10%
),
(
    NAME = panda_test_log_2,
    FILENAME = N'D:/panda_test_log_2.ldf',
    SIZE = 2MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 10%
);

创建数据库之前检测数据库存在:

IF NOT EXISIS
(SELECT name FROM sys.databases WHERE name = N'数据库名');

实例1:直接创建

CREATE DATABASE [数据库名]

创建数据库的最佳实践

根据数据库中预期大小创建尽可能大的数据文件,比如:UNLIMITED

使用数据库次要文件的场景

数据库主文件将要或已经达到盘分区容量,通过次要文件放在其他盘来解决

数据库文件放置在不同的盘提高 SQL Server 的运行效率

创建数据库之间验证数据库是否存在

USE master
GO
IF NOT EXISTS (
   SELECT name
   FROM sys.databases
   WHERE name = N'TutorialDB'
)
CREATE DATABASE [TutorialDB]
GO

修改数据库

修改数据库注意

确保没有任何用户正在使用数据库,再进行修改数据库。

修改数据库-使用 SSMS

点击数据库,选择属性。

image

进入数据库属性页进行修改。
image

修改数据库参数-使用T-SQL

ALTER DATABASE 语句可以进行以下的修改:增加或删除数据文件、改变数据文件、文件的大小和增长方式、增加或者删除日志文件和文件组。
image

参数说明:
database_name:要修改的数据库名称。
MODIFY NAME:指定新的数据库名称。
ADD FILE:向数据库中添加文件。
TO FILEGROUP {filegroup_name}:将指定文件添加到的文件组。filegroup_name为文件组名。
ADD LOG FILE:将要添加的日志文件添加到指定的数据库。
REMOVE FILE logical_file_name:从SQL Server 的实例中删除逻辑文件并删除物理文件,除非文件为空,否则无法删除文件。logical_file_name是在SQL Server 中引用文件时所用的逻辑名称。
MODIFY FILE:指定应修改的文件。一次只能更改一个<filespec>属性。必须在<filespec>中指定NAME,以标识要修改的文件。如果指定了SIZE,那么新大小必须比文件当前大小要大。
MODIFY NAME:使用指定的名称重命名数据库。
ADD FILE…TO FILEGROUP:添加新数据库文件到指定的文件组中。
ADD FILEGROUP:向数据库中添加文件组。
REMOVE FILEGROUP:从数据库中删除文件组。除非文件组为空,否则无法将该文组删除。
MODIFY FILEGROUP:通过将状态设置为READ_ONLY或READ_WRITE,将文件组设置为数据库的默认文件组或者通过更改文件组名称来修改文件组。

修改数据库-增加数据库文件-使用T-SQL

ALTER DATABASE PandaTest
ADD FILE
(
    NAME = PandaTest,
    FILENAME = 'F:/PandaTest2.ndf',
    SIZE = 10MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 10%
) TO FILEGROUP [文件组名];

实例:

ALTER DATABASE [panda_test2]
ADD FILE
(
    NAME = [panda_file_3],
    FILENAME = 'D:/panda_test_3.ldf',
    SIZE = 8MB,
    MAXSIZE = 300MB,
    FILEGROWTH = 10%
)
TO FILEGROUP [panda_group1];

修改数据库-增加数据库日志文件-使用T-SQL

ALTER DATABASE PandaTest
ADD LOG FILE
(
    NAME = PandaTestLog,
    FILENAME = 'F:/PandaTestLog2.ldf',
    SIZE = 10MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 10%
);

修改数据库-添加文件并添加到指定文件组-使用T-SQL

ALTER DATABASE PandaTest
ADD LOG FILE
(
    NAME = PandaTestLog,
    FILENAME = 'F:/PandaTestLog2.ldf',
    SIZE = 10MB,
    MAXSIZE = UNLIMITED,
    FILEGROWTH = 10%
) TO FILEGROUP [文件组名];

修改数据库-删除数据库文件-使用T-SQL

ALTER DATABASE PandaTest
REMOVE FILE PandaTestLog;

修改数据库-修改数据库文件大小-使用T-SQL

注意:如果修改了文件大小(SIZE),文件大小必须比原有大小要大

ALTER DATABASE PandaTest
MODIFY FILE
(
    NAME = PandaTest_DATA,
    SIZE = 50MB
    ....
);

修改数据库-修改数据库文件的最大大小-使用T-SQL

ALTER DATABASE PandaTest
MODIFY FILE
(
	NAME = PandaTest_DATA,
    MAXSIZE = 5000MB
);

修改数据库-修改数据库名-使用T-SQL

EXEC sp_renamedb 'PandaTest' ,'Panda';

或者

ALTER DATABASE PandaTest
MODIFY NAME = [新数据库名];

修改数据库-添加文件组-使用T-SQL

ALTER DATABASE PandaTest
ADD FILEGROUP [文件组名];

修改数据库-移除文件组-使用T-SQL

ALTER DATABASE PandaTest
REMOVE FILEGROUP [文件组名];

开启数据库查询存储-使用T-SQL

Query Store是SQL Server 2016中引入的、语句级别的性能监控和调优工具
不仅自动捕获查询(Query)、执行计划(Plan)、运行时统计信息(Runtime)和等待(Wait)统计的信息
而且还可以识别出由于执行计划更改而导致的性能差异,简化了性能故障排除的流程,降低了性能优化的难度

ALTER DATABASE [TutorialDB] SET QUERY_STORE=ON

删除数据库

删除数据库-使用SSMS

image

删除数据库-使用T-SQL

DROP DATABASE Panda;

注意:在删除数据库之前确保数据库没有被使用

使用数据库

USE [DBName];

查看数据库

查看数据库文件详细信息-使用T-SQL

使用sys.database_files视图查看

USE [panda_test];
SELECT *
FROM SYS.database_files;

结果:
image

查看数据库在线状态-使用T-SQL

SELECT name,state_desc FROM sys.databases;

数据库支持的状态:
image

image

查看数据库文件组信息-使用T-SQL

使用sys.filegroups视图查看

USE [panda_test];
SELECT *
FROM SYS.filegroups;

结果:
image

查看所有数据库的文件的基本信息-使用T-SQL

使用sys.master_files视图查看

USE [panda_test];
SELECT *
FROM SYS.master_files;

结果:

image

查看所有数据库的基本信息-使用T-SQL

使用sys.databases视图查看

SELECT *
FROM SYS.databases;

结果:
image

查看数据库的指定信息-使用T-SQL

使用函数:

SELECT DATABASEPROPERTYEX('panda_test','要查询的项');

查询的项支持:
image

image

image
实例:

SELECT DATABASEPROPERTYEX('panda_test','collation');

结果:
image

查看数据库磁盘使用空间-使用T-SQL

使用存储过程sp_spaceused查看数据库使用和保留空间

USE panda_test;
EXEC sp_spaceused;

结果:
image

查看数据库磁盘使用空间-使用SSMS

选中数据库,鼠标右键,依次选择【报表】I【标准报表】,选择 【磁盘使用情况】
image

查看所有数据库占用磁盘大小-使用T-SQL

使用存储过程sp_helpdb

EXEC sp_helpdb;

结果:
image

获得数据库的ID

SELECT DB_ID(N'PandaDatabase');

获得数据库的名称

SELECT DB_NAME(), DB_NAME(DB_ID('PandaDatabase'));

导出数据库脚本-使用SSMS

进入导出脚本页面
image

还可以选择导出数据结构或者数据
image

表的类型

持久基表:
就是平时用来保存数据的表,是最常用的表
全局临时表:
在tempdb数据库下建立的表,可以被所有用户访问
当所用用户都断开连接之后,将删除全局临时表
表名以##开头
可以使用CREATE TABLE 或 SELECT INTO 创建全局临时表
局部临时表:
在tempdb数据库下建立的表
当创建者断开连接后,系统自动删除该表
表名以#开头
可以使用CREATE TABLE 或 SELECT INTO 创建局部临时表
image

表变量:
在内存中创建的只对创建者可见的临时表
是SQL SERVER提供的一种数据类型
当创建者断开连接后,系统自动删除该表

创建数据表

创建数据表-使用SSMS

image

创建数据表-使用T-SQL

CREATE TABLE [数据库名].[架构名].表名
(
    属性名 数据类型 [CONSTRAINT 约束名] [约束] [约束参数]
);

注意:外键约束要单独写
注意:数据库名和架构名可以不写,但会使用默认值
注意:创建全局临时表,表名使用##开头
注意:创建局部临时表,表名使用#开头

外键关联:

CREATE TABLE [表名]
(
    属性名 数据类型 [CONSTRAINT 约束名] [约束] [约束参数],
    [CONSTRAINT 约束名] FOREIGN KEY(列名)
    REFERENCES 表名(列名)
);

实例:自增长字段

CREATE TABLE [PandaTable]
(
    Id INT PRIMARY KEY IDENTITY(1,1),
    -- 从1开始,每次自增1
)

实例:局部临时表

CREATE TABLE [#PandaTable]
(
    Id INT PRIMARY KEY IDENTITY(1,1),
    -- 从1开始,每次自增1
)

实例:全局临时表

CREATE TABLE [#PandaTable]
(
    Id INT PRIMARY KEY IDENTITY(1,1),
    -- 从1开始,每次自增1
)

如果表存在则删除表

IF(OBJECT_ID('dbo.表名')) IS NOT NULL
DROP TABLE dob.表名

删除数据表

删除数据库的前提

删除数据库中的所有数据库快照
如果日志传送涉及数据库,就删除日志传送
如果为事务复制发布了数据库或将数据库发布或订阅到合并复制,移除复制
用户必须至少对数据库具有 CONTROL 权限

使用SSMS

image

使用T-SQL

DROP TABLE 表名;

清空表-使用T-SQL

TRUNCATE TABLE TestData.dbo.Products

架构(Schema)

架构说明

类似编程语言中的命名空间

创建架构-使用SSMS

进入指定的数据库-进入安全性-架构
image

创建架构-使用T-SQL

CREATE SCHEMA [架构名] AUTHORIZATION 所属人;

实例:

CREATE SCHEMA [Panda_Schema] AUTHORIZATION GUEST;

删除架构-使用T-SQL

DROP SCHEMA [架构名];

实例:

DROP SCHEMA [Panda_Schema];

删除架构-使用SSMS

image

修改数据表

修改表-使用SSMS

image

修改表-使用T-SQL

修改列-增加表的列-使用T-SQL

ALTER TABLE 表名
ADD 属性名 数据类型(长度) [约束];

修改列-删除表的列-使用T-SQL

ALTER TABLE 表名
DROP COLUMN 属性名;

修改列-修改表的列-使用T-SQL

ALTER TABLE 表名
ALTER COLUMN 属性名 数据类型 [CONSTRAINT 约束名] [约束];

修改列-修改表的列名-使用T-SQL

EXEC sp_rename '表名.列名','新列名';

修改列-修改表的表名-使用T-SQL

EXEC sp_rename '原表名','新表名';

修改列-删除约束-使用T-SQL

ALTER TABLE 表名
DROP CONSTRAINT 约束名称

查看数据表

查询字段名称

SELECT COL_NAME(OBJECT_ID('PandaTable'),1);

查看表字段结构

exec sp_columns 表名

约束(Constraint)

说明

可以在表或字段上设置约束,确保符合数据完整性约束。
image

常见约束关键字

PRIMARY KEY     -- 主键
FOREIGN KEY     -- 外键
IDENTITY        -- 生成连续编号
UNIQUE          -- 必须唯一,但可以为空
NOT NULL        -- 非空约束
NULL            -- 可空约束
CHECK           -- 约束条件
DEFAULT 默认值   -- 设置默认值

注意:DEFAULT不可以用于timestamp数据类型
注意:DEFAULT不可以用于IDENTITY列
注意:DEFAULT不可以用于ROWGUIDCOL列
提示:DEFAULT可以配合函数使用,比如:DEFAULT GETDATE()、DEFAULT GUID()
提示:PRIMARY KEY和UNIQUE区别:
UNIQUE可以包含NULL,PRIMARY KEY不可以包含NULL
表只能有一个PRIMARY KEY,可以有多个UNIQUE

修改列约束

修改列的非空约束

ALTER TABLE 表名
ALTER COLUMN 列名 数据类型 NOT NULL | NULL;

增加列约束

ALTER TABLE 表名
ADD [CONSTRAINT 约束名] 约束(列名);

或者在创建表的时候就加入约束

CREATE TABLE [表名]
(
	字段 数据类型 [CONSTRAINT 约束名] 约束
)

增加PRIMARY KEY约束

ALTER TABLE 表名
ADD CONSTRAINT 约束名 PRIMARY KEY(列名,...);

增加UNIQUE约束

ALTER TABLE 表名
ADD CONSTRAINT 约束名 UNIQUE(属性名);

注意:UNIQUE约束是可以为NULL的
注意:UNIQUE 约束是允许空值的
注意:使用了 UNIQUE 约束的字段会建立唯一性索引
注意:在默认的情况下, UNIQUE 约束创建的是非聚集索引

增加CHECK约束

ALTER TABLE 表名
ADD CONSTRAINT 约束名 CHECK(条件表达式);

增加DEFAULT约束

ALTER TABLE 表名
ADD CONSTRAINT 约束名 DEFAULT(值) FOR 列名;

增加FOREIGN KEY约束

ALTER TABLE 表名
ADD CONSTRAINT 约束名 FOREIGN KEY(列名)
REFERENCES 表名(列名);

或者在定义时就增加

CREATE TABLE Employee 
( 
    Eid    INT PRIMARY KEY, 
    Ename  VARCHAR(30), 
    Salary MONEY, 
    Dno    INT FOREIGN KEY REFERENCES Dept(Dno) 
)

注意:表中最多可以使用 31 个外键约束
注意:临时表中不能建立外键约束.
注意:主键和外键的数据类型必须严格匹配

删除列约束

ALTER TABLE 表名
DROP CONSTRAINT 约束名;

What are the differences between the primary key and unique key in SQL Server?

As we already discussed both unique key and Primary Key handles the uniqueness of a column on which they are applied. But the difference is that by default in SQL Server the primary key creates a unique clustered index whereas the unique key creates a unique non-clustered index on the column. Another difference between them is that the primary key column doesn’t allow NULL values whereas the unique key column allows only one NULL value.

What is the difference between Primary Key and Foreign Key Constraint in SQL Server?

Primary Key in SQL Server:

  1. The Primary Key Constraint in SQL Server uniquely identifies a record in the table.
  2. Primary Key constraint neither accepts null values nor duplicate values on the column on which it is applied.
  3. By default Primary Key Constraint in SQL Server create a unique clustered index that will physically organize the data in the table.
  4. We can create only one Primary Key on a table in SQL Server. The most important point is that you can create the primary key either on a single column or multiple columns.

Foreign Key in SQL Server:

  1. The Foreign Key in SQL Server is a field in a table that is a unique key in another table.
  2. A Foreign Key can accept both null values and duplicate values in SQL Server.
  3. By default, the foreign key does not create any index. If you need then you can create an index on the foreign key column manually.
  4. We can create more than one Foreign key on a table in SQL Server.

Note: We can’t insert foreign key column value into the table if the primary key value not available but the reverse is possible. We can’t delete the primary key value if the foreign key reference is set into the table but the reverse is possible.

Is it possible that a foreign key references a non-primary key in SQL Server?

Yes, it is possible. The point that you need to keep in mind is that a foreign key actually references a key that should contain unique values. So it may be a primary key or unique key as both keys maintain the uniqueness of the column of a table.

主键与外键层级关联问题(Cascading Referential Integrity Constraint)

主键与外键关联问题就是:当被引用的表的(主键)记录被删除/更新,后引用该表数据的表如何处理。

支持以下操作:

SET NULL:
If a user tries to delete or update statement(s) that will affect rows in the foreign key table, then those values will be set to NULL when the primary key record is deleted or updated in the Primary key table. The important thing that we need to keep in mind that the foreign key columns affected must allow NULL values.

CASCADE:
If a user tries to delete the statement(s) which will affect the rows in the foreign key table, then those rows will be deleted when the primary key record is deleted. Similarly, if an update statement affects rows in the foreign key table, then those rows will be updated with the value from the primary key record after it has been updated.

SET DEFAULT:
If a delete or update statement affects rows in a foreign key table, then all rows containing those foreign keys are set to the default value. All foreign key columns in the related table must have default constraints defined on them.

NO ACTION:
This is the default action that SQL Server performs. This specifies that if an update or deletes statement affects rows in foreign key tables, then the action will be denied and rolled back. An error message will be raised.

可以在定义外键约束的时候按需求进行设置:

<COLUMN> <DATATYPE> <CONSTRAINT NAME> REFERENCES <MASTER TABLENAME>(<PRIMARY KEY COLUMN>)
ON DELETE (NO ACTION/CASCADE/SET NULL/DEFAULT}
ON UPDATE (NO ACTION/CASCADE/SET NULL/DEFAULT}

实例:

CREATE TABLE [Person](
  [Id] [int] PRIMARY KEY,
  [Name] [varchar](100) NOT NULL,
  [Email] [varchar](100) NOT NULL,
  [GenderID] [int] CONSTRAINT FK_Person_GenderID FOREIGN KEY REFERENCES dbo.Gender(Id) 
  												ON DELETE CASCADE 
  												ON UPDATE CASCADE
)

Identity Column(标识列)

What is Identity in SQL Server?

The Identity in SQL Server is a property that can be applied to a column of a table whose value is automatically created by the server. So, whenever you marked a column as identity, then that column will be filled in an auto-increment way by SQL Server. That means as a user we cannot insert a value manually into an identity column.

语法

IDENTITY [(seed,increment)]

Arguments:
Seed: Starting value of a column. The default value is 1.
Increment: It specifies the incremental value that is added to the identity column value of the previous row. The default value is 1.

实例:

PersonId int identity(1, 1),
-- 或者通过修改表的方式加入
ALTER TABLE Person
ADD PersonId INT IDENTITY(1,1); 

How to explicitly supply Values for Identity Column in SQL Server?

设置为可以手动插入Identity列

SET Identity_Insert [表名] ON

然后插入完成后,再关闭不可以手动插入Identity列

SET Identity_Insert [表名] OFF

How to Reset the Identity Column Value in SQL Server?

DBCC CHECKIDENT([表名], RESEED, 0)

How we will get the last generated identity column value in SQL Server?

三种方法:

SCOPE_IDENTITY()
@@IDENTITY
IDENT_CURRENT([表名])

区别如下:

The SCOPE_IDENTITY() returns the last identity value that is created in the same session (Connection) and in the same scope (in the same Stored procedure, function, trigger). Let’s say, I have 2 tables Person1 and Person2 and I have a trigger on the Person1 table, which will insert a record into the Person2 table.

Now, when we insert a record into the Person1 table, SCOPE_IDENTITY() returns the identity value that is generated in the Person1 table, whereas @@IDENTITY returns, the value that is generated in the Person2 table.

So @@IDENTITY returns the last identity value that is created in the same session without any consideration to the scope. The IDENT_CURRENT(‘Person’) returns the last identity value created for a specific table across any session and any scope.

默认值(Default)

说明

默认值指用户在插入数据时,如果没有给某个字段指定相应的数值,SQL Server 系统会自动为该字段填充一个数值。默认值可以应用于字段或用户定义的数据类型,但是认值不会因对字段或用户定义的数据类型进行了修改、删除等操作而受到影响。

默认值注意:

默认值只在INSERT语句中使用,即在UPDATE语句和DELETE语句中将被忽略。
如果在INSERT语句中提供了任意值,那么就不使用默认值。
如果没有提供值,那么就使用默认值。
对于默认值约束,有以下可以执行的操作:
在数据表定义时作为表的一部分同时被创建。
可以添加到已创建的表中。
可以删除DEFAULT定义。

创建默认值

创建默认值可使用CREATE DEFAULT语句

CREATE DEEAULT <default_name>
AS <constant_expression>

default_name:默认值的名称。
constant_expression:包含常量值的表达式。

实例:在stu_info表中创建默认值

CREATE DEFAULT defaultSex AS'男'

把自定义默认值绑定到字段

默认值必须绑定到字段或用户定义的数据类型,这样创建的默认值才可以应用到字段。绑定默认值使用系统存储过程sp_bindefault

sp _bindefault 'default', 'object_name', [,'futureonly_flag']

default:由 CREATE DEFAULT创建的默认值(用默认值名称来指定)。
object_name:将默认值绑定到的数据表、字段列或别名数据类型。

实例:

EXEC sp_bindefault 'defaultSex', 'stu_info.s_sex'

取消默认值的绑定

如果想取消默认值的绑定,可以使用系统存储过程 sp_unbindefault 语句将绑定取消。

sp_unbindefault 'object_name', [,'futureonly_flag']

实例:

EXEC sp_unbindefault 'stu_info.s_sex'
EXEC sp_unbindefault 'PandaTable.NAME';

删除默认值

当默认值不再需要使用时,可以使用DROP DEFAULT语句将其删除,DROP DEFAULT 语句

DROP DEFAULT default_name

default_name表示要删除的默认值(用默认值名称来指定)。

规则(Rule)

说明

规则是对存储的数据表的字段(即列)或用户定义数据类型中的值的约束,规则与其作用的表或用户定义数据类型是相互独立的,也就是说,对数据表或用户定义数据类型的任何操作不影响对其设置的规则。

规则的使用

规则的基本操作包括创建、绑定、验证、取消和删除。

创建规则

创建规使用CREATE RULE语句

CREATE RULE rule_name
AS condition_expression

rule_name:表示新规则的名称。规则名称必须符合标识符的命名规则。
condition_expression:表示定义规则的条件。规则可以是WHERE子句中任何有效的表达式,并且可以包括诸如算术运算符、关系运算符和谓词(如IN、LIKE、BETWEEN)这样的元素。但是,规则不能引用字段或其他数据库对象。

实例:为stu_info表定义一个规则,指定其成绩字段的值必须大于0且小于100

GO
CREATE RULE rule_score
AS
@score > 0 AND @score < 100
GO

绑定规则

使用系统存储过程sp_bindrule

sp_bindrule rule_name,[Table_Name.Column_Name];

实例:

GO
-- 创建规则
CREATE RULE prule
AS
@A > 5 AND @A < 10;
GO
-- 创建表格用于测试
CREATE TABLE PandaTable
(
	Id INT PRIMARY KEY IDENTITY,
	NAME VARCHAR(266),
	AGE INT NOT NULL
);
GO
-- 将规则应用到表格
 EXEC sp_bindrule prule,[PandaTable.AGE];
GO

验证规则

规则绑定到指定的字段上之后,用户的操作必须满足规则的要求,如果用户执行了违反规则的操作,将被禁止执行。

GO
-- 创建规则
CREATE RULE prule
AS
@A > 5 AND @A < 10;
GO
-- 创建表格用于测试
CREATE TABLE PandaTable
(
	Id INT PRIMARY KEY IDENTITY,
	NAME VARCHAR(266),
	AGE INT NOT NULL
);
GO
-- 将规则应用到表格
 EXEC sp_bindrule prule,[PandaTable.AGE];
GO
-- 插入不符合规则的数据
INSERT INTO [PandaTable] VALUES
('Cat',1)
GO

将提示错误
image

取消规则绑定

如果不再使用规则,可以将规则解除,使用系统存储过程 sp_unbindrule 可以解除规则。

sp_unbindrule 'object_name' [ , 'futureonly_flag' ]

实例:

EXEC sp_unbindrule 'stu info.s_score'

删除规则

当规则不再需要使用时,可以使用DROP RULE语句将其删除,DROP RULE 语句可以同时删除多个规则

DROP RULE rule_name

注意:删除规则时必须确保待删除的规则没有与任何数据表中的字段绑定,正在使用的规则将不允许被删除。

实例:

DROP RULE rule_score;

Sequence Object(序列对象)

What is a Sequence Object in SQL Server?

A sequence is an object in SQL Server that is used to generate a number sequence. This can be useful when we need to create a unique number to act as a primary key.

The Sequence Object is one of the new features introduced in SQL Server 2012. A sequence is a user-defined object and as its name suggests it generates a sequence of numeric values according to the properties with which it is created. It is similar to the Identity column, but there are many differences between them that we will discuss in our next article. But the most important point to keep in mind is that the Sequence Object in SQL Server is not limited to a column or table but is scoped to an entire database.

Syntax of Sequence Object in SQL Server

CREATE SEQUENCE [schema_name . ] sequence_name
    [ AS [ built_in_integer_type | user-defined_integer_type ] ]
    [ START WITH <constant> ]
    [ INCREMENT BY <constant> ]
    [ { MINVALUE [ <constant> ] } | { NO MINVALUE } ]
    [ { MAXVALUE [ <constant> ] } | { NO MAXVALUE } ]
    [ CYCLE | { NO CYCLE } ]
    [ { CACHE [ <constant> ] } | { NO CACHE } ]
    [ ; ] 

Properties of Sequence Object:
DataType: Built-in integer type (tinyint, smallint, int, bigint, decimal, etc…) or user-defined integer type. The default is bigint.
START WITH: The Start With Value is nothing but the first value that is going to be returned by the sequence object
INCREMENT BY: The Increment by value is nothing but the value to increment or decrement by the sequence object for each row. If you specify a negative value then the value is going to be decrement.
MINVALUE: It specifies the value for the sequence object
NO MINVALUE: It specifies that there is no minimum value specified for the given sequence object.
MAXVALUE: Maximum value for the sequence object
NO MAXVALUE: It means that there is no maximum value specified for the sequence.
CYCLE: It specifies that reset the sequence object when the Sequence Object reached the maximum or minimum value.
NO CYCLE: When you specify the No Cycle option, then it will throw an error when the Sequence Object reached its maximum or minimum value.
CACHE: Cache sequence values for performance. The default value is CACHE.
NO CACHE: As the name says, if you specify the NO CACHE option then it will not cache the sequence numbers.

Note: If you have not specified either Cycle or No Cycle then the default is No Cycle in SQL Server.

实例:

CREATE SEQUENCE [dbo].[SequenceObject]
AS INT
START WITH 1
INCREMENT BY 1

在SSMS中创建Sequence

image

Drop Sequence object

DROP SEQUENCE sequence_name

How to Generate the Next Sequence Value in SQL Server?

Once we created the sequence object, now let see how to generate the sequence object value. To generate the sequence value in SQL Server, we need to use the NEXT VALUE FOR clause as shown below

SELECT NEXT VALUE FOR [dbo].[SequenceObject]

How to see the current Sequence value

SELECT * FROM sys.sequences WHERE name = 'SequenceObject'

How to Retrieving the current sequence value in SQL Server?

ALTER SEQUENCE [SequenceObject] RESTART WITH 1

在INSERT中使用

INSERT INTO Employees VALUES
(NEXT VALUE for [dbo].[SequenceObject], 'Ben', 'Male')
INSERT INTO Employees VALUES
(NEXT VALUE for [dbo].[SequenceObject], 'Sara', 'Female')

在Table中使用

CREATE TABLE dbo.Customer (
  ID INT DEFAULT(NEXT VALUE FOR DBO.SequenceObject),
    Name VARCHAR(100)
)

Creating the Decrementing Sequence in SQL Server

CREATE SEQUENCE [dbo].[SequenceObject] 
AS INT
START WITH 100
INCREMENT BY -1

Specifying MIN and MAX values for the sequence

CREATE SEQUENCE [dbo].[SequenceObject]
START WITH 100
INCREMENT BY 10
MINVALUE 100
MAXVALUE 150

How to Recycling the Sequence values in SQL Server

ALTER SEQUENCE [dbo].[SequenceObject]
INCREMENT BY 10
MINVALUE 100
MAXVALUE 150
CYCLE

How To Improve the Performance of Sequence Object in SQL Server

If you want to improve the performance then you can Cache the Sequence object values by using the CACHE option in SQL Server. When the Sequence Object values are cached, then they are simply read from the memory instead of the disk which will improve the performance of the application. When the cache option is specified, if you want then you can also specify the size of the cache that is the number of values to be cached.

The example below going to create the sequence object with 10 values in the cached. When the 11th value is requested, then the next 10 values will be cached again.

CREATE SEQUENCE [dbo].[SequenceObject]
START WITH 1
INCREMENT BY 1
CACHE 10

the difference between sequence and identity in SQL Server

  1. The Identity Property of a column is available from SQL Server 2000 whereas the Sequence object is available from SQL Server 2012. Identity cannot be controlled by application code whereas Sequence can be controlled by application code.
  2. If any column is marked as Identity then we cannot insert data into this column directly. In that case, we must first turn off the Identity of the column whereas a Sequence object does not depend on the table so we can insert any value in the column.
  3. We cannot get the value of an Identity column before inserting a record whereas we can get the value of the next Sequence number for a Sequence Object before inserting a record.
  4. We can reseed an Identity property but we cannot change the step size whereas we can alter the Seed as well as the Step size of a Sequence object at any time.
  5. The sequence is used to generate a database-wide sequential number whereas the identity column is tied to a table.

数据类型(Data Type)

分类

默认数据类型(基本数据类型)

用户自定义的数据类型

数据类型分类的原因

合理地分配数据类型可以达到优化数据表

节省空间资源

系统自带数据类型

类型分类

精确数值数据类型(Exact Numeric Types)
浮点数数值数据类型(Approximate Numeric Types)
日期时间数据类型(Date and Time Types)
字符串数据类型(Character Strings)
Unicode字符串数据类型(Unicode Character Strings)
二进制字符串数据类型(Binary Strings)
其他数据类型(Other Data Types)

精确数值数据类型(Exact Numeric Types)

整数数值数据类型

BIT

占内存大小:1位
取值范围:0或1
注意:给BIT赋的值为非0值将取值为1
注意:BIT不是bool类型,不能自动进行逻辑判断

TINYINT

占内存大小:1字节(8位)
取值范围:0 ~ 255

SMALLINT

占内存大小:2字节(16位)
取值范围:-32768 ~ 32767

INT

占内存大小:4字节(32位)
取值范围:正负2亿
提示:可以给数值类型修饰:IDENTITY来表示标识列,系统会自动提供一个增量值
提示:每张表只能有一个IDENTITY列
提示:IDENTITY一般和PRIMARY KEY一起使用,即:PRIMARY KEY IDENTITY

BIGINT

占内存大小:8字节(64位)
范围:-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

DECIMAL(p,[s])

固定精度
DECIMAL中的p表示总位数,取值范围:1~38,默认为18
DECIMAL中的s表示小数位数,s是可选的,默认为0
范围:-10^38 +1 ~ 10^38 –1

NUMERIC(p,[s])

同DECIMAL

货币数据类型

MONEY

需在值前加货币符,如:$、¥
范围:-922,337,203,685,477.5808 ~ +922,337,203,685,477.5807
占用8个字节空间

SMALLMONEY

需在值前加货币符,如:$、¥
范围:-214,748.3648 ~ +214,748.3647
占用4个字节空间
注意:MONEY和SMALLMONEY精确到小数点后四位

浮点数数值数据类型(Approximate Numeric Types)

REAL

浮点数
REAL类型占4字节
精确到7位小数
范围:-3.40E + 38 ~ 3.40E + 38

FLOAT(n)

浮点数
FLOAT 中的n为存储FLOAT数值尾数的位数
FLOAT中的n取值范围:1~53,默认值53
FLOAT中的n取值在1~24时,实际上定义的是一个REAL类型,占4字节
FLOAT中的n取值在大于24时,占8位
范围:-1.79E + 308 ~ 1.79E + 308

日期时间数据类型(Date and Time Types)

DATE

日期
范围:0001-01-01 ~ 9999-12-31
格式:YYYY-MM-DD
占用3字节空间

TIME

时间
范围:00:00:00 ~ 23:59:59
格式:HH:MM:SS[.nnnnnnn]
占用5字节空间
可以定义TIME(小数位数)来定义高精度时间
N: 表示存储时间秒的小数位,取佳范围为 0-9999999
在SQL Server 2008引入

SMALLDATETIME

日期时间(比DATETIME范围更小)
格式:YYYY-MM-DD HH:MM:SS
范围:1900-1-1 ~ 2079-6-6
占用4字节空间

DATETIME

日期时间
格式:YYYY-MM-DD HH:MM:SS
范围:1753-1-1 ~ 9999-12-31
占用8字节空间

DATETIME2

日期时间(比DATETIME范围更大,精度更高)
格式:YYYY-MM-DD HH:MM:SS[.nnnnnnn]
范围:0001-01-01 ~ 9999-12-31
可以定义DATETINE2(小数位数)来定义高精度时间
占用 6~8 字节的存储空间
在SQL Server 2008引入

DATETIMEOFFSET

日期时间时区(DATETIME2的全部功能+时区功能)
格式:YYYY-MM-DD HH:MM:SS {+|- hh:ss}
范围:0001-01-01 ~ 9999-01-01
占用10字节空间
可以定义DATETINEOFFSET(小数位数)来定义高精度时间
DATETIMEOFFSET转为字符串后,需要35个字节
赋值值格式:’2019-11-18 16:59.1234567 +8:00′

字符串与文本数据类型(Character Strings)

CHAR(n)

Fixed-length non-Unicode character data with a maximum length of 8,000 characters
注意:CHAR(n)存储的长度是列长

VARCHAR(n)

Variable-length non-Unicode data with a maximum of 8,000 characters
注意:CHAR(n)/VARCHAR(n)中的n可取范围:1~8000,默认为1
注意:VARCHAR(n)存储的长度不是列长 而是数据的长度

VARCHAR(MAX)

Variable-length non-Unicode data with a maximum length of 231 characters
Introduced in SQL Server 2005

TEXT

Variable-length non-Unicode data with a maximum length of 2,147,483,647 characters
只能用于表,不可以用于参数和局部变量
注意:在未来版本中将删除TEXT、NTEXT类型、IMAGE类型
考虑使用NVARCHAR(MAX)、VARCHAR(MAX)、VARBINARY(MAX)代替

Unicode字符串数据类型(Unicode Character Strings)

NCHAR(N)

Fixed-length Unicode data with a maximum length of 4,000 characters.
注意:NCHAR/NVARCHAR/NTEXT字符串前需要加大写N,即:N’abc’

NVARCHAR(N)

Variable-length Unicode data with a maximum length of 4,000 characters

NVARCHAR(MAX)

Variable-length Unicode data with a maximum length of 230 characters
Introduced in SQL Server 2005

NTEXT

Variable-length Unicode data with a maximum length of 1,073,741,823 characters
只能用于表,不可以用于参数和局部变量
注意:在未来版本中将删除TEXT、NTEXT类型、IMAGE类型
考虑使用NVARCHAR(MAX)、VARCHAR(MAX)、VARBINARY(MAX)代替

二进制字符串数据类型

BINARY(n)

Fixed-length binary data with a maximum length of 8,000 bytes
固定长度二进制
最多255个字节
n范围1-8000
输入时需要在数据前面加前缀:0x
只能用于表,不可以用于参数和局部变量

VARBINARY(n|MAX)

Variable-length binary data with a maximum length of 8,000 bytes
可变长度二进制
最多255个字节
n范围1-8000
输入时需要在数据前面加前缀:0x
前缀:0x
只能用于表,不可以用于参数和局部变量

VARBINARY(MAX)

Variable-length binary data with a maximum length of 231 bytes
Introduced in SQL Server 2005

IMAGE

Variable-length binary data with a maximum length of 2,147,483,647 bytes
可变长度二进制
用于存储图片
只能用于表,不可以用于参数和局部变量
注意:IMAGE类型将在未来移除,使用VARBINARY(MAX)代替

其他数据类型

UNIQUEIDENTIFIER

Stores a globally unique identifier (GUID)
全局唯一标识符(GUID)
占用16字节的
一般作为主键使用

CURSOR

A reference to a cursor
游标类型

TABLE

Stores a result set for later processing
表格类型

ROWVERSION

列计数器
每一次对数据表的更改, SQL Server都会更新一个内部的序列数

TIMESTAMP

Stores a database-wide unique number that gets updated every time a row gets updated
注意:将会在后续版本中删除该类型

SQL_VARIANT

Stores values of various SQL Server-supported data types
except text, ntext, and timestamp
可存储多种数据类型(除TEXT、TIMESTAMP)

XML

Stores XML data
can store XML instances in a column or a variable
Introduced in SQL Server 2005
XML类型
实例大小不可以超过2GB

hierarchyid

A variable length, system data type used to represent position in a hierarchy
Introduced in SQL Server 2008

用户定义类型

说明

用户定义类型本质上是系统类型的别名

适用场景:
设置数据类型相同、长度相同、其他参数相同的类型,多个表可以统一类型
注意:无法删除系统正在使用的用户定义类型

定义自定义类型-使用SSMS

image

定义自定义类型-使用T-SQL

USE [panda_test];
EXEC sp_addtype @typename=[panda_type4], /* 用户自定义类型名 */
@phystype=int,      /* 对应的系统预定义类型 */
@nulltype=null; 	 /* 是否可以是null,可取值:NULL、NOT NULL */

实例:

EXEC sp_addtype 'panda_type6','INT','NOT NULL';

删除自定义类型-使用SSMS

image

删除自定义类型-使用T-SQL

EXEC sp_droptype [panda_type];

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/277916.html

(0)
上一篇 2022年7月30日
下一篇 2022年7月30日

相关推荐

发表回复

登录后才能评论