首页 / 资讯中心 / 文章详情

SQL Server知识地图:关系模型、约束、索引与视图复习

SQL Server知识地图:关系模型、约束、索引与视图复习 ★ FEATURED ARTICLE
简介这份 SQL Server 学习笔记面向数据库初学者、数据库管理从业者以及准备系统梳理 SQL Server 基础知识的人群围绕关系数据库管理系统的主要特点与核心知识点展开可用于课堂复习、岗位入门和日常查阅。压缩包内含 1 个 doc 文档大小约 499KB体积轻便适合直接下载后按章节阅读与标注。目前已有 440 人学习或下载具备一定的参考与交流基础。内容覆盖创建、删除、修改数据库对象C/S 体系与编程接口表、列、索引、触发器、存储过程的限制参数以及关系模型中的实体、属性、码、域和元组等概念同时整理数据库授权、系统数据库作用、数据文件与日志文件存储、建库建表语句、主键/外键/默认值/check/unique 约束和视图创建等要点便于读者建立从概念到语句实践的完整知识框架并快速查阅常见对象与约束的用法。1. 知识地图从一条语句到整个库的四层骨架复习 SQL Server 学习笔记时最容易忽略的往往不是语句本身——写起来顺手——也不是那些数字比如一张表最多能建几个索引。真正容易模糊的是模型层与完整性层候选码和主码差在哪、第二范式为什么会被一个联合主键搞崩、视图为什么有的能更新有的不能、簇索引为什么一个表只能有一个。这份笔记按四条线整理体系与对象容量架构、接口、上限参数、系统库与文件、模型与范式实体、码、域、1NF 到 BCNF、实现与约束建库建表、五类约束、视图索引存储过程游标、授权链、易错点与自查。前两条线决定概念题能不能答对后两条线决定动手时会不会返工重来。适合已经写过一些语句、但知识还散着、一查就乱的人拿来对照。2. 体系与对象容量上限、系统库与文件组成的参数表2.1 C/S 体系与编程接口先搞清楚谁在连谁SQL Server 的结构第一层是 C/S 体系客户端发起请求服务器端解析、执行、把结果集送回去。这决定了后面很多参数为什么会存在——用户连接有上限、权限按登录来控制、锁与打开对象被单独统计、可同时打开的数据库数量也有上限。它不是「一个软件装完就完事」而是一套两端的协作关系。编程接口这一层ODBC、VB、VC、Access 都能接入说明它是开放的前端换语言、换工具不影响后端数据怎么组织。再往上是能力层Web 支持与基于 Web 的分析、数据仓库功能、XML 扩展标记语言支持、分布式分区视图。分布式分区视图是把多台服务器上的表拼成一张逻辑表给前端看做水平拆分时用得上但代价是查询要走多台机器跨机事务要额外考虑。这一段建议按「接入方式 → 分析能力 → 分布式能力」三层来记不要零散背名词。复习时问自己三个问题就够了客户端以什么身份连进来、连进来能做什么分析、数据分散在多台机器上时靠什么拼成整体。2.2 容量上限这些数字需要一次查清不用反复背笔记里最容易抄错、也最容易考到的就是这张表。先把原样整理出来对象上限容易记错的地方数据库大小1MB — 1TB上限不是无限规划容量时按这个量级估每个数据库的表20 亿与「锁定及打开对象 20 亿」是同一个数量级别串每张表的列1024 列与存储过程的 1024 个参数撞数靠「列 vs 参数」区分每行的字符8060 字符是行宽限制不是列数也不是单个列的长度索引每表 1 个簇索引、249 个非簇索引16 列249 只数非簇索引簇索引永远只有 1 个触发器每表 3 个INSERT、UPDATE、DELETE是按三种操作各一个不是任意三个存储过程最多 1024 个参数、32 级嵌套嵌套级数是 32不是 1024用户连接32767这是连接数不是表数可同时打开的数据库32767笔记里也出现过 327687 的写法属于抄录串位统一按表格与用户连接同数容易互相污染锁定及打开对象20 亿与表数量同量级这张表不建议死背要记住的是「抓手」1024 出现两次列、参数32767 出现两次连接、同时打开的库20 亿出现两次表、锁定对象249 只属于非簇索引8060 只属于行宽。这样即使考场上记不清具体数字也能靠配对关系推回来。提示笔记里同一个参数出现两个数字时不要两个都记选一个写进自己的参数表另一个标注「已废弃写法」否则复习时会一直自我冲突。2.3 系统数据库与文件组成库不是一坨是几个文件加几个角色六个系统库各有分工混在一起背会乱系统库作用记忆点master保存主数据登录账号、其他数据库信息、服务器全部配置信息坏了整套都起不来最不能乱动model模板库新建数据库时按它的样子复制改它等于改以后所有新库的默认长相tempdb存放临时表连接一断里面的东西就没了msdb默认 12MB保存调度作业、警报、接收警报的操作员信息与「自动化任务」相关pubs样例数据库练手用northwind样例数据库练手用业务模型比 pubs 完整数据在磁盘上被映射成几类操作系统文件主要数据文件.mdf包含数据库的启动信息并存储数据次要数据文件.ndf用来承接主文件放不下的数据需要把数据摊到多个磁盘时用它延伸日志文件.ldf是事务机制和可恢复性的实现基础记录用于恢复数据库的日志信息一个事务的日志记录不可分割。文件组是为了方便管理文件把若干文件构成一个分配单元。做规划时的顺序是先定数据文件和日志文件能不能放在不同的物理盘上日志顺序写、数据随机读混在一起性能会互相拖再考虑要不要多个次要文件分摊 IO最后才谈文件组。这个顺序反过来做往往建完就得重建。3. 关系模型与范式实体、码、域到三大范式3.1 概念模型里的六个基本词这部分看着简单但它是后面所有约束、主键、外键讨论的地基词一旦混用后面的题就全歪。实体是客观存在、可以相互区分的事物。属性是实体具有的某一特性比如性别、年龄。码是能唯一标识实体的属性集学号就是学生实体的码——给一个学号20111221004只能对应一个学生这才叫唯一标识。域是属性的取值范围性别取「男、女」学号取 11 位整数这就是域在起作用。再往上一层是抽象实体型是用实体名加属性集合来描述同类实体写成「顾客编号、姓名、性别、年龄」这种形式实体集是同型实体的集合比如全体顾客、全体学生。联系有两层含义一层是实体内部的联系属性之间的关系一层是实体之间的联系顾客和订单之间。这两个层次别混在一起记前者在建模阶段消化掉后者才会变成外键。四种常见数据模型层次模型、网状模型、关系模型、面向对象模型。关系模型是现在的主流原因很实际——它把数据组织成表用户不用关心物理存储怎么排查询只描述「要什么」不描述「怎么找」。层次和网状模型要求你按指针路径访问改一个结构牵动一大片这是它们退场的主要原因。3.2 关系模型里的一词两用学术叫法和工程叫法对照同一个东西在教材里叫一个名字在工具里叫另一个名字这是概念题丢分的高发区学术叫法工程叫法说明关系表一张表就是一个关系元组行表里的一行记录属性列 / 字段表里的一列分量单元格的值元组中的一个属性值主码主键能唯一确定一个元组的属性组域取值范围属性的取值集合关系模式表结构关系名、列名、属性所属域名、属性向域的映射、数据间的依赖关系「关系模式」这一行值得单独说它描述的不是某一时刻表里有什么数据而是这张表长什么样、列之间有什么依赖。所以你写CREATE TABLE的时候写的其实是关系模式你INSERT进去的每一条才是关系在某个时刻的实例。这个区分在讨论范式的时候必须清楚因为范式约束的是关系模式不是某一批数据。3.3 一张表凭什么算「关系」五个条件不是随便一张二维表都能叫关系要同时满足每一列的数据类型都相同没有完全相同的两行列与列之间字段名不能重复没有组合列即一列里不能再有子列也不能把一列拆成两列以上行列的顺序不影响语义教材里常说的「行无序、列无序」。第 4 条是最容易被忽略的因为它和实际建表习惯冲突。业务上经常有人想在一列里塞「生活用品,电子产品」这种逗号分隔的多值看着方便实际已经把表踢出了关系模型——查询时得靠字符串切割索引也用不上排序更无从谈起。这就是下一节第一范式要解决的问题。3.4 从 1NF 到 BCNF每一层都在解决上一层留下的一个具体毛病第一范式解决组合列。笔记里的例子很典型一张商品表列写成goods_type_1, goods_type_2, goods_type_3想查「所属类别为生活用品的商品编号」结果为空——因为生活用品可能落在第一列也可能落在第三列条件写哪一列都不完整。这就是组合列的直接代价。改法有两种把非原子属性拆成多列适合列数固定且很少或者拆成多行适合列数不定。更彻底的是分解表把类别单独抽成一张表商品表只留类别编号。判断要不要继续拆的标准是具体业务如果业务上永远最多三个类别拆成三列也能用一旦会出现第四个就必须拆表。第二范式解决部分依赖。笔记里那张buy_info是关键案例CREATE TABLE buy_info ( 购买了商品的用户编号 VARCHAR(10), 用户购买商品编号 VARCHAR(10), 用户购买商品名称 VARCHAR(10), PRIMARY KEY (购买了商品的用户编号, 用户购买商品编号) );这段代码的毛病不在语法在语义用户购买商品名称只依赖「用户购买商品编号」这一个属性却被绑在由两列组成的联合主键上形成部分依赖。后果有两个都很具体一是联合主键的每一列都不允许为空可现实中某个字段没填就可能插不进去这叫插入异常二是同一个商品名会在多条记录里重复出现改名的时候要更新多处漏一处就数据不一致这叫更新异常。第二范式的定义就是在满足 1NF 的前提下每个非主属性都完全依赖于码不存在只依赖码的一部分的非主属性。第三范式解决传递依赖。如果 a 决定 bb 决定 c而 c 不属于 b、b 也推不出 a那 c 就是通过 b 传递依赖于 a这张表就不满足 3NF。典型场景是学生表里塞了「宿舍楼 → 楼长」这种链学号定宿舍楼宿舍楼定楼长楼长跟学号没有直接关系却被迫跟着每一行学生记录重复存储。BCNF是修正的第三范式。3NF 只约束非主属性对码的依赖BCNF 把这个要求收紧到所有属性包括主属性——即每一个决定因素本身都必须是候选码。考试里区分 3NF 和 BCNF 的经典套路就是表里有两个候选码它们之间有重叠属性某个主属性被另一个主属性决定这时它满足 3NF 但不满足 BCNF。这一节的复习方法不是背定义而是拿一张具体的表逐条问三个问题有没有一列里塞了多个值1NF、有没有哪个非主属性只依赖联合主键的一部分2NF、有没有哪个非主属性被另一个非主属性决定3NF。三个问题都答「没有」范式这一块基本就过关了。4. 建库建表与可编程对象DDL 主干、五类约束与授权链4.1 创建数据库的三段式ON 和 LOG ON 各管一段建库语句的结构很固定难点不在语法在每个参数怎么填CREATE DATABASE shop -- 数据库逻辑名允许用中文 ON PRIMARY -- 主文件组存放数据文件 ( NAME shop_data, -- 逻辑文件名后续备份恢复靠它识别 FILENAME D:\data\shop_data.mdf, -- 物理路径必须提前建好目录 SIZE 10MB, -- 初始大小 MAXSIZE 500MB, -- 增长上限不写就可能把磁盘吃满 FILEGROWTH 5MB -- 每次增长量按 MB 或百分比 ) LOG ON -- 事务日志文件与数据文件分开 ( NAME shop_log, FILENAME D:\data\shop_log.ldf, SIZE 5MB, MAXSIZE 200MB, FILEGROWTH 1MB );逐段看ON后面定义数据文件文件名、存储路径、初始大小、可增长到的最大值、增长增量LOG ON后面定义事务日志文件参数一一对应。SIZE给太小会频繁自动增长每次增长都伴随文件初始化表现为偶发卡顿MAXSIZE不写日志文件会一路涨到磁盘满FILEGROWTH给百分比在小库上没问题库大了每次增长就是几百 MB容易抖。日常建库时可选项方括号里的内容一般不指定用默认值关键字大小写不敏感create和CREATE等价数据库逻辑名可以用中文但物理文件名建议还是英文避免跨平台拷文件时编码出问题。4.2 建表与数据类型char 的截断是静默发生的常用数据类型整理成表更清楚类型写法关键点定长字符char(n)n 取 1—8000实际存储长度固定为 n超出 n 的部分被截掉且不报错变长字符varchar(n)存储大小为实际输入的字节数不是 n整型int、bigint、smallint、tinyint按取值范围从大到小选别一律用 int精确数值numeric(p, s)p 是总位数s 是小数位货币money不需要单引号但要带合适的货币符号日期时间datetime表示一天内的时间点表类型table存一组数据并作为函数结果集返回只支持主键、唯一性、空值三种约束char那条要单独画重点超长部分是静默截断的不抛异常。也就是说你插一个 12 位的字符串进char(10)存进去只有 10 位而且当时的语句是成功的。这个坑在导入历史数据时特别常见往往是事后对账才发现少了两个字符。变长场景一律用varchar只有在长度绝对固定如统一 6 位编码时才用char因为定长在频繁更新时不会产生行迁移。插入语句的约束是硬性的INSERT INTO goods (goods_id, goods_name, goods_type) VALUES (G00001, 课桌, 生活用品);括号里的列必须和值一一对应个数和顺序都要匹配否则整条插入失败。建表时如果某列允许为空插入时这一项可以直接写NULL占位如果建表时设了默认值约束省略该列也能成功系统会自动填默认值。这两种情况的区别要分清写NULL是明确告诉系统「这里就是空」省略列是「让它自己按默认值来」语义不一样。4.3 五类约束与完整性四条线约束是手段完整性是目的先看约束五类各有各管的范围约束写法管什么违反时的表现主键约束PRIMARY KEY唯一标识每行值不能为空插入重复或空值直接拒绝外键约束FOREIGN KEY ... REFERENCES两张表之间的对应关系被引用表里没有对应值时拒绝默认值约束DEFAULT用户没指定时自动填的值不违反自动补齐用户自定义约束CHECK自定义的取值规范不满足规范时拒绝执行唯一性约束UNIQUE该列的值不可重复插入已存在的值被拒绝再看完整性四条线是「目的」约束只是实现目的的手段答题时不要混为一谈域完整性输入到某一列的数据是否符合这一列的要求即列的输入有效性是对列做的规定靠DEFAULT和CHECK实现实体完整性要求每行有一个唯一标识符能和其他行区分表里没有重复行是对行做的规定靠主键实现用户自定义完整性业务规则层面的约束靠CHECK、规则、触发器实现参考完整性维护表与表之间主键和外键的对应关系在插入或删除记录时保证已定义的关系不被破坏靠外键实现。强制完整性的方式有三种笔记里点得很清楚约束、默认、规则。默认的用法是两步先建默认对象再绑定到列上CREATE DEFAULT goods_type_default AS 生活用品; -- 先定义默认值对象 EXEC sp_bindefault goods_type_default, goods.goods_type_name; -- 再绑定到具体列注意sp_bindefault的第二个参数是「表名.列名」的字符串形式写错表名不会报错只会在插入时才发现没生效——这类静默失败在排查时最费时间绑定完最好立刻插一条测试数据验证。修改表的操作归纳成五类这是实操题的高频点-- 1. 加列 ALTER TABLE goods ADD goods_remark VARCHAR(100) NULL; -- 2. 加约束约束名建议自己起别用系统随机名 ALTER TABLE goods ADD CONSTRAINT ck_goods_number CHECK (goods_number 0); -- 3. 删约束再删列——顺序不能反 ALTER TABLE goods DROP CONSTRAINT ck_goods_number; ALTER TABLE goods DROP COLUMN goods_remark; -- 4. 开关约束 ALTER TABLE goods NOCHECK CONSTRAINT ALL; -- 关闭全部 ALTER TABLE goods CHECK CONSTRAINT ALL; -- 打开全部 -- 5. 改列类型或可空性 ALTER TABLE goods ALTER COLUMN goods_number INT NULL;第 3 类操作有个必须先做的前置动作要删的列如果身上挂着索引、CHECK、外键、唯一性、主键、默认值或规则绑定必须先删掉这些依赖否则DROP COLUMN会直接失败。笔记里那句「要删除商品数量需要先删除商品的约束条件」说的就是这个顺序。4.4 视图定义限制比语法更值得记建视图的基本形式CREATE VIEW goods_1_view_5 AS SELECT goods_name, goods_type_name FROM goods_1 WHERE goods_type_name 电子产品 WITH CHECK OPTION; -- 通过本视图做的修改必须满足 WHERE 条件可选项一共四个含义差别很大WITH ENCRYPTION要求在存储视图语句文本时加密WITH SCHEMABINDING把视图绑定到架构上底层表的结构就不能随便改了WITH VIEW_METADATA让浏览模式的元数据返回相对基表的视图名而不是基表名WITH CHECK OPTION规定对该视图做插入、修改时必须满足视图定义里的查询条件。定义视图的查询表达式有三条硬限制定义者必须对派生此视图的基本表有SELECT权限查询语句里不能出现INTO、ORDER BY、COMPUTE、COMPUTE BY不能引用临时表或表变量临时表存在临时库里连接一断就消失视图没法依赖它。更新视图数据要同时满足几个条件FROM子句至少引用一个表选择列表里没有派生列没有聚合函数不含TOP、GROUP BY、UNION、DISTINCT。这四条记不住也没关系反着想更快只要是「算出来的」或「去重后的」结果就没法反推回唯一一行自然不能更新。多表连接视图的更新更严格因为一行视图数据可能对应多张表的多行系统无法判断该改哪张。删除同理DELETE里的视图必须是可更新且正确引用一个基表的视图。删一张表的数据和删多表关联视图的数据成功率完全不在一个量级。4.5 索引簇索引只有一个这句话值得抄三遍索引是加速检索的一种由关键字组成的树状结构建立目的是提高访问速度可以用能唯一标识数据子集的列来建也可以建成与原表分开的独立数据库对象。两类索引的区别在于物理顺序簇索引的顺序与表中数据的物理存储顺序一致所以一个表只能有一个非簇索引按完全不同的结构对数据排序表里的数据可以按另一种顺序存储它的运行原理是先通过索引找到数据存放的位置再去那个位置取数据——也就是多一次定位。簇索引是「数据就是索引」非簇索引是「索引指向数据」。建索引的四个典型场景几乎是原题经常被搜索的列、需要排序的列、主键或外键所在列、经常出现在WHERE条件里的列。-- 唯一簇索引值不允许重复且决定物理顺序 CREATE UNIQUE CLUSTERED INDEX goods_index ON goods_1(goods_id ASC); -- 复合索引多列组合列的先后顺序有讲究 CREATE INDEX goods_index2 ON goods_1(goods_id, goods_type_id);参数含义UNIQUE表示唯一性索引不允许存在索引值相同的两行CLUSTERED表示簇索引ASC/DESC指定排序方向。复合索引的列序不是随便排的把选择性高、查询里最常用的列放前面才能让后续列的排序也顺带用上索引反过来如果查询条件只用到了第二列这个复合索引基本白建。索引不是越多越好每建一个索引插入、更新、删除都要多维护一棵树。真实项目里一张高频写入的表挂七八个索引写性能掉一半是常事。所以「该建索引的地方」那四条是筛选标准不是「全都建一遍」的清单。4.6 存储过程与游标把多条语句打包把多行数据逐条处理存储过程把查询、插入、删除、更新等一系列语句封在一起调用时一起执行。能被触发器触发的操作是UPDATE、DELETE、INSERT三种。CREATE PROCEDURE modify_process bid_user VARCHAR(10), -- 出价用户 bid_date DATETIME, -- 出价时间 bid_number INT, -- 本次购买数量 bid_goods_id VARCHAR(10), -- 商品编号 goods_price MONEY -- 成交单价 AS UPDATE goods SET goods_number goods_number - bid_number WHERE goods_id bid_goods_id; INSERT INTO user_history VALUES (bid_user, goods_price * bid_number, bid_date);这段的价值在于「两条语句必须一起成功」扣库存和记流水如果分开执行中间挂掉就会出现库存扣了但流水没记的脏数据。封装进存储过程后失败可以整体回滚。参数前缀后面跟类型调用时按位置或按名传值参数个数最多 1024 个嵌套层级最多 32 级。有个细节值得留意存储过程里的 SQL 语句在建的时候是封装好的所以系统不会对它引用的表做存在性验证——表名写错了照样能建成功要到执行时才报错。写完立刻EXEC一遍是省事也实在的习惯。游标用来处理「一行一行来」的场景标准五步DECLARE goods_name VARCHAR(50), goods_number VARCHAR(20); DECLARE shop_info CURSOR FOR SELECT goods_name, goods_number FROM goods WHERE goods_name LIKE S% ORDER BY goods_name, goods_number; OPEN shop_info; -- 1. 打开 FETCH NEXT FROM shop_info INTO goods_name, goods_number; -- 2. 取第一行 WHILE FETCH_STATUS 0 -- 3. 循环取到取不出为止 BEGIN PRINT goods_name goods_number; FETCH NEXT FROM shop_info INTO goods_name, goods_number; END CLOSE shop_info; -- 4. 关闭 DEALLOCATE shop_info; -- 5. 释放FETCH_STATUS是全局变量0 表示取到了非 0 表示已到末尾或出错。这个循环的写法必须先FETCH一次再进WHILE否则第一行会被跳过——这是游标最经典的一处坑。另外游标本质是逐行处理数据量上万就会明显变慢能用集合操作UPDATE ... FROM、INSERT ... SELECT就别用游标。补充一个集合思路处理模糊查询的例子比LIKE %关键字%更可控SELECT title FROM mydb WHERE title LIKE 关键字% UNION SELECT title FROM mydb WHERE title NOT LIKE 关键字% AND CHARINDEX(关键字, title) 1;前半段把前缀匹配的排前面后半段用CHARINDEX补上出现在中间的情况UNION去重。这样排序优先级可控比单纯的%...%更容易判断索引有没有被用上。4.7 登录、用户、角色授权是一条链不是一步数据库授权是通过新建用户来实现的目的是对这个用户指定其基于本登录所拥有的数据库操作权限。注意这句话里的层次登录是服务器级的用户是数据库级的角色是权限的集合。三者是一条链跳过任何一环都会出问题。EXEC sp_addlogin app_user, pwd_here, shop; -- 1. 建登录名称、密码、默认库 EXEC sp_adduser app_user, app_user, db_owner; -- 2. 建用户登录名、用户名、所属角色 EXEC sp_addrole report_role, dbo; -- 3. 建角色角色名、拥有者 GRANT SELECT, INSERT ON goods TO app_user; -- 4. 授权 REVOKE INSERT ON goods FROM app_user; -- 5. 回收sp_addlogin的第三个参数是登录后默认连接的数据库第四个是默认语言都能省略。sp_adduser的用户自动成为指定角色的成员角色填db_owner就是库内全权生产环境一般不给。GRANT给权限REVOKE回收权限这两个是配套的只授不回收权限会越滚越大最后没人说得清谁有什么。5. 易错点五个最容易被跳过的地方5.1 概念层的三个漏点易漏点一候选码、主码、外码当成同义词用。为什么漏教材里三个词挨着出现定义又都是「唯一标识」读快了就糊成一团。 怎么补记住一条链——候选码是「所有能唯一标识一行的属性组」可能有好几个主码是从候选码里选定一个作为主码所以主码一定是候选码候选码不一定是主码包含在任何一个候选码里的属性叫主属性一个都没沾上的叫非主属性外码是联系两张表的那个属性它的值必须能在另一张表的主码里找到。做范式题第一步永远是先把候选码全列出来漏一个候选码后面 2NF、3NF 的判断全错。易漏点二联合主键里放了可为空的列。为什么漏建表时只盯着「唯一性」忘了主键隐含「非空」。 怎么补主键的每一列都不允许为空联合主键也一样。只要其中一列可能为空这张表在设计上就已经埋了插入异常——业务上这条记录缺失该字段时根本插不进去。判断方法很直接把主键的每一列单独问一句「这列业务上会不会没值」答案是「会」就该拆表或者换主键。易漏点三视图定义里顺手写了 ORDER BY。为什么漏写查询写习惯了SELECT后面跟ORDER BY是肌肉记忆。 怎么补视图定义里不能出现INTO、ORDER BY、COMPUTE、COMPUTE BY也不能引用临时表或表变量。排序需求放到查询视图的那条语句上去写不要塞进视图定义。同理TOP、GROUP BY、UNION、DISTINCT出现在视图里这个视图基本就告别更新能力了。5.2 语句层的两个翻车点易漏点四以为索引可以随便建忘了簇索引只有一个。为什么漏参数表里「249 个非簇索引」这个大数字太醒目容易把「1 个簇索引」当成笔误。 怎么补一张表只能有一个簇索引因为簇索引决定的是数据的物理存储顺序一个表不可能同时按两种顺序摆。已经有一个簇索引再建第二个直接报错。同理在已经有大量重复值的列上建UNIQUE索引也会被拒绝——建之前先GROUP BY ... HAVING COUNT(*) 1查一遍重复值比建失败再回头找原因省时间。易漏点五删列直接删忘了先拆约束。为什么漏以为DROP COLUMN就是砍掉一列没意识到这一列可能被索引、CHECK、外键、默认值、规则绑定引用着。 怎么补删列前先查依赖按「删约束 → 删索引 → 删列」的顺序走。被复制的列、用在索引中的列、用在CHECK/ 外键 /UNIQUE/ 主键里的列都不能直接删。另外DELETE和DROP千万别混DELETE FROM 表删的是行表结构还在DROP TABLE 表删的是整张表连结构带数据一起没。这两者搞混是能上生产事故级别的失误。6. 复习清单一页纸自查与查漏补缺到了这一章笔记该收了。复习时我不再从头翻而是拿一张自查表过一遍答不上来的那一格就是当天的复习任务自查项能答出来就算过答不上就回看一张表最多几个簇索引、几个非簇索引1 个、249 个2.2 参数表一行最多多少字符是列数还是行宽8060行宽2.2 参数表master 和 model 各管什么master 存主数据与配置model 是新库模板2.3 系统库关系、元组、属性在工程里叫什么表、行、列3.2 对照表一张表算「关系」的五个条件同类型、无重复行、列名不重、无组合列、行列无序3.32NF 解决的是哪种依赖非主属性对码的部分依赖3.43NF 和 BCNF 差在哪BCNF 把约束收紧到主属性3.4五类约束分别对应哪条完整性主键→实体外键→参考CHECK/DEFAULT→域4.3视图不可更新的四个典型特征派生列、聚合、TOP/GROUP BY/UNION/DISTINCT4.4删列前必须先做什么先删约束和索引5.2登录、用户、角色分别在哪一层服务器、数据库、权限集合4.7游标五步的顺序声明、打开、取、关、释放4.6表格之外还有三个查漏补缺的具体做法比反复看笔记有效得多。第一个是反向出题。把参数表盖住只留左侧的对象名自己默写上限把范式定义盖住只给一张具体的表自己判断它到第几范式。能出题说明真懂了只能读说明只是眼熟。第二个是拿错误代码验证。笔记里那些「会失败」的例子亲手跑一遍比看十遍定义管用往char(10)里插 12 位字符串看截断、往有簇索引的表上再建一个簇索引看报错、在视图里写ORDER BY看提示、删一个带CHECK约束的列看报错信息。报错信息本身就是最好的复习材料它会告诉你系统在检查什么。第三个是按错误分类建错题本。我自己的分类是三栏概念混淆候选码/主码、登录/用户、语法限制视图不能带ORDER BY、DROP COLUMN的前置条件、数值记串249 和 32767 混着用。每栏只记「错在哪 正确说法 一句话原因」不抄整道题。复习时只看第一栏能想起后两栏就算过。最后说个我自己踩过的坑早年复习这类笔记我总喜欢从第一页按顺序读到最后一页读完感觉全会一合上笔记问「249 是非簇索引还是索引总数」就卡住。后来改成先过自查表、再定点回看对应章节同样一小时效果差出一大截。从那以后我每次复习都强制先做一遍自查表答不上来的才翻书不再从头顺着读。希望这套整理方式能帮到你——这份 SQL Server 学习笔记的完整版按章节顺序排好了需要的时候拿去对照着过一遍就行。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站