专栏首页跟着阿笨一起玩NET关于SQL Server数据库设计的感悟,请指教

关于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 条评论
登录 后参与评论

相关文章

  • 使用FileSystemWatcher监视文件变化

    本文转载:http://www.cnblogs.com/zanxiaofeng/archive/2011/01/08/1930583.html

    跟着阿笨一起玩NET
  • 自定义 SqlHelp

    跟着阿笨一起玩NET
  • 用 XML 文件持久化和恢复图片信息

    跟着阿笨一起玩NET
  • 前端面试题

    3、实现效果,点击容器内的图标,图标边框变成border 1px solid red,点击空白处重置。

    grain先森
  • JMeter 关于JMeter 正则表达式提取器的一点研究

    结论:默认情况下,放置于线程组之下的正则表达式提取器,对全部sampler有效,我个人的感觉是正则表达式为后置处理器,每执行完一个sample,都会执行一次正...

    授客
  • 程序员必须掌握哪些算法?算法与数据结构文章详细分类与整理!

    为了让你对数据结构和算法能有个全面的认识,我画了一张图,里面几乎涵盖了所有数据结构和算法书籍中都会讲到的知识点。

    五分钟学算法
  • 你到底是对称还是不对称?

    至此,总结下,大部分情况下使用对称加密,具有比较不错的安全性。如果需要分布式进行秘钥分发,考虑非对称。如果不需要可逆计算则散列算法。因为这段时间有这方面需求,就...

    我是程序员小贱
  • 高并发系统中的常见问题

    本文一共分析了三个案例,分别介绍并发系统中的共享资源并发访问、计算型密集型任务缓存访问 、单一热点资源峰值流量问题和解决方案。 Q1:订票系统,某车次只有一张火...

    wangxl
  • 去除Notepad++打开文件后文字下面出现红色波浪线的问题

    也有时候我们一打开Notepad++就会看到满眼的红色波浪线,很是不爽,今天就手把手教大家如何去除文章中下面的红色波浪线。

    黑泽君
  • 速读原著-TCP/IP(Unix选路守护程序)

    U n i x系统上常常运行名为r o u t e d路由守护程序。几乎在所有的 T C P / I P实现中都提供该程序。该程序只使用R I P进行通信,我们...

    cwl_java

扫码关注云+社区

领取腾讯云代金券