关于SQL Server数据库设计的感悟,请指教

有问题的时候,我经常回来博客园寻找答案,久而久之,总结了一些东西。 妄自菲薄,请大家多指出错误,并给出意见 数据库设计三范式基本原则 第一范式:数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。 也就是说,绝对不要出现下面的情况

学生信息

一年一班,97001,张三

这个很容易做到吧,呵呵。

第二范式:数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。

也就是说,绝对不要出现下面的情况

学号

姓名

年龄

课程名称

成绩

学分

97001

张三

13

化学

88

2

其中学号和课程名称是联合主键

因为: (课程名称) → (学分) (学号) → (姓名, 年龄) 第三范式:在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系: 关键字段 → 非关键字段x → 非关键字段y 也就是说,绝对不要出现下面的情况

学号

姓名

年龄

所在学院

学院地点

学院电话

97001

张三

13

清华

中关村

8888888

因为:(学号) → (所在学院) → (学院地点, 学院电话)

特别注意:有时为了提高效率,第三范式可以被打破!多见于外键特别多而且数据量巨大的表。为了提高查询的效率,可以牺牲增删改的效率。

关于表、视图、存储过程: 表就是用来存储数据的,要尽量满足三个范式,不要出现冗余的东西。 视图是用来查询数据的,对于没有外键的基础表,可以直接用来查询。对于外键比较多的业务表,查询操作全部要通过视图。 存储过程和触发器我基本不用,我倾向于在数据库层面不要体现太多的业务(甚至不体现),我把业务全部集中在代码层面。其实还有另外一个原因,我不太精通这方面的技术,见谅见谅。

关于索引: 有朋友举过很好的一个例子,聚合索引就像拼音检索,非聚合索引就像部首索引。 拼音索引在整个字典中都是排好序的,就像查英文单词,你只要按照每页角上的英文索引就可以向后翻或者向前翻来找到你想要的单词。但是想象一下,如果造出了一个新单词,再插入字典中,那将是很恐怖的事情,整个该新单词后面的全部单词全都要向后挪,等于字典重新做了。所以,聚合索引对于查找、排序、筛选(比如,我就想看A到C的所有单词)是很方便的事情。 但是,就算有聚合索引,有的SQL关键字也还是要导致全表扫描的,比如说,我要找类似于*ng的单词(LIKE '%ng'),你就要找遍整个字典(全表扫描),但是如果你找类似于ac*的单词(LIKE 'ac%')就很容易。

非聚合索引就是一对一个关系了(非聚合索引就是对应每条内容的地址),你找某一条记录一下就可以定位到。大家可以想想什么样的字段可以作为非聚合索引,没错,一个就是类似于单据号的字段,每条记录都不一样,而且几乎每次都只找一条。还有什么?对,外键,外键都要加非聚合索引,我实际测过,一个表有很多外键,视图中都是用Inner Join连接起来的,相比之下,10万条数据,没有建立非聚合外键索引的情况下,试图打开用12秒,为每个外键建立非聚合索引,打开速度马上缩短到6秒。 我引用联机文档中的原话来描述一下: 在创建非聚集索引之前,应先了解访问数据的方式。考虑对具有以下属性的查询使用非聚集索引:

  • 使用 JOIN 或 GROUP BY 子句。 应为联接和分组操作中所涉及的列创建多个非聚集索引,为任何外键列创建一个聚集索引。
  • 不返回大型结果集的查询。
  • 包含经常包含在查询的搜索条件(例如返回完全匹配的 WHERE 子句)中的列。

关于主键: 我比较倾向于主键的业务无关性,用的是著名的GUID。虽然占用空间较大,效率也偏低,但是在找不出其它更好的方法。 需要注意的是,建立主键时,SQL Server默认会把主键设置为聚合索引,一定要把他去掉,设置在更有意义的其它字段上,或者压根就不设。

GUID的好处很多,有: 生成主键简单,可预知。 没有并发时主键重复的烦恼。 防止用户手动更改数据库中的数据,一看到GUID,就都吓回去了。 避免数据库表迁移时的麻烦(用自增型的主键,在表迁移时简直就是灾难)。 避免了基础表更新时外键的级联更新(主要体现在主键业务无关性上)。 欢迎大家多提意见。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术翻译

编写SQL查询的最佳方法

毫无疑问,编写代码更像是一门艺术,而不是一门科学。即使有经验,每个编码人员也无法编写既可读又可维护的优美代码。一般来说,当您学习编码艺术时,编码会随着经验而提高...

660
来自专栏影子

PostgreSQL=>递归查询

转载请注明源地址:http://www.cnblogs.com/funnyzpc/p/8232073.html

1403
来自专栏java架构学习交流

面试技巧,如何通过索引说数据库优化能力,内容来自Java web轻量级开发面试教程

       如果我们需要招个Java方面的高级程序员,一方面看年限(本科3年),具体到数据库方面的技能要求,包括如下三个方面:        第一,是否会...

2076
来自专栏葡萄城控件技术团队

一句SQL完成动态分级查询

在最近的活字格项目中使用ActiveReports报表设计器设计一个报表模板时,遇到一个多级分类的难题:需要将某个部门所有销售及下属部门的销售金额汇总,因为下属...

2098
来自专栏鸿的学习笔记

Stream和Table的联系

传统的Table领域和目前的Stream领域看似横亘着不可跨越的鸿沟,类似于经典力学和量子力学,但Stream和Table的依然存在着相关性。在研究这个理论之前...

1022
来自专栏james大数据架构

你真的会玩SQL吗?冷落的Top和Apply

你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接、外连接 你真的会玩SQL吗?三范式、数据完整性 你真...

2268
来自专栏崔庆才的专栏

MySQL 枚举类型的“八宗罪”

2494
来自专栏影子

PostgreSQL>窗口函数的用法

转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9311281.html

1121
来自专栏影子

PostgreSQL=>递归查询

3418
来自专栏用户画像

实验3.1 简单的单表查询

熟练掌握用SELECT语句实现简单的单表查询。掌握SELECT子句、FROM子句、WHERE子句及ORDER BY 子句的用法。

1122

扫码关注云+社区