还剩58页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
数据库训练课件实践与SQL提升欢迎参加我们的数据库SQL训练课程在这个为期60课时的课程中,我们将带领您从基础知识开始,逐步深入到SQL的高级应用技巧无论您是数据库初学者还是希望提升技能的从业人员,本课程都将为您提供系统而全面的学习体验课程概述课程目标本课程旨在帮助学员全面掌握SQL语言,能够独立设计、创建和管理关系型数据库,编写高效的SQL查询语句,并能针对实际业务需求进行数据库优化通过系统学习,您将具备专业的数据库开发和管理能力学习路径我们将从数据库基础知识开始,逐步学习SQL语句的编写,包括数据定义语言DDL、数据操作语言DML和数据查询语言DQL,最后通过两个实际项目巩固所学内容,并探讨SQL的高级应用预期成果数据库基础知识什么是数据库数据库管理系统()语言简介DBMS SQL数据库是按照数据结构组织、存储和管理数数据库管理系统是一种操纵和管理数据库的据的仓库它按照一定的数据模型组织数大型软件,用于建立、使用和维护数据库据,描述了数据的关系,并存储数据与数据常见的DBMS包括Oracle、SQL之间的联系数据库提供了数据的有效访问Server、MySQL和PostgreSQL等方式,使我们能够方便地管理和使用数据DBMS提供了数据定义、操作、控制和共享等功能简介SQL Server安装和配置管理工具SQL Server特性2012安装SQL Server需要考SQL Server2012是微虑硬件要求、操作系统兼软公司推出的一款关系型容性和网络配置在安装数据库管理系统,具有高过程中,需要选择实例配性能、高可用性和先进的置、服务账户设置和身份安全特性它引入了多项验证模式等安装完成新功能,如AlwaysOn后,还需进行初始配置,可用性组、列存储索引、包括内存分配、网络协议窗口函数扩展和序列对象启用和数据库文件位置设等,极大提升了数据处理置能力数据库设计基础规范化理论数据库规范化是通过一系列规则来减少数据冗余和提高数据完整性的过程常见的规范化级实体关系图()ERD别包括第一范式1NF、第二范式2NF和第三2实体关系图是数据库设计的重要工具,用范式3NF合理的规范化可以避免插入、删于表示实体类型、属性和实体间关系通除和更新异常,提高数据库的效率过ERD,我们可以清晰地描述业务需求,1确定数据模型的结构,为后续的数据库实设计原则现奠定基础绘制ERD时需注意实体的标良好的数据库设计应遵循以下原则满足业务识、关系的类型和基数等3需求、保持数据完整性、减少数据冗余、支持性能优化、考虑扩展性在设计过程中,应权衡规范化程度和查询性能,有时适当的反规范化也是必要的创建数据库语句数据库文件配置数据库属性设置1CREATE DATABASE23在SQL Server中,使用CREATE创建数据库时,可以指定数据文件和日志文在创建数据库时,可以设置多种属性,如排DATABASE语句创建新数据库基本语法件的物理位置、初始大小和增长设置例如序规则COLLATION、兼容性级别为CREATE DATABASECREATE DATABASETestDB ONCOMPATIBILITY_LEVEL、自动创建统database_name此语句会创建一个具PRIMARY NAME=TestDB_Data,计信息AUTO_CREATE_STATISTICS和有默认属性的数据库,包括主数据文件和事FILENAME=D:\Data\TestDB.mdf,自动更新统计信息务日志文件,以及各种默认配置参数SIZE=100MB,MAXSIZE=AUTO_UPDATE_STATISTICS等,以满UNLIMITED,FILEGROWTH=10%足特定的业务需求LOG ONNAME=TestDB_Log,FILENAME=D:\Data\TestDB.ldf,SIZE=50MB;表结构设计数据类型选择选择合适的数据类型对表性能至关重要常见的数据类型包括整数类型INT,BIGINT、字符串类型CHAR,VARCHAR,NVARCHAR、日期时间类型DATE,DATETIME、货币类型MONEY等应根据数据的实际需求和未来可能的扩展选择最适合的类型主键和外键主键是唯一标识表中每一行的列或列的组合,通常使用自增长的整数或自然键外键建立表之间的关系,维护参照完整性设计主外键时,应考虑查询性能、数据完整性和业务需求的平衡约束条件约束用于限制可存入表中的数据类型SQL Server支持的约束包括主键约束PRIMARY KEY、外键约束FOREIGN KEY、唯一约束UNIQUE、检查约束CHECK和默认约束DEFAULT等,它们共同保证数据的完整性和一致性创建表语句列定义CREATE TABLE使用CREATE TABLE语句创建新列定义包括列名、数据类型和可选表,基本语法为CREATE的约束例如employee_id INTTABLEtable_name column1NOT NULL,first_namedatatype,column2VARCHAR50NOT NULL,datatype,...;创建表时需指定每hire_date DATEDEFAULT列的名称和数据类型,还可以添加GETDATE定义列时应考虑数据约束条件和默认值等的性质、存储需求和访问模式表约束表约束可以在创建表时一起定义,也可以后续通过ALTER TABLE添加例如CONSTRAINT PK_Employee PRIMARY KEY employee_id,CONSTRAINT FK_Department FOREIGNKEY department_idREFERENCES Departmentid,CONSTRAINT CHK_Salary CHECKsalary0修改表结构语句1ALTER TABLEALTER TABLE用于修改现有表的结构,包括添加、修改、删除列和约束等操作基本语法为ALTER TABLEtable_name ACTION;表修改操作可能会影响到表中的数据和依赖对象,执行前应仔细规划添加列2使用ALTER TABLEtable_name ADDcolumn_name datatype[NULL|NOT NULL][CONSTRAINT]添加新列例如ALTER TABLEEmployee ADDemail VARCHAR100NULL;添加非空列时,若表中已有数据,必须提供默认值修改列3使用ALTER TABLEtable_name ALTERCOLUMN column_name datatype[NULL|NOT NULL]修改列的定义例如ALTER TABLEEmployee ALTERCOLUMNphone VARCHAR20NOT NULL;修改列类型时要确保与现有数据兼容删除列4使用ALTER TABLEtable_name DROP COLUMN column_name删除列例如ALTERTABLE EmployeeDROPCOLUMNfax;删除列是永久性操作,执行前应确保该列不被任何约束、索引或其他对象引用索引设计与创建索引类型语句CREATE INDEXSQL Server支持多种索引类型,包括使用CREATE INDEX语句创建索引,聚集索引一个表仅有一个、非聚集索基本语法为CREATE[UNIQUE]引一个表可有多个、唯一索引、复合[CLUSTERED|NONCLUSTERED]索引、全文索引和空间索引等每种索INDEX index_name ON引类型适用于不同的查询模式和数据特table_name column1征[ASC|DESC],...;例如CREATENONCLUSTERED INDEXIX_Employee_LastName ONEmployeelast_name;索引优化策略有效的索引策略应考虑索引常用的查询条件列;为外键列创建索引;避免索引频繁更新的列;考虑列的基数唯一值数量;定期重建或重组碎片化的索引;监控索引使用情况,删除未使用的索引数据操作插入数据语句基础INSERTINSERT语句用于向表中添加新行基本语法为INSERT INTOtable_name column1,column2,...VALUES value1,value2,...;如果为表的所有列提供值,可以省略列名列表例如INSERT INTOCustomerVALUES1,Zhang San,Beijing,13800138000;插入多行可以在一个INSERT语句中插入多行数据,提高插入效率语法为INSERTINTO table_name VALUESvalue1_1,value1_2,...,value2_1,value2_2,...,...;这种方式比多次执行单行插入更高效批量插入技巧对于大量数据插入,可以使用BULK INSERT或BCP批量复制程序工具,或者通过表值参数和临时表进行批处理这些方法可以显著提高大数据量的插入性能,减少日志空间的使用数据操作更新数据语句UPDATE1UPDATE语句用于修改表中的现有数据基本语法为UPDATE table_name SETcolumn1=value1,column2=value2,...WHERE condition;如果省略WHERE子句,表中所有行都将被更新条件更新UPDATE语句通常与WHERE子句一起使用,只更新满足特定条件的行例如2UPDATE EmployeeSET salary=salary*
1.1WHERE department_id=10;条件表达式可以使用AND、OR等逻辑运算符组合多个条件批量更新可以通过JOIN或子查询进行复杂的批量更新例如UPDATE e3SET e.salary=e.salary*
1.2FROM Employee e JOINDepartment d ON e.department_id=d.id WHEREd.name=研发部;这种方式可以基于关联表的数据进行更新数据操作删除数据语句条件DELETE WHERE1删除特定行数据,保留表结构指定要删除的数据行条件2DROP TABLE4TRUNCATE TABLE完全删除表结构及数据3快速删除表中所有行DELETE语句用于从表中删除符合条件的行,基本语法为DELETE FROM table_name WHERE condition;如果省略WHERE子句,将删除表中所有行DELETE会记录每行删除操作,因此对大表操作时效率较低TRUNCATE TABLE是一个DDL命令,它通过释放表中数据所占用的存储空间来快速删除所有行,语法为TRUNCATE TABLEtable_name;TRUNCATE比DELETE快,因为它不记录单独的行删除操作,但会重置标识列计数器DROP TABLE则完全删除表的结构及其数据、索引、触发器等,语法为DROP TABLEtable_name;执行此操作前必须谨慎,因为它会永久删除表及相关对象基本查询语句结构列选择1SELECT2SELECT语句是SQL中最常用的可以选择表中的特定列,如命令,用于从数据库中检索数SELECT first_name,据其基本结构包括SELECT last_name FROM列列表FROM表名WHERE条Employee;使用星号*可选件GROUP BY分组HAVING分择所有列SELECT*FROM组条件ORDER BY排序各子Employee;但在生产环境中,句有特定的执行顺序,理解这一应尽量避免使用*,而是明确列出点对编写高效查询非常重要需要的列,以提高查询效率列别名3可以为列指定别名,使结果集更易读别名可以用AS关键字指定,也可以直接在列名后用空格隔开例如SELECT employee_id ASID,first_name++last_name ASName FROM Employee;,使用别名可以简化复杂表达式的引用子句WHERE高级过滤组合多条件的复杂查询1逻辑运算符2AND、OR、NOT的组合应用比较运算符3=、、、=、=、基本比较WHERE子句用于筛选满足特定条件的行基本语法为SELECT columns FROM tableWHERE condition;条件表达式使用比较运算符,如等于=、大于、小于、大于等于=、小于等于=和不等于逻辑运算符用于组合多个条件AND要求所有条件都满足;OR要求至少一个条件满足;NOT用于反转条件的结果例如SELECT*FROM ProductWHEREcategory=电子产品AND price1000OR category=家具AND price5000;其他常用的过滤操作包括BETWEEN用于范围查询;IN用于列表匹配;LIKE用于模式匹配;IS NULL/IS NOT NULL用于检查空值熟练运用这些操作可以构建精确的查询条件,提高数据检索的精度排序和限制结果集子句子句ORDER BYTOPORDER BY子句用于对查询结果进行排序语法为SELECT TOP子句用于限制查询返回的行数,是SQL Server特有的语法基columns FROM table ORDER BY column1[ASC|DESC],本语法为SELECT TOPn columnsFROM table[WHEREcolumn2[ASC|DESC],...;默认为升序ASC,可以指定为降序condition][ORDER BYorder_list];其中n可以是具体数值或百DESC可以按多列排序,排序优先级从左到右依次降低分比例如SELECT employee_id,last_name,salary FROM例如SELECT TOP10PERCENT product_name,unit_priceEmployee ORDER BY salaryDESC,last_name ASC;此查FROM Product ORDER BY unit_price DESC;此查询返回价询首先按薪资降序排列,对于薪资相同的员工,再按姓氏字母升序排格最高的10%的产品使用TOP时通常与ORDER BY组合使用,以列确保返回的是有意义的前n行聚合函数函数和函数和函数COUNT SUMAVG MAXMINCOUNT函数用于计算行SUM函数计算指定列的所MAX函数返回指定列的最数COUNT*计算表中有值的总和,AVG函数计大值,MIN函数返回最小的所有行;算平均值,两者都忽略值,两者都忽略NULL值COUNTcolumn计算指NULL值例如这些函数可以用于数值、定列的非NULL值的数量;SELECT字符或日期类型的列例COUNTDISTINCT department_id,如SELECTcolumn计算指定列的不SUMsalary ASMAXhire_date AS同非NULL值的数量例TotalSalary,LatestHire,如SELECT COUNT*AVGsalary ASMINhire_date ASASTotalEmployees,AverageSalary FROMEarliestHire FROMCOUNTDISTINCTEmployee GROUP BY Employee;department_id ASdepartment_id;这些DepartmentCount函数只能用于数值类型的FROM Employee;列分组查询子句HAVING分组计算HAVING子句用于筛选分组后的结果,类似于子句GROUP BY通过GROUP BY,可以计算每个分组的聚合值WHERE过滤行,但HAVING过滤分组语法为GROUP BY子句用于将查询结果按一个或多个列例如SELECT department_id,COUNT*SELECT columnsFROM table[WHERE的值分组,通常与聚合函数一起使用语法为AS EmployeeCount,AVGsalary AScondition]GROUP BY columns HAVINGSELECT columns,AverageSalary FROM Employee GROUPgroup_condition;例如SELECTaggregate_functioncolumn FROMtable BY department_id;此查询计算每个部门的员department_id,AVGsalary FROM[WHERE condition]GROUP BY columns;工数量和平均薪资Employee GROUP BYdepartment_id分组列必须出现在SELECT列表中或被聚合函数使HAVING AVGsalary5000;用多表连接LEFT OUTERJOIN RIGHTOUTER JOINLEFT JOIN返回左表中的所有行,即使在RIGHT JOIN返回右表中的所有行,即使右表中没有匹配的行没有匹配的情况在左表中没有匹配的行没有匹配时,左INNER JOIN下,右表的列为NULL例如SELECT表的列为NULL例如SELECTFULL OUTERJOININNER JOIN返回两表中满足连接条件的c.customer_name,o.order_date e.name,p.project_name FROM行语法为SELECT columnsFROM FROMCustomer c LEFT JOINEmployee eRIGHT JOINProject pFULL JOIN返回左表和右表中的所有table1INNER JOINtable2ON Orderso ON c.customer_id=ON e.employee_id=行,不管是否有匹配没有匹配时,相应table
1.column=table
2.column;例o.customer_id;此查询返回所有客户p.manager_id;此查询返回所有项目表的列为NULL例如SELECT如SELECT e.employee_id,及其订单,包括没有订单的客户及其经理,包括没有指定经理的项目s.student_name,c.course_namee.name,d.department_name FROMStudent sFULL JOINFROMEmployee eINNER JOIN Enrollment e ON s.student_id=Department dON e.department_id e.student_id FULLJOIN Course c=d.department_id;ON e.course_id=c.course_id;2314子查询子查询基础非相关子查询子查询是嵌套在另一个查询中的非相关子查询独立于外部查询执行,其SELECT语句,可以出现在SELECT、结果用于外部查询的条件判断例如FROM、WHERE和HAVING子句中SELECT product_name FROM子查询必须放在括号内,可以返回单个Product WHEREcategory_id IN值、多个值或多行多列的结果集,根据SELECT category_id FROM返回类型决定如何使用Category WHEREcategory_nameLIKE电%;此类子查询执行一次,结果集传递给外部查询相关子查询相关子查询引用了外部查询中的列,因此必须为外部查询的每一行重新执行一次例如SELECT e
1.employee_id,e
1.salary FROMEmployee e1WHERE e
1.salary SELECTAVGe
2.salary FROMEmployeee2WHERE e
2.department_id=e
1.department_id;集合操作UNIONUNION操作符用于合并两个或多个SELECT语句的结果集,并删除重复行语法为SELECTcolumns FROMtable1UNION SELECT columnsFROMtable2;两个查询必须具有相同数量的列,且对应位置的列必须具有兼容的数据类型UNION ALLUNION ALL与UNION类似,但不删除重复行,因此速度更快例如SELECT product_id,product_name FROM Product UNION ALL SELECT product_id,product_nameFROM DiscontinuedProduct;当确定没有重复或需要保留重复时使用UNIONALL可提高性能INTERSECTINTERSECT返回两个查询结果集的交集,即同时存在于两个结果集中的行例如SELECTcustomer_id FROMActiveCustomer INTERSECTSELECT customer_id FROMPremiumCustomer;此查询返回同时是活跃客户和高级客户的客户IDEXCEPTEXCEPT返回第一个查询结果集中存在但第二个结果集中不存在的行例如SELECTemployee_id FROMEmployee EXCEPTSELECT employee_id FROMManager;此查询返回所有不是经理的员工ID视图创建视图1视图是基于SQL查询的虚拟表,可以像表一样被查询创建视图的语法为CREATE VIEWview_name AS SELECT columnsFROM tables[WHEREcondition];例如CREATEVIEW EmployeeSummaryAS SELECTe.employee_id,e.name,d.department_nameFROM Employeee JOINDepartmentdON e.department_id=d.department_id;视图的用途2视图可以用于简化复杂查询、限制数据访问行级和列级安全性、提供数据抽象层、保持数据独立性和支持向后兼容视图特别适合于经常使用的复杂查询,可以提高开发效率和代码可读性更新视图3在某些条件下,视图是可更新的可更新视图允许通过视图执行INSERT、UPDATE和DELETE操作,这些操作会影响基础表视图的可更新性取决于其查询定义,例如包含JOIN、DISTINCT、GROUP BY等的视图通常不可更新索引视图4索引视图也称为具体化视图是一种特殊的视图,其结果集被物理存储并建立索引通过使用WITHSCHEMABINDING选项创建,并在视图上创建唯一聚集索引索引视图可以显著提高复杂查询的性能,尤其是涉及聚合和连接的查询存储过程创建存储过程存储过程是一组预编译的SQL语句,可以接受参数、执行多个操作并返回结果创建语法为CREATE PROCEDUREprocedure_name[@parameter datatype[=default]][,...]AS BEGINSQL_statements END;存储过程编译后存储在数据库中,可以重复调用参数传递存储过程可以有输入参数、输出参数和返回值输入参数用于向过程传递值;输出参数用于从过程返回值;而RETURN语句通常用于返回执行状态例如CREATEPROCEDURE GetEmployeeByDepartment@dept_id INT,@emp_countINT OUTPUTAS BEGINSELECT@emp_count=COUNT*FROMEmployee WHERE department_id=@dept_id;SELECT*FROMEmployee WHEREdepartment_id=@dept_id;END;执行存储过程执行存储过程的语法为EXEC[CUTE]procedure_name[parameters];例如DECLARE@count INT;EXEC GetEmployeeByDepartment10,@count OUTPUT;PRINT员工数量:+CAST@count ASVARCHAR;存储过程可以从应用程序、触发器或其他存储过程中调用触发器创建触发器触发器触发器AFTER INSTEAD OF触发器是在表上执行INSERT、UPDATE或AFTER触发器在触发操作成功完成后执INSTEAD OF触发器用于替代触发操作的DELETE操作时自动执行的特殊存储过程行例如CREATE TRIGGER执行例如CREATE TRIGGER创建触发器的基本语法为CREATE trg_UpdateInventory ONtrg_ViewInsert ONEmployeeViewTRIGGER trigger_name ONOrderDetail AFTER INSERT ASINSTEAD OFINSERT AS BEGINtable_name[AFTER|INSTEAD OF]BEGIN UPDATEProduct SETINSERT INTOEmployee SELECT{INSERT|UPDATE|DELETE}AS BEGINstock_quantity=stock_quantity-name,department_id FROMSQL_statements END;触发器用于实i.quantity FROMProduct p JOIN insertedWHEREdepartment_id IN施复杂的业务规则和数据完整性约束inserted iON p.product_id=SELECT department_id FROMi.product_id END;AFTER触发器不能Department END;INSTEADOF触发用于视图器常用于使复杂视图可更新事务管理持久性Durability事务完成后的持久保存1隔离性Isolation2事务间相互独立执行一致性Consistency3保持数据库一致状态原子性Atomicity4事务操作全部完成或全部取消事务是一组作为单个逻辑工作单元执行的SQL语句,要么全部执行成功,要么全部回滚事务必须满足ACID特性原子性、一致性、隔离性和持久性,以确保数据库操作的可靠性在SQL Server中,事务的基本语法为BEGIN TRANSACTION;SQL_statements;[COMMIT|ROLLBACK]TRANSACTION;例如BEGIN TRAN;UPDATE AccountSETbalance=balance-1000WHERE account_id=1;UPDATE AccountSET balance=balance+1000WHERE account_id=2;IF@@ERROR=0COMMIT TRANELSEROLLBACK TRAN;SQL Server支持不同的事务隔离级别READ UNCOMMITTED、READ COMMITTED默认、REPEATABLE READ和SERIALIZABLE,每个级别提供不同程度的数据一致性和并发性根据应用需求选择合适的隔离级别可以平衡数据完整性和系统性能错误处理块错误函数1TRY...CATCH2SQL Server提供TRY...CATCH结构在CATCH块中,可以使用多个函数获进行错误处理,类似于其他编程语言取错误信息ERROR_NUMBER返语法为BEGIN TRY回错误代码;ERROR_MESSAGESQL_statements_that_might_ca返回错误消息;ERROR_SEVERITYuse_error ENDTRY BEGIN返回严重性级别;ERROR_STATECATCH返回错误状态;ERROR_LINE返回error_handling_statements发生错误的行号;END CATCH;当TRY块中发生错误ERROR_PROCEDURE返回发生错时,控制转到CATCH块,可以执行错误的存储过程或触发器的名称误处理逻辑和3RAISERROR THROWRAISERROR用于手动生成错误消息和设置错误状态,语法为RAISERRORerror_message,severity,state[,arguments];SQL Server2012引入了THROW语句,它更简单THROW[error_number,message,state];THROW比RAISERROR更简洁,且自动重新抛出原始错误用户定义函数标量函数内联表值函数多语句表值函数标量函数返回单个值,可以在内联表值函数返回表,定义为多语句表值函数返回表,可以SELECT语句或WHERE子句单个SELECT语句语法为包含多个SQL语句和临时表中使用创建语法为CREATE FUNCTION语法为CREATECREATE FUNCTIONfunction_name@parame FUNCTIONfunction_name@parame ter datatype RETURNSfunction_name@parameter datatypeRETURNS TABLE AS RETURNterdatatypeRETURNSreturn_datatype ASSELECT_statement;例@table_variable TABLEBEGINfunction_body如CREATE FUNCTION column_definitions ASRETURNvalue END;例如dbo.GetEmployeesByDep BEGINSQL_statementsCREATE FUNCTIONartment@dept_id INTRETURN END;这些函数通dbo.GetAge@birthdate RETURNSTABLEAS常比内联表值函数性能稍低,DATE RETURNSINT ASRETURN SELECT*FROM但可以实现更复杂的逻辑BEGIN RETURNEmployee WHEREDATEDIFFYEAR,department_id=@birthdate,GETDATE@dept_id;END;数据库安全用户和角色管理权限分配SQL Server安全模型基于主体用户、使用GRANT语句为用户或角色授予权限角色和应用程序和可安全对象数据库、GRANT permissionON objectTO表、视图等创建用户的语法为principal;例如GRANT SELECT,CREATE USERuser_name FORINSERT ON dbo.Employee TOLOGINlogin_name;角色用于简化HR_Staff;可以使用DENY明确拒绝权权限管理,可以创建数据库角色限,使用REVOKE撤销之前的GRANTCREATE ROLErole_name或DENY权限可以是对象级别的如AUTHORIZATION owner_name;SELECT、INSERT,也可以是数据库级别的如CREATE TABLE行级安全性SQL Server支持行级安全性RLS,允许基于用户特征如部门、角色限制数据访问实现RLS需要创建安全谓词函数和安全策略CREATE SECURITY POLICYpolicy_name ADDFILTER PREDICATEpredicate_functionargs ONtable_name这种方式可以在应用程序外部实施细粒度的访问控制性能优化基础索引优化查询计划分析创建和维护合适的索引2理解执行计划的关键部分1查询重写改进SQL语句结构和逻辑35资源配置统计信息更新合理分配系统资源4保持最新的数据分布统计查询性能优化是数据库管理中的核心任务使用STATISTICS IO和STATISTICS TIME命令可以查看查询的I/O成本和执行时间使用图形执行计划可视化查询步骤,识别潜在瓶颈,如表扫描、排序操作和昂贵的连接索引是提高查询性能的主要手段应为WHERE子句、JOIN条件和ORDER BY子句中的列创建适当的索引但索引也会增加写操作的开销和存储空间,需要权衡利弊定期检查索引使用情况和碎片化程度,适时进行重组或重建查询优化的其他策略包括避免在WHERE子句中对列使用函数;合理使用临时表和表变量;减少不必要的排序和分组;优化JOIN顺序;利用查询提示在特定场景下指导优化器性能优化是一个迭代过程,需要持续监控和调整实践项目商品管理系统需求分析商品管理系统需要管理商品信息、分类、供应商、库存和销售记录系统应支持商品的增删改查、库存变动跟踪、订单处理和基本的销售统计分析用户包括管理员、采购人员和销售人员,各角色有不同的权限需求数据库设计根据需求,设计以下主要实体Product商品、Category分类、Supplier供应商、Inventory库存、Order订单和OrderDetail订单明细实体间的关系包括一个分类有多个商品;一个供应商提供多个商品;一个订单包含多个商品;商品和库存之间是一对一关系系统功能基于这个数据库设计,系统将实现以下功能商品信息管理、分类管理、供应商管理、库存管理、订单处理和销售统计同时,我们将创建视图简化报表生成,使用存储过程处理复杂业务逻辑,通过触发器自动更新库存和销售统计商品管理系统表结构设计商品表Product product_id主键、product_name、category_id外键、supplier_id外键、unit_price、description、discontinued、create_date分类表Category category_id主键、category_name、description供应商表Supplier supplier_id主键、supplier_name、contact_name、phone、email、address库存表Inventory inventory_id主键、product_id外键、quantity、last_update、reorder_level订单表Order order_id主键、customer_id、employee_id、order_date、required_date、shipped_date、status订单明细表OrderDetail order_id主键/外键、product_id主键/外键、quantity、unit_price、discount商品管理系统创建表创建数据库基本表创建关系表创建首先创建商品管理系统数据库CREATE创建Category表CREATE TABLE创建Product表CREATE TABLEDATABASEProductManagement;Category category_id INTPRIMARY Product product_id INTPRIMARYUSE ProductManagement;然后按照KEY IDENTITY,category_name KEY IDENTITY,product_name依赖关系顺序创建表,先创建不依赖其他表NVARCHAR50NOT NULL,NVARCHAR100NOT NULL,的基本表Category、Supplier,再创建description NVARCHAR200;创建category_id INTREFERENCES依赖这些表的表Product,最后创建依赖Supplier表CREATE TABLESupplier Categorycategory_id,supplier_idProduct的表Inventory、Order、supplier_id INTPRIMARY KEYINT REFERENCESOrderDetailIDENTITY,supplier_name Suppliersupplier_id,unit_priceNVARCHAR100NOT NULL,MONEY NOT NULL,descriptioncontact_name NVARCHAR50,phone NVARCHAR500,discontinued BITVARCHAR20,email VARCHAR100,DEFAULT0,create_date DATEaddress NVARCHAR200;DEFAULT GETDATE;商品管理系统插入示例数据分类数据供应商数据INSERT INTOCategory VALUESINSERT INTOSupplier VALUES电子产品,各类电子设备和配件,科技有限公司,张三,13800138001,办公用品,办公所需的各种耗材和设备zhangsan@tech.com,北京市海,家居用品,家庭生活使用的各类产淀区,办公用品批发商,李四,品;这些基础数据为后续的商品分类13800138002,lisi@office.com,提供支持,可以根据实际需求扩展更多上海市浦东新区;供应商信息对于采分类购和联系跟踪非常重要商品数据INSERT INTOProduct VALUES笔记本电脑,1,1,
5999.00,高性能商务笔记本,0,GETDATE,打印纸A4,2,2,
45.50,标准A4打印纸,500张/包,0,GETDATE;商品数据是系统的核心,需要与分类和供应商建立正确的关联商品管理系统基本查询商品列表查询1基本商品信息查询SELECT product_id,product_name,unit_price,discontinued FROMProduct ORDER BY带分类的商品查询product_name;此查询返回所有商品的基础信息,按商品名称2排序,便于用户浏览商品目录SELECT p.product_id,p.product_name,c.category_name,p.unit_price FROMProduct p JOIN Category c ONp.category_id=c.category_id WHEREp.discontinued=0带供应商的商品查询3ORDER BY c.category_name,p.product_name;此查询显示未下架商品及其所属分类,先按分类再按商品名排序SELECT p.product_id,p.product_name,s.supplier_name,p.unit_price FROMProduct p JOIN Supplier s ONp.supplier_id=s.supplier_id ORDERBY s.supplier_name,库存预警查询p.unit_price DESC;此查询显示商品及其供应商信息,按供应商4和价格排序,便于采购分析和供应商管理SELECTp.product_name,i.quantity,i.reorder_levelFROM Product pJOINInventory iON p.product_id=i.product_id WHEREi.quantity=i.reorder_level ORDERBYi.quantity;此查询显示库存低于预警水平的商品,帮助及时补货商品管理系统复杂查询分组统计查询子查询示例复杂查询JOIN按分类统计商品数量和平均价格SELECT查找高于平均价格的商品SELECT查询每个商品的销售量和销售额SELECTc.category_name,product_name,unit_price FROMp.product_name,SUMod.quantityCOUNTp.product_id ASProduct WHEREunit_priceAS TotalQuantity,SUMod.quantity*ProductCount,AVGp.unit_price ASSELECT AVGunit_price FROMod.unit_price*1-od.discount ASAvgPriceFROM Category cLEFTProductORDERBYunit_price;查找TotalAmount FROMProduct pLEFTJOIN Productp ON c.category_id=最近30天内有销售的商品SELECT JOINOrderDetail odONp.category_id GROUPBY DISTINCTp.product_name FROMp.product_id=od.product_id LEFTc.category_name ORDERBY Productp WHEREp.product_id INJOIN[Order]o ON od.order_id=ProductCount DESC;此查询帮助了解SELECT od.product_id FROMo.order_id WHEREo.order_date各分类的商品分布情况OrderDetail odJOIN[Order]o ONBETWEEN2023-01-01AND2023-12-od.order_id=o.order_id WHERE31GROUPBY p.product_id,o.order_date=DATEADDday,-30,p.product_name ORDERBYGETDATE;TotalAmount DESC;商品管理系统存储过程创建销售报表存储过程创建库存更新存储过程CREATE PROCEDUREGenerateSalesReport创建订单处理存储过程CREATE PROCEDUREUpdateInventory@start_date DATE,@end_date DATEASCREATE PROCEDUREProcessOrder@product_id INT,@quantity_change INTAS BEGINSELECT c.category_name,@customer_id INT,@employee_id INT,BEGIN DECLARE@current_quantity INT;p.product_name,SUMod.quantity AS@order_items OrderItemTypeREADONLY SELECT@current_quantity=quantity TotalQuantity,SUMod.quantity*AS BEGINTRANSACTION;DECLARE FROMInventory WHEREproduct_id=od.unit_price*1-od.discount AS@order_id INT;INSERT INTO[Order]@product_id;IF@current_quantity+TotalAmount FROMOrderDetail odJOINcustomer_id,employee_id,order_date@quantity_change0THROW50000,库存ProductpONod.product_id=p.product_idVALUES@customer_id,@employee_id,不足,无法完成操作,1;UPDATE Inventory SET JOINCategory c ON p.category_id=GETDATE;SET@order_id=quantity=quantity+@quantity_change,c.category_id JOIN[Order]o ONod.order_idSCOPE_IDENTITY;INSERT INTOlast_update=GETDATE WHERE=o.order_id WHEREo.order_date BETWEENOrderDetailSELECT@order_id,product_id,product_id=@product_id;END;@start_date AND@end_date GROUPBYquantity,unit_price,discount FROMc.category_name,p.product_name ORDER@order_items;UPDATE InventorySET BY c.category_name,TotalAmount DESC;quantity=i.quantity-oi.quantity FROMEND;Inventory iJOIN@order_items oiONi.product_id=oi.product_id;COMMITTRANSACTION;商品管理系统触发器订单明细插入触发器商品价格更新触发器库存预警触发器CREATE TRIGGER CREATE TRIGGERCREATE TRIGGERtrg_OrderDetail_Insert ONtrg_Product_PriceUpdate ONtrg_Inventory_Check ONInventoryOrderDetail AFTERINSERT AS BEGIN ProductAFTER UPDATE AS BEGIN IF AFTER UPDATEAS BEGIN DECLAREUPDATEInventorySETquantity=UPDATEunit_price INSERT INTO@low_stock TABLEproduct_id INT,i.quantity-ins.quantity FROMPriceHistory product_id,old_price,product_name NVARCHAR100,Inventory iJOIN inserted ins ONnew_price,change_date SELECTquantity INT,reorder_level INT;i.product_id=ins.product_id;i.product_id,d.unit_price,i.unit_price,INSERT INTO@low_stock SELECTUPDATEProduct SETunit_price=GETDATE FROMinserted iJOIN i.product_id,p.product_name,unit_price WHEREproduct_id INdeleted dON i.product_id=i.quantity,i.reorder_level FROMSELECTproduct_id FROMinserted;d.product_id WHEREi.unit_priceinserted iJOIN Productp ONEND;d.unit_price;END;i.product_id=p.product_id WHERE此触发器在订单明细插入后自动减少相应商i.quantity=i.reorder_level;END;品的库存数量,确保库存记录与销售情况同此触发器在商品价格更新时记录价格变更历步,防止超卖史,便于分析价格趋势和审计此触发器在库存更新后检查是否有商品库存低于预警水平,如有则生成预警信息商品管理系统视图商品目录视图库存状态视图销售汇总视图CREATE VIEWProductCatalog ASSELECT CREATE VIEW InventoryStatusASSELECTCREATE VIEWSalesSummary ASSELECTp.product_id,p.product_name,c.category_name,p.product_id,p.product_name,i.quantity,p.product_id,p.product_name,c.category_name,p.unit_price,p.description,s.supplier_name i.reorder_level,CASE WHEN i.quantity=COUNTDISTINCT od.order_id ASorder_count,FROMProductpJOINCategory c ON i.reorder_level THEN需要补货WHENi.quantity=SUMod.quantity AStotal_quantity,p.category_id=c.category_id JOINSuppliersON i.reorder_level*2THEN库存偏低ELSE库存充足SUMod.quantity*od.unit_price*1-od.discountp.supplier_id=s.supplier_id WHEREEND ASstock_status,i.last_update FROMProduct AStotal_amount FROMProductpLEFT JOINp.discontinued=0;此视图提供一个综合的商品目录,pJOINInventory iON p.product_id=i.product_id;OrderDetail odON p.product_id=od.product_id包含分类和供应商信息,便于展示给用户浏览此视图显示商品库存状态,帮助库存管理LEFT JOIN[Order]o ONod.order_id=o.order_idLEFT JOINCategoryc ON p.category_id=c.category_id GROUPBYp.product_id,p.product_name,c.category_name;此视图汇总各商品的销售情况商品管理系统权限管理系统管理员1完全控制系统的所有功能部门经理2查看报表和批准重要操作采购人员3管理商品和供应商信息销售人员4处理订单和查询库存首先,创建数据库角色CREATE ROLESalesStaff;CREATE ROLEPurchaseStaff;CREATE ROLEDepartmentManager;CREATE ROLESystemAdmin;然后,为每个角色分配适当的权限,符合最小权限原则销售人员权限GRANT SELECTON ProductCatalogTO SalesStaff;GRANT SELECTON InventoryStatusTO SalesStaff;GRANT EXECUTEON ProcessOrderTOSalesStaff;采购人员权限GRANT SELECT,INSERT,UPDATE ONProduct TOPurchaseStaff;GRANT SELECT,INSERT,UPDATE ONSupplier TOPurchaseStaff;GRANTEXECUTE ONUpdateInventory TOPurchaseStaff;部门经理权限GRANT SELECTON SalesSummaryTO DepartmentManager;GRANT EXECUTEON GenerateSalesReportTO DepartmentManager;系统管理员权限GRANT CONTROLON DATABASE::ProductManagement TOSystemAdmin;最后,将用户添加到适当的角色ALTER ROLESalesStaff ADDMEMBER[domain\user1];实践项目学生成绩管理系统需求分析数据库设计系统功能学生成绩管理系统需要管理学生信息、课程根据需求,设计以下主要实体Student学基于数据库设计,系统将实现以下功能学信息、教师信息和成绩记录系统应支持学生、Teacher教师、Course课程、生信息管理、教师信息管理、课程管理、选生选课、教师登记成绩、成绩查询和统计分Class班级、Enrollment选课和课管理、成绩录入和查询、统计分析报表析等功能用户包括管理员、教师和学生,Grade成绩实体间的关系包括学生属于同时,我们将创建视图简化报表生成,使用每类用户具有不同的权限和操作需求班级;教师教授课程;学生选修课程;每个存储过程处理复杂业务逻辑,通过触发器确选课记录对应一个成绩记录保数据一致性学生成绩系统表结构设计学生表Student student_id主键、student_name、gender、birth_date、class_id外键、address、phone教师表Teacher teacher_id主键、teacher_name、gender、birth_date、specialty、phone课程表Course course_id主键、course_name、credit、teacher_id外键、description班级表Class class_id主键、class_name、grade_year、major选课表Enrollment enrollment_id主键、student_id外键、course_id外键、enrollment_date、status成绩表Grade grade_id主键、enrollment_id外键、score、grade_point、submit_date、comment学生成绩系统创建表创建数据库创建基础表1创建学生管理系统数据库创建Class、Teacher表2创建业务表创建关联表4创建Enrollment、Grade表3创建Student、Course表首先创建学生成绩管理系统数据库CREATE DATABASEStudentGradeManagement;USE StudentGradeManagement;然后按照依赖关系顺序创建表,先创建不依赖其他表的基本表Class、Teacher,再创建依赖这些表的表Student、Course,最后创建选课和成绩表创建Class表CREATE TABLEClass class_id INTPRIMARY KEYIDENTITY,class_name NVARCHAR50NOT NULL,grade_year INTNOT NULL,majorNVARCHAR50;创建Teacher表CREATE TABLETeacher teacher_id INTPRIMARY KEYIDENTITY,teacher_name NVARCHAR50NOT NULL,gender CHAR1CHECK genderIN M,F,birth_date DATE,specialty NVARCHAR100,phone VARCHAR20;创建Student表CREATE TABLEStudent student_id INTPRIMARYKEYIDENTITY,student_name NVARCHAR50NOT NULL,gender CHAR1CHECK genderIN M,F,birth_date DATE,class_id INTREFERENCES Classclass_id,addressNVARCHAR200,phone VARCHAR20;创建Course表CREATE TABLECourse course_idINT PRIMARYKEYIDENTITY,course_name NVARCHAR100NOTNULL,credit DECIMAL3,1NOTNULL,teacher_id INTREFERENCES Teacherteacher_id,description NVARCHAR500;学生成绩系统插入示例数据班级数据1INSERT INTOClass VALUES计算机科学2021级1班,2021,计算机科学与技术,软件工程2021级1班,2021,软件工程,数据科学2022级1班,2022,数据科学与大数据技术;这些基础数据为后续的学生分班提供支持,可以根据实际需求扩展更多班级教师数据2INSERT INTOTeacher VALUES王教授,M,1970-05-15,数据库系统,13900139001,李教授,F,1975-08-22,人工智能,13900139002,张教授,M,1968-12-10,软件工程,13900139003;教师信息对于课程安排和成绩管理非常重要学生数据3INSERT INTOStudent VALUES张三,M,2000-01-15,1,北京市海淀区,13800138001,李四,F,2001-03-22,1,上海市浦东新区,13800138002,王五,M,2000-07-30,2,广州市天河区,13800138003;学生数据是系统的核心,需要与班级建立正确的关联课程数据4INSERT INTOCourse VALUES数据库原理,
4.0,1,关系数据库基础知识和SQL语言,高级程序设计,
3.5,3,C++程序设计和面向对象编程,人工智能导论,
3.0,2,人工智能基础理论和应用;课程数据需要与教师建立正确的关联,指定授课教师学生成绩系统基本查询学生信息查询课程信息查询基本学生信息查询SELECT student_id,student_name,带教师的课程查询SELECT c.course_id,c.course_name,gender,birth_date,phone FROMStudent ORDERBYc.credit,t.teacher_name FROMCourse cJOIN Teachertstudent_name;此查询返回所有学生的基础信息,按学生姓名排ONc.teacher_id=t.teacher_id ORDERBY序,便于用户浏览学生列表c.course_name;此查询显示课程及其授课教师信息,按课程名称排序,便于课程管理带班级的学生查询SELECT s.student_id,s.student_name,c.class_name,s.gender FROMStudent sJOIN Class c ON学生选课情况查询SELECT s.student_name,s.class_id=c.class_id ORDERBYc.class_name,c.course_name,e.enrollment_date FROMStudent sJOINs.student_name;此查询显示学生及其所属班级,按班级和姓名Enrollment e ON s.student_id=e.student_id JOIN Course排序cON e.course_id=c.course_id WHEREe.status=ActiveORDER BY s.student_name,c.course_name;此查询显示当前有效的选课记录学生成绩系统复杂查询成绩统计查询按课程统计成绩SELECTc.course_name,COUNTg.grade_id ASStudentCount,AVGg.score ASAvgScore,MAXg.score ASMaxScore,MINg.score ASMinScore FROMCourse cLEFTJOIN Enrollment e ONc.course_id=e.course_id LEFTJOIN Grade g ON e.enrollment_id=g.enrollment_id GROUPBYc.course_id,c.course_name ORDERBY AvgScoreDESC;此查询计算每门课程的成绩统计信息学分统计查询计算学生获得的总学分SELECT s.student_name,SUMc.credit ASTotalCredits FROMStudent sJOIN Enrollment e ON s.student_id=e.student_id JOINCourse cON e.course_id=c.course_id JOIN Grade g ON e.enrollment_id=g.enrollment_id WHEREg.score=60GROUPBY s.student_id,s.student_name ORDERBY TotalCreditsDESC;此查询计算每个学生已通过课程的总学分排名查询计算学生总成绩排名SELECT s.student_name,AVGg.score ASAvgScore,RANK OVER ORDERBYAVGg.score DESCAS RankingFROMStudent sJOIN Enrollmente ON s.student_id=e.student_id JOINGrade gON e.enrollment_id=g.enrollment_id GROUPBY s.student_id,s.student_name;此查询使用窗口函数计算学生的平均成绩排名不及格学生查询查询有不及格课程的学生SELECT s.student_name,c.course_name,g.score FROMStudent sJOIN EnrollmenteON s.student_id=e.student_id JOINCourse cON e.course_id=c.course_id JOINGrade gON e.enrollment_id=g.enrollment_id WHEREg.score60ORDERBY s.student_name,c.course_name;此查询帮助找出需要补考的学生学生成绩系统存储过程选课存储过程1处理学生选课与退课操作成绩录入存储过程2录入和更新学生课程成绩成绩单生成存储过程3生成学生成绩单报表创建选课处理存储过程CREATE PROCEDUREEnrollCourse@student_id INT,@course_id INTAS BEGINIF EXISTSSELECT1FROM Enrollment WHERE student_id=@student_id ANDcourse_id=@course_id ANDstatus=Active THROW50000,该学生已选择此课程,1;INSERT INTOEnrollment student_id,course_id,enrollment_date,status VALUES@student_id,@course_id,GETDATE,Active;END;创建成绩录入存储过程CREATE PROCEDURERecordGrade@enrollment_id INT,@score DECIMAL5,2ASBEGINIF@score0OR@score100THROW50001,成绩必须在0-100之间,1;DECLARE@grade_point DECIMAL3,2;SET@grade_point=CASE WHEN@score=90THEN
4.0WHEN@score=80THEN
3.0WHEN@score=70THEN
2.0WHEN@score=60THEN
1.0ELSE0END;IF EXISTSSELECT1FROM GradeWHERE enrollment_id=@enrollment_id UPDATEGrade SETscore=@score,grade_point=@grade_point,submit_date=GETDATE WHEREenrollment_id=@enrollment_id;ELSE INSERTINTO Gradeenrollment_id,score,grade_point,submit_date VALUES@enrollment_id,@score,@grade_point,GETDATE;END;创建成绩单生成存储过程CREATE PROCEDUREGenerateTranscript@student_id INTASBEGINSELECT s.student_name,c.class_name,co.course_name,co.credit,g.score,g.grade_point FROMStudent sJOIN ClasscONs.class_id=c.class_id JOINEnrollmenteONs.student_id=e.student_id JOINCourse co ON e.course_id=co.course_id LEFTJOINGrade gONe.enrollment_id=g.enrollment_id WHEREs.student_id=@student_id ORDERBY co.course_name;SELECT s.student_name,AVGg.score ASAvgScore,SUMco.credit ASTotalCredits,SUMco.credit*g.grade_point/SUMco.credit ASGPA FROMStudent sJOINEnrollmenteONs.student_id=e.student_id JOINCourse coONe.course_id=co.course_id JOINGradegONe.enrollment_id=g.enrollment_id WHEREs.student_id=@student_id GROUPBYs.student_id,s.student_name;END;学生成绩系统触发器成绩录入触发器选课冲突检查触发器成绩更新日志触发器123CREATE TRIGGER trg_Grade_Insert CREATETRIGGERCREATETRIGGERtrg_Grade_UpdateON GradeAFTERINSERT ASBEGINtrg_Enrollment_Insert ONON GradeAFTERUPDATEAS BEGINDECLARE@enrollment_id INT,Enrollment AFTERINSERTASBEGINIFUPDATEscore INSERTINTO@score DECIMAL5,2;SELECT DECLARE@student_id INT,GradeUpdateLog enrollment_id,@enrollment_id=enrollment_id,@course_id INT;SELECT old_score,new_score,update_date@score=score FROMinserted;IF@student_id=student_id,SELECT d.enrollment_id,d.score,@score0OR@score100BEGIN@course_id=course_id FROMi.score,GETDATE FROMdeleted dROLLBACKTRANSACTION;THROW inserted;IF SELECTCOUNT*FROM JOINinsertediONd.grade_id=50000,成绩必须在0-100之间,1;END;EnrollmentWHEREstudent_id=i.grade_id WHEREd.scorei.score;END;@student_id ANDcourse_id=END;@course_id ANDstatus=Active1此触发器在成绩录入后验证成绩范围,确保此触发器记录成绩变更历史,便于审计和问BEGIN ROLLBACKTRANSACTION;数据有效性如果成绩超出有效范围0-题追踪每次成绩更新时,都会记录旧成绩、THROW50001,该学生已经选择了此课100,将回滚事务并抛出错误新成绩和更新时间程,1;END;END;此触发器检查学生是否重复选择同一课程,防止数据重复如果发现重复选课,将回滚事务并抛出错误学生成绩系统视图创建学生信息视图CREATE VIEWStudentInfo ASSELECT s.student_id,s.student_name,s.gender,s.birth_date,c.class_name,c.major FROMStudent sJOIN ClasscONs.class_id=c.class_id;此视图提供学生的基本信息和班级信息,便于查询创建课程选修视图CREATE VIEWCourseEnrollment ASSELECTc.course_id,c.course_name,c.credit,t.teacher_name,COUNTe.enrollment_id ASstudent_count FROMCoursecJOIN Teachert ONc.teacher_id=t.teacher_id LEFTJOINEnrollmenteONc.course_id=e.course_id WHEREe.status=Active GROUPBYc.course_id,c.course_name,c.credit,t.teacher_name;此视图显示每门课程的选课人数创建学生成绩汇总视图CREATEVIEWStudentGradeSummary ASSELECT s.student_id,s.student_name,c.class_name,COUNTg.grade_id AScourse_count,AVGg.score ASaverage_score,SUMco.credit AStotal_credits FROMStudent sJOINClasscONs.class_id=c.class_id LEFTJOINEnrollment eONs.student_id=e.student_id LEFTJOINGradegONe.enrollment_id=g.enrollment_id LEFTJOINCoursecoONe.course_id=co.course_id GROUPBYs.student_id,s.student_name,c.class_name;此视图汇总学生的成绩情况学生成绩系统权限管理教务管理员教务管理员可以管理班级、课程和教师信息,教师但不能修改学生成绩授权示例GRANTSELECT,INSERT,UPDATE,DELETE教师可以查看自己授课的课程信息和学生选ON ClassTO AcademicAdmin;课情况,输入和修改学生成绩授权示例学生GRANT SELECT,INSERT,UPDATE,GRANT SELECTON StudentInfoTO系统管理员学生只能查看自己的选课和成绩信息,不能DELETE ONCourse TOTeacherRole;GRANT SELECTON系统管理员拥有对整个数据库的完全控制权修改任何数据授权需要行级安全性AcademicAdmin;GRANT SELECT,VIEW::CourseEnrollment TO限,可以创建、修改、删除任何数据库对象,INSERT,UPDATE,DELETE ONTeacherRole;GRANT EXECUTEON CREATESECURITYPOLICY管理用户和角色,以及分配权限通过SQL TeacherTO AcademicAdmin;RecordGrade TOTeacherRole;StudentDataPolicy ADDFILTER语句授权GRANT CONTROLON PREDICATEDATABASE::StudentGradeManagem dbo.fn_StudentDataAccessstudent_ent TOSystemAdmin;id ONStudent;这确保学生只能访问自己的数据2314进阶技巧动态SQL SQL动态基础使用SQL EXEC动态SQL是指在运行时构建和执行SQL最简单的动态SQL方法是使用EXEC或语句的技术它可以在不知道具体表名、EXECUTE命令执行字符串形式的SQL语列名或查询条件的情况下生成SQL语句句例如DECLARE@tableName动态SQL在存储过程、自定义函数或应NVARCHAR50=Employee;用程序中特别有用,可以实现高度灵活DECLARE@sql NVARCHARMAX的查询=SELECT*FROM+@tableName;EXEC@sql;这种方法适用于简单查询,但不支持参数传递,可能存在SQL注入风险sp_executesqlsp_executesql存储过程提供了更安全的动态SQL执行方式,支持参数化查询例如DECLARE@sql NVARCHARMAX=SELECT*FROMEmployee WHEREdepartment_id=@deptId;DECLARE@params NVARCHAR100=@deptId INT;EXEC sp_executesql@sql,@params,@deptId=10;这种方法可以有效防止SQL注入攻击进阶技巧递归查询SQL基础CTE1公共表表达式CTE是一个命名的临时结果集,在单个SQL语句中定义基本语法为WITH cte_name ASSELECT statement递归结构SELECT*FROM cte_name;CTE可以引用自身,这就是递归2CTECTE的基础,用于处理层次结构数据递归CTE包含锚成员基本查询和递归成员引用CTE本身的查询,两者通过UNIONALL连接例如WITH EmployeeHierarchyASSELECT employee_id,manager_id,name,0AS levelFROMEmployeeWHEREmanager_id ISNULL UNION实际应用3ALL SELECTe.employee_id,e.manager_id,e.name,递归CTE常用于查询组织结构、产品分类树、任务依赖关系等层次eh.level+1FROMEmployeee JOINEmployeeHierarchy结构数据例如,查询员工及其所有下属WITH ehONe.manager_id=eh.employee_idEmployeeHierarchy AS...SELECT*FROMEmployeeHierarchy ORDERBY level;或者查找产品分类及其所有子分类WITH CategoryHierarchyAS SELECTcategory_id,parent_id,name FROMCategory WHEREparent_id ISNULL UNIONALL SELECTc.category_id,c.parent_id,c.name FROMCategorycJOINCategoryHierarchy chONc.parent_id=ch.category_id进阶技巧窗口函数SQL排名函数聚合窗口函数导航函数ROW_NUMBER为每行标准聚合函数SUM,AVG,LEADcolumn,offset访分配唯一的顺序号;RANK COUNT,MIN,MAX可以问当前行之后的行;为相同值分配相同排名,后作为窗口函数使用,计算当LAGcolumn,offset访问续排名跳跃;前行相关的一组行的聚合值当前行之前的行;DENSE_RANK为相同值例如SELECT FIRST_VALUEcolumn分配相同排名,后续排名连department_id,name,返回窗口第一行的值;续;NTILEn将结果分为n salary,AVGsalary LAST_VALUEcolumn返个桶例如SELECT OVERPARTITION BY回窗口最后一行的值例如name,salary,RANK department_id ASSELECT order_date,OVER ORDERBY salarydept_avg FROMamount,LAGamountDESC ASsalary_rank Employee;这将显示每个OVERORDERBYFROM Employee;员工的薪资和其所在部门的order_date AS平均薪资previous_amountFROM Orders;这将显示每个订单金额及前一个订单的金额进阶技巧透视表SQL123操作操作动态PIVOT UNPIVOTPIVOT将行数据转换为列形式呈现将列数据转换为行形式呈现处理未知列值的灵活解决方案PIVOT操作将行数据转换为列数据,特别适用于生成交叉表报表基本语法为SELECT...FROMtablePIVOT aggregate_functioncolumnFOR pivot_column INpivot_value1,pivot_value2,...AS alias;例如,计算每个部门每个季度的销售总额SELECT department,Q1,Q2,Q3,Q4FROM SalesPIVOT SUMamountFOR quarterIN Q1,Q2,Q3,Q4AS PivotTable;UNPIVOT操作与PIVOT相反,将列数据转换为行数据语法为SELECT...FROMtableUNPIVOT value_column FORname_column INcolumn1,column2,...AS alias;例如SELECT department,quarter,amount FROMQuarterlySales UNPIVOTamount FORquarterIN Q1,Q2,Q3,Q4AS UnpivotTable;动态PIVOT处理未知的pivot值集合,需要使用动态SQL例如,若季度名称事先未知DECLARE@columns NVARCHARMAX,@sqlNVARCHARMAX;SELECT@columns=STRING_AGGQUOTENAMEquarter,,FROM SELECTDISTINCT quarterFROM SalesASquarters;SET@sql=SELECT department,+@columns+FROM SalesPIVOT SUMamountFOR quarterIN+@columns+AS PivotTable;EXEC sp_executesql@sql;进阶技巧数据处理SQL JSON数据类型操作函数解析与索引JSON JSONJSONSQL Server2016及更高版本支持JSON数JSON_VALUE提取标量值SELECT OPENJSON函数将JSON数组转换为表格据处理,尽管没有专门的JSON数据类型,JSON_VALUE{name:John,形式SELECT*FROM但提供了一组函数用于处理存储在age:30},$.name;JSON_QUERY OPENJSON[apple,orange,NVARCHAR列中的JSON数据可以通过提取对象或数组SELECT banana]WITH valueISJSON函数验证JSON格式的有效性JSON_QUERY{address:{city:NVARCHAR50$;为提高性能,可以SELECT ISJSON{name:John,Beijing}},$.address;在经常查询的JSON属性上创建计算列索age:30};JSON_MODIFY修改JSON SELECT引ALTERTABLECustomer ADDJSON_MODIFY{name:John},name AS$.age,31;FOR JSON子句将查询结果JSON_VALUEcustomer_info,转换为JSON SELECTname,age$.name;CREATE INDEXFROMPerson FORJSON PATH;IX_Customer_Name ONCustomername;数据库维护数据完整性检查备份策略验证数据库结构和数据2定期备份确保数据安全1索引维护重建和重组索引减少碎片35恢复计划统计信息更新测试和验证恢复流程4维护最新统计信息优化查询数据库备份是最基本的维护任务SQL Server支持完整备份、差异备份和事务日志备份完整备份捕获整个数据库;差异备份仅捕获自上次完整备份后的变化;事务日志备份捕获事务日志记录使用T-SQL命令BACKUP DATABASEdatabase_name TODISK=path\file.bak;BACKUP DATABASEdatabase_name TODISK=path\file.diff WITHDIFFERENTIAL;BACKUP LOGdatabase_name TODISK=path\file.trn;索引维护对于保持查询性能至关重要随着数据修改,索引会变得碎片化,降低查询效率使用sys.dm_db_index_physical_stats DMV检查碎片水平,然后使用ALTER INDEXREORGANIZE碎片率5%-30%或ALTER INDEXREBUILD碎片率30%进行维护例如ALTER INDEXALL ONtable_name REBUILDWITH ONLINE=ON;统计信息帮助查询优化器生成高效的执行计划默认情况下,统计信息会自动更新,但有时需要手动更新UPDATE STATISTICStable_name;定期执行数据库一致性检查DBCCCHECKDB确保数据库结构完整性制定并测试恢复计划,包括各种故障情况的恢复程序,确保在灾难发生时能快速恢复业务数据迁移和ETL数据导出数据导入简介SSISSQL Server提供多种数据导出方法BCP批量复导入数据的方法包括BCP导入bcp SQL Server IntegrationServicesSSIS是企业制程序是命令行工具,用于高性能导出数据bcp database.schema.table infile.txt-c-T级ETL工具,提供图形设计环境创建数据集成解决方database.schema.table outfile.txt-c-T BULK INSERT语句BULKINSERT案SSIS包含各种任务和转换,如数据流任务、执SSMS的导出向导提供图形界面导出数据还可以使Target_Table FROMfile.txt WITH行SQL任务、脚本任务等SSIS特别适合复杂的数用SQL脚本生成INSERT语句SELECT INSERTFIELDTERMINATOR=,,ROWTERMINATOR据转换、清洗和加载过程,支持多种数据源和目标,INTO Target_Table VALUES+...+FROM=\n;OPENROWSET函数INSERTINTO可以处理异构数据系统之间的数据移动Source_Table;Target_Table SELECT*FROMOPENROWSETBULK file.txt,FORMATFILE=format.xml ASSource;数据库监控性能计数器是监控SQL Server性能的基本工具重要的计数器包括SQLServer:Buffer Manager的Buffer cachehit ratio缓冲区缓存命中率;SQLServer:SQLStatistics的Batch Requests/sec每秒批处理请求数和Compilations/sec每秒编译数;SQLServer:Locks的Lock Waits/sec每秒锁等待数;SQLServer:Memory Manager的Total ServerMemoryKB服务器内存总量动态管理视图DMV和函数DMF提供服务器状态信息,是深入了解SQL Server行为的强大工具常用DMV包括sys.dm_exec_requests当前正在执行的请求;sys.dm_exec_sessions用户会话;sys.dm_os_wait_stats等待统计;sys.dm_db_index_usage_stats索引使用情况;sys.dm_io_virtual_file_stats文件I/O统计扩展事件XEvents是轻量级的性能监控框架,可以捕获系统事件SQL ServerProfiler虽然功能强大,但在生产环境中使用需谨慎,因为可能导致性能开销对于长期监控,应考虑设置SQL ServerAgent作业定期收集性能数据,存储到专门的监控数据库中,并创建报表或仪表板进行可视化分析实际工作中的应用SQL临时表与表变量事务和锁定管理临时表#temp和表变量@table在复理解事务和锁定机制对于开发高并发应杂查询中经常使用,用于存储中间结果用至关重要长时间运行的事务会持有临时表创建在tempdb数据库中,可以锁,阻塞其他事务,导致性能问题使创建索引,适合大数据量;表变量存储用适当的隔离级别可以平衡数据一致性在内存中,适合小数据量使用临时表和并发性在高并发环境中,考虑使用可以简化复杂查询,提高可读性和维护乐观并发控制通过性ROWVERSION/TIMESTAMP而不是悲观锁定批处理和分页查询处理大数据集时,使用批处理和分页查询可以提高性能和用户体验分页查询示例SELECT*FROM SELECTROW_NUMBER OVERORDERBYcolumn ASRowNum,*FROM TableAS RowConstrainedResultWHERE RowNumBETWEEN@start AND@end;SQL Server2012以后可使用OFFSET-FETCH SELECT*FROM TableORDERBYcolumn OFFSET@offset ROWSFETCHNEXT@pageSize ROWSONLY;课程总结高级应用1性能优化与高级技术应用实践项目2综合案例实战训练进阶知识SQL3存储过程、触发器和视图等基础操作SQL4数据定义和操作语句数据库基础5关系型数据库基本概念本课程系统性地介绍了SQL Server数据库的基础理论、核心功能和高级应用技术从数据库和表的创建,到数据的操作和查询,再到复杂的存储过程、触发器和视图的实现,我们逐步构建了完整的数据库应用开发知识体系通过两个实际项目案例—商品管理系统和学生成绩管理系统,我们将理论知识应用到实践中,解决了实际业务问题学习了如何设计数据库结构、创建各类对象、编写高效查询,以及实现各种业务逻辑我们还探讨了SQL的高级特性,如动态SQL、递归查询、窗口函数、透视表和JSON数据处理,以及数据库维护、监控和性能优化的最佳实践这些知识将帮助您应对实际工作中的各种挑战,成为一名专业的数据库开发人员或管理员结语持续学习与实践在线学习资源认证与进阶实践与交流微软官方文档docs.microsoft.com/sql提供微软提供多种SQL Server认证,如Microsoft真正的学习来自实践尝试开发自己的数据库项最权威的SQL Server技术资料;SQLServerCertified:Azure DatabaseAdministrator目,参与开源项目贡献代码,解决StackCentralsqlservercentral.com拥有丰富的Associate和Microsoft Certified:Data Overflow上的问题加入本地或线上SQL用户教程和论坛;Pluralsight和Udemy等平台提Engineer这些认证可以验证您的技能并提升组,参加技术会议和工作坊,与同行交流经验供专业的视频课程;GitHub上有众多开源项目职业竞争力除了SQLServer,建议学习定期阅读技术博客和书籍,保持对新技术的敏感和代码示例可供学习定期关注这些资源,了解NoSQL数据库如MongoDB、数据仓库技术度和学习动力最新技术动态和大数据平台如Hadoop、Spark,拓宽数据领域知识。
个人认证
优秀文档
获得点赞 0