本篇主要讲述的是关系型数据库Sql Server,原因也很简单,因为大部分学校还在以sql server 为教学材料,不过没关系无论是sql
server 、mysql 还是oracle,只要是关系型数据库,概念都是相通的,语句也大差不差。 关系型数据库是一种采用关系模型来组织数据的数据库系统。它将数据存储在表格形式的结构中,通常称为表。这些表由行和列组成,每一行代表一条记录,每一列代表一个字段。关系型数据库的核心是表之间的关系,这些关系可以是一对一、一对多或多对多的形式。关系型数据库的设计允许用户通过查询语言(如SQL)来检索、更新和管理数据。
关系型数据库主要用于存储、检索和管理结构化数据。它们在企业级应用中非常流行,因为它们提供了数据一致性、完整性和并发控制的保障。关系型数据库可以处理复杂的事务处理,支持多种数据类型,并且可以高效地查询数据。此外,它们还提供了安全可靠的数据访问机制。关系型数据库广泛应用于银行、零售、电信、互联网等领域,例如亚马逊的AWS和谷歌的GCP都是基于关系型数据库构建的。
联系
数据抽象
数据库系统的三级模式结构
应用程序 => 外模式(用户级) => 模式(概念级) => 内模式(物理级) => 数据库
两层映象与数据独立性
三级模式结构与两层映像的优点
三层架构
界面表示层 => 业务处理层 => 数据访问层
结构类型
相关的术语
R ⋃ S = { t | t∈R ∧ t ∈S}
R − S = { t | t ∈R ∧ ┐ t ∈ S}
R(A) × S(B) = { t | ∃ (u ∈R) ∃(s ∈S)(t[A] = u[A] ∧ t[B] = s[B])}
σcon(R)={ t | t ∈ R ∧ F(con) }
∏A( R ) = { t[A] | t ∈ R }
代数优化、物理优化
基本步骤
需求分析 => 概念结构设计 => 逻辑结构设计 => 物理结构设计 => 数据库实施 => 数据库运行和维护
E-R图
函数依赖是指在关系模式中,一个或一组属性(称为决定因素)能够决定另一个或一组属性(称为依赖因素)的关系。函数依赖通常用 X→Y来表示,其中X 是决定因素,Y 是依赖因素。
关系范式是用来衡量关系模式是否规范化的标准。常见的关系范式包括:
Armstrong公理系统的基本规则包括:
Armstrong公理系统还包括一些推论规则,例如:
函数依赖集的等价
F+ = G+的充分必要条件是G+包含F,F+包含G
两个函数依赖集等价的定义是:如果它们的闭包相等,即一个函数依赖集能够推导出另一个函数依赖集中的所有函数依赖,反之亦然。这种等价关系允许我们在不同的函数依赖集中进行转换,而不会改变关系模式的本质特征。
函数依赖集的最小化
T-SQL(Transact-SQL)是Microsoft SQL Server中使用的扩展版本的SQL语言。在T-SQL中,命令和语句的书写通常不区分大小写,但是为了提高代码的可读性,建议使用统一的命名规范,例如使用大写字母表示关键字,小写字母表示变量和列名。
T-SQL中的运算符分为几类:
数据库定义
-- 通常情况下只需要以下语句
CREATE DATABASE MyDataBase;
基本表定义
-- 定义语法
CREATE TABLE table_name (
column1 datatype constraint1,
column2 datatype constraint2,
column3 datatype constraint3,
...
columnN datatype constraintN
);
-- 例如
CREATE TABLE Students (
StudentID INT PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
Age INT,
Gender CHAR(1),
Major VARCHAR(100)
);
数值数据类型
INT
:可以存储4个字节的整数值,范围从-2,147,483,648到2,147,483,647。SMALLINT
:可以存储2个字节的整数值,范围从-32,768到32,767。TINYINT
:可以存储1个字节的整数值,范围从0到255。BIGINT
:可以存储8个字节的整数值,范围从-263到263-1。DECIMAL
和 NUMERIC
:用于存储精确的小数值,可以指定精度和小数位数。FLOAT
:用于存储浮点数值,可以指定精度。MONEY
和 SMALLMONEY
:用于存储货币值,通常有四位小数。字符数据类型
CHAR
:存储固定长度的字符串,不足部分会用空格填充。VARCHAR
:存储可变长度的字符串,不需要额外的空格填充。NCHAR
和 NVARCHAR
:类似于 CHAR
和 VARCHAR
,但用于存储Unicode字符数据,NCHAR
是固定长度,NVARCHAR
是可变长度。日期和时间数据类型
DATETIME
:用于存储日期和时间值,范围从1753年1月1日到9999年12月31日。其他数据类型
TEXT
、NTEXT
、IMAGE
、VARBINARY(MAX)
和 XML
:用于存储大量文本或二进制数据。修改基本表
-- 新增新列
ALTER TABLE <表名>
ADD <列名> <数据类型> [<列级完整性约束>]
-- 修改原列
ALTER TABLE <表名>
ALTER COLUMN <列名> <新数据类型> [<列级别完整性约束>]
-- 删除列
ALTER TABLE <表名>
DROP COLUMN <列名>
-- 添加或删除完整性约束
ALTER TABLE <表名>
ADD CONSTRAINT <约束名> <约束定义>
ALTER TABLE <表名>
DROP CONSTRAINT <约束名>
索引定义
-- 创建
CREATE [UNIQUE][CLUSTERED | NONCLUSTERED] INDEX index_name
ON {table_name | view_name} [WITH [index_property [,....n]]]
UNIQUE
:表示创建的是唯一索引,不允许有重复的键值。CLUSTERED
:表示创建的是聚集索引。NONCLUSTERED
:表示创建的是非聚集索引。index_name
:索引的名称。table_name | view_name
:要在其上创建索引的表或视图的名称。index_property
:索引属性,用于定义索引的额外特性,如填充因子等。-- 删除
DROP INDEX table_name.index_name[,table_name.index_name]
-- 显示
EXEC sp_helpindex table_name
索引修改
-- 添加或删除索引列
-- 假设已经存在一个名为IX_WorkOrder_ProductID的非聚集索引
-- 现在想要添加一个新列Column3到索引中
CREATE NONCLUSTERED INDEX IX_WorkOrder_ProductID ON Production.WorkOrder(ProductID)
WITH (DROP_EXISTING = ON, FILLFACTOR = 80, PAD_INDEX = ON)
INCLUDE (Column3);
-- 修改索引属性
-- 修改名为AK_SalesOrderHeader_SalesOrderNumber的唯一索引的属性
ALTER INDEX AK_SalesOrderHeader_SalesOrderNumber ON Sales.SalesOrderHeader
SET (STATISTICS_NORECOMPUTE = ON, IGNORE_DUP_KEY = ON, ALLOW_PAGE_LOCKS = ON);
-- 重建或重组索引
-- 重建名为IX_WorkOrder_ProductID的非聚集索引
ALTER INDEX IX_WorkOrder_ProductID ON Production.WorkOrder REBUILD;
-- 重组名为IX_WorkOrder_ProductID的非聚集索引
ALTER INDEX IX_WorkOrder_ProductID ON Production.WorkOrder REORGANIZE;
视图定义
-- 创建
CREATE [OR ALTER] VIEW [schema_name.]view_name [(column [,...n])]
AS
SELECT_statement
[WITH <view_attribute> [,...n]]
其中
可以是以下选项之一:
ENCRYPTION
:加密视图定义,防止未授权的用户查看。SCHEMABINDING
:绑定视图,阻止对基表进行某些更改,除非先删除视图。VIEW_METADATA
:返回视图的元数据,而不是基表的元数据。修改视图
-- 假设我们有一个名为MyView的视图,我们想要修改它
ALTER VIEW MyView
AS
SELECT Column1, Column2
FROM MyTable
WHERE SomeCondition = True;
增
INSERT INTO 表名 (列名 [, 列名...])
VALUES (值 [, 值...])
删
DELETE FROM 表名
WHERE 条件
改
UPDATE 表名
SET 列名 = 新值 [, 列名 = 新值...]
WHERE 条件
查
SELECT [ALL | DISTINCT] 列名 [AS 别名]
FROM 表名
[WHERE 条件]
[GROUP BY 列名]
[HAVING 条件]
[ORDER BY 列 [ASC | DESC]]
简单查询
-- 查询所有列
SELECT * FROM TableName;
-- 查询特定列
SELECT Column1, Column2 FROM TableName;
-- 条件查询
SELECT * FROM TableName WHERE Condition;
-- 模糊查询
SELECT * FROM TableName WHERE Column LIKE Pattern;
-- 使用 % 作为通配符来匹配任意数量的字符
SELECT * FROM TableName WHERE Column LIKE 'Pattern%';
-- 排序查询
SELECT * FROM TableName ORDER BY Column ASC/DESC;
-- 统计查询
SELECT COUNT(*), SUM(Column), AVG(Column), MIN(Column), MAX(Column) FROM TableName;
-- 分组查询
SELECT Column, COUNT(*) FROM TableName GROUP BY Column HAVING Condition;
连接查询
-- 内连接
SELECT column_list
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name;
-- 外连接(OUTER JOIN)
-- 左外(LEFT OUTER JOIN),右外(RIGHT OUTER JOIN)
SELECT column_list
FROM table1
LEFT OUTER JOIN table2
ON table1.column_name = table2.column_name;
-- 全连接
SELECT column_list
FROM table1
FULL OUTER JOIN table2
ON table1.column_name = table2.column_name;
-- 交叉连接
SELECT column_list
FROM table1
CROSS JOIN table2;
-- 自连接
SELECT column_list
FROM table1
SELF JOIN table2;
嵌套查询
SELECT column_list
FROM outer_table
WHERE condition
AND (SELECT column_list
FROM inner_table
WHERE another_condition);
常见的嵌套查询类型
>
, <
, =
等,用于比较子查询返回的值。组合查询
-- 获取所有员工及其所在部门的信息
SELECT Employees.EmployeeID, Employees.Name, Departments.DepartmentName
FROM Employees
INNER JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID;
权限控制通常涉及以下几个关键概念:
授予权限
GRANT SELECT, INSERT ON ObjectName TO UserOrRoleName;
撤销权限
REVOKE SELECT ON ObjectName FROM UserOrRoleName;
查看权限
使用 EXEC sp_helprotect
或 EXEC sp_helprolemember
等系统存储过程来查看对象的权限信息或用户或角色的权限信息。
声明
DECLARE @局部变量名|@@全局变量 数据类型[ = 初值];
DECLARE @id INT;
赋值和查询
-- 赋值
-- 单值
SET @id = 1;
-- 多值
SELECT @name = name FROM students WHERE id = @id;
输出
PRINT @id; -- 打印输出
语句块
BEGIN
语句
...
END;
IF…ELSE条件语句
IF 条件表达式
语句
ELSE
语句
WHILE循环语句
WHILE 条件表达式
语句 | BREAK | CONTINUE
CASE多条件函数
CASE 输入表达式
WHEN 比较表达式 THEN 结果
WHEN 比较表达式 THEN 结果
WHEN 比较表达式 THEN 结果
ElSE
语句
END
WAITFOR语句
WAITFOR {DELAY | TIME}
GOTO语句
标签名称
语句组
GOTO 标签名称
RETURN语句
RETURN [<整数表达式>]
注释语句
/*多行注释*/
-- 单行注释
CREATE PROCEDURE MyProcedure
AS
BEGIN
-- 这里放置您的SQL语句
SELECT * FROM MyTable WHERE MyColumn = 'SomeValue';
END
GO
-- 创建带有参数的存储过程
CREATE PROCEDURE MyProcedureWithParam @MyParam INT
AS
BEGIN
-- 这里放置您的SQL语句,使用@MyParam作为参数
SELECT * FROM MyTable WHERE MyColumn = @MyParam;
END
GO
EXEC MyProcedure;
-- 或者
EXECUTE MyProcedure;
-- 执行带有参数的存储过程
EXEC MyProcedureWithParam @MyParam = 10;
-- 或者
EXECUTE MyProcedureWithParam 10;
DML 触发器是在执行 DML 操作(如 INSERT、UPDATE 或 DELETE)时自动触发的存储过程。它们用于在数据更改之前或之后执行某些操作,例如记录更改、强制业务规则或同步多个表之间的数据。
-- 创建 DML 触发器的示例
CREATE TRIGGER trg_AfterInsert ON YourTable
AFTER INSERT
AS
BEGIN
-- 在这里编写触发器逻辑
-- 例如,记录插入的数据到另一个表
INSERT INTO AuditLogTable (ColumnName, OperationType)
SELECT ColumnName, 'INSERT' FROM inserted
END;
DDL 触发器与 DML 触发器类似,但它们响应的是 DDL 事件,如 CREATE、ALTER 或 DROP 语句。DDL 触发器通常用于审计数据库架构的变化,或者防止对某些对象的修改或删除。
-- 创建 DDL 触发器的示例
CREATE TRIGGER trg_PreventTableDrop ON DATABASE
FOR DROP_TABLE
AS
BEGIN
-- 阻止 DROP TABLE 操作
RAISERROR ('不允许删除表。', 16, 1)
ROLLBACK
END;
-- 创建函数
CREATE FUNCTION [schema_name].function_name ([{ @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ NULL ] [ = default ] [ READONLY ] } [ , ...n ] ])
RETURNS return_data_type [ WITH <function_option> [ , ...n ] ]
[ AS ]
BEGIN
function_body
RETURN scalar_expression
END;
标量函数返回单个确定类型的值。它们可以接受零个或多个参数,并执行计算后返回结果。标量函数通常用于执行简单的数学运算、字符串处理或日期时间处理等操作。
-- 标量函数示例,它计算两个数的平均值
CREATE FUNCTION dbo.AverageNumbers (@num1 INT, @num2 INT)
RETURNS FLOAT
AS
BEGIN
DECLARE @result FLOAT
SET @result = (@num1 + @num2) / 2.0
RETURN @result
END
-- 使用这个函数的SQL语句如下
SELECT dbo.AverageNumbers(10, 20) AS AverageResult
表值函数则返回一个表格数据结构,即一组行和列。它们可以接受参数,并根据这些参数执行查询或计算,最终返回一个结果集。表值函数通常用于处理复杂的数据检索或聚合操作。
-- 表值函数,以下是一个简单的例子,它返回一个部门的所有员工信息
CREATE FUNCTION dbo.GetEmployeesByDepartment (@deptID INT)
RETURNS TABLE
AS
RETURN (
SELECT EmployeeID, Name, BirthDate
FROM Employees
WHERE DepartmentID = @deptID
)
-- 使用这个函数的SQL语句如下
SELECT * FROM dbo.GetEmployeesByDepartment(1)
游标是一种数据访问机制,它允许您在SQL Server数据库中逐行访问结果集。游标的实质是一种能从包括多条数据记录的结果集中每次取出一条记录的缓冲区。游标通常用于处理那些不适合用单一SQL语句一次性处理完毕的复杂逻辑。
在T-SQL中,使用游标通常涉及以下几个步骤:
DECLARE CURSOR
语句定义游标,并指定其属性,如方向(正向、反向、静态等)、类型(只读、可更新等)以及作用域(局部或全局)。OPEN
语句激活游标,此时游标会准备好开始遍历结果集。FETCH
语句从游标中检索数据。可以选择FETCH NEXT
来获取下一条记录,或者使用其他选项如FIRST
、LAST
、PRIOR
等来获取特定位置的记录。FETCH
之后,可以执行各种SQL语句来处理检索到的数据,例如更新、插入或删除操作。CLOSE
语句关闭游标,释放与之相关的资源。DEALLOCATE
语句彻底移除游标,释放内存空间。/*
我们首先声明了一个名为myCursor的游标,它用于检索employees表中属于Sales部门的员工记录。然后我们打开游标,并使用FETCH NEXT来获取第一条记录。接着,我们进入一个WHILE循环,直到@@FETCH_STATUS指示没有更多的记录可以获取为止。在循环体内,我们打印出每条记录的ID和姓名,并可以根据需要添加其他业务逻辑。最后,我们关闭并释放游标。
*/
DECLARE myCursor CURSOR FOR
SELECT id, name FROM employees
WHERE department = 'Sales';
OPEN myCursor;
FETCH NEXT FROM myCursor INTO @id, @name;
WHILE @@FETCH_STATUS = 0
BEGIN
-- 处理每条记录
PRINT 'ID: ' + CAST(@id AS VARCHAR) + ', Name: ' + @name;
-- 可以在这里添加更多的业务逻辑
FETCH NEXT FROM myCursor INTO @id, @name;
END;
CLOSE myCursor;
DEALLOCATE myCursor;
-- 创建新的服务器角色
CREATE SERVER ROLE server_role_name;
-- 向服务器角色添加成员
EXEC sp_addrolerolemember 'server_role_name', 'member_name';
-- 授予权限
GRANT permission_name TO server_role_name;
-- 撤销权限
REVOKE permission_name FROM server_role_name;
完整性控制类型,主要包括以下几种:
实现完整性控制的方法包括:
数据库事务管理是数据库管理系统中的一个重要组成部分,它确保了数据库操作的一致性和可靠性。事务是一系列对数据库的操作,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务管理必须满足以下四个基本特性,通常称为ACID属性:
-- 开始一个新的事务。在事务开始后,所有后续的数据库操作都会包含在这个事务中,直到事务被提交或回滚。
BEGIN TRANSACTION;
-- 这里放置一系列的数据库操作
COMMIT TRANSACTION;
-- 提交当前事务,使所有自事务开始以来所做的更改永久保存到数据库中。
BEGIN TRANSACTION;
-- 这里放置一系列的数据库操作
COMMIT TRANSACTION;
-- 撤销当前事务中所做的所有更改,将数据库恢复到事务开始前的状态。
BEGIN TRANSACTION;
-- 这里放置一系列的数据库操作
ROLLBACK TRANSACTION;
-- 创建一个保存点,允许在事务中回滚到该特定点,而不是整个事务。
BEGIN TRANSACTION;
-- 这里放置一系列的数据库操作
SAVE TRANSACTION savepoint_name;
-- 如果发生错误,可以回滚到savepoint_name
ROLLBACK TRANSACTION savepoint_name;
-- 回滚到指定的保存点,撤销该保存点之后的所有更改。
BEGIN TRANSACTION;
-- 这里放置一系列的数据库操作
SAVE TRANSACTION savepoint_name;
-- 如果发生错误,可以回滚到savepoint_name
ROLLBACK TRANSACTION TO savepoint_name;
并发控制是指在多个用户或进程同时访问和修改数据库时,确保数据的一致性和完整性。并发操作可能导致以下几种问题:
锁类型
有异议、意见等等欢迎评论区留言反馈!