关于数据库设计的一些理解,很久以前整理过的资料,现在找出来晒一晒,以网上书店设计为例.
网上书店要存储销售给用户的图书信息,这个信息要保存书的国际标准号(International standard book number ISBN号)、书名、出版日期、零售价、分类、出版社名称、订购该书的出版社人员、该书作者姓名
ISBN | 书名 | 出版日期 | 零售价 | 分类 | 出版社名称 | 出版社联系人 | 作者 |
978-7-302-10041-6 | 数据库设计规范 | 2008-01-01 | 50.78 | 数据库类 | 工业出版社 | 张三 | 王清华,李北大 |
988-7-301-10051-7 | Oracle基础知识 | 2009-01-01 | 70.9 | 数据库类 | 清华大学出版社 | 王五 | 李连发, 钱百万 周万财, |
999-9-401-10081-8 | Java编码规范 | 2009-3-14 | 100 | 编程类 | 电子出版社 | 李四 | 朱一刀,陈万剑, |
111-0-890-10092-1 | JSP2.0从入门到精通 | 2008-01-10 | 50 | 编程类 | 电子出版社 | 周大 | 吴江
|
表一:books表
第一步,识别主键。主键是用来唯一标识各个记录的字段。可以选择ISBN号来标识识每一本书,因为任何两本书都不会具有相同的ISBN号。但对于选择主键,我们常规的做法是选择数据库的自增标识来作为主键,为什么不选择ISBN号,主要的原因是主键在存入数据库时可能会因为修改,如果作为主表的主键发生修改,则会产生数据库不一致的情况。但在数据库设计时要对ISBN列建”唯一性约束”
第二步,将可以拆分的属性拆成不可再分的列,分成如下的表。
ISBN | 书名 | 出版日期 | 零售价 | 分类 | 出版社名称 | 出版社联系人 | 作者 |
978-7-302-10041-6 | 数据库设计规范 | 2008-01-01 | 50.78 | 数据库类 | 工业出版社 | 张三 | 王清华 |
978-7-302-10041-6 | 数据库设计规范 | 2008-01-01 | 50.78 | 数据库类 | 工业出版社 | 张三 | 李北大 |
988-7-301-10051-7 | Oracle基础知识 | 2009-01-01 | 70.9 | 数据库类 | 清华大学出版社 | 王五 | 李连发 |
988-7-301-10051-7 | Oracle基础知识 | 2009-01-01 | 70.9 | 数据库类 | 清华大学出版社 | 王五 | 钱百万 |
988-7-301-10051-7 | Oracle基础知识 | 2009-01-01 | 70.9 | 数据库类 | 清华大学出版社 | 王五 | 周万财 |
999-9-401-10081-8 | Java编码规范 | 2009-3-14 | 100 | 编程类 | 电子出版社 | 李四 | 朱一刀 |
999-9-401-10081-8 | Java编码规范 | 2009-3-14 | 100 | 编程类 | 电子出版社 | 李四 | 陈万剑, |
111-0-890-10092-1 | JSP2.0从入门到精通 | 2008-01-10 | 50 | 编程类 | 电子出版社 | 周大 | 吴江
|
表二:删除了多个值的字段,此时已经满足了第一范式。
此时不能再使用书的ISBN号作为主键了,因为已经有重复的行了。所以只能以ISBN号和作者作为联合主键了。
此时表二存在的问题,书名,出版日期只依赖于书的ISBN号,而不依赖于整个联合主键,此时会出现部分依赖,部分依赖会导致插入冗余,修改不一致等情况,解决部分依赖的最简单的方法就是将复合主键分成两部分,每一部分单独作为一个表,在此例中你可以为书创建一个表,为作者创建一个表,消除了部分依赖,数据库表满足了第二范式。
ISBN | 书名 | 出版日期 | 零售价 | 分类 | 出版社名称 | 出版社联系人 |
978-7-302-10041-6 | 数据库设计规范 | 2008-01-01 | 50.78 | 数据库类 | 工业出版社 | 张三 |
988-7-301-10051-7 | Oracle基础知识 | 2009-01-01 | 70.9 | 数据库类 | 清华大学出版社 | 王五 |
999-9-401-10081-8 | Java编码规范 | 2009-3-14 | 100 | 编程类 | 电子出版社 | 李四 |
111-0-890-10092-1 | JSP2.0从入门到精通 | 2008-01-10 | 50 | 编程类 | 电子出版社 | 李四 |
表三,所有的非主属性依赖于主属性的全部。
作者序列(此字段可以作为主键) | 作者姓名 |
1 | 王清华 |
2 | 李北大 |
3 | 李连发 |
4 | 钱百万 |
5 | 周万财 |
6 | 朱一刀 |
7 | 陈万剑 |
8 | 吴江 |
表四,作者表
建立书与作者的关联表,这样就可以通过数据库的关联,形成书与作者信息的显示。
关联表主键 | ISBN | 作者序列 |
1 | 978-7-302-10041-6 | 1 |
2 | 978-7-302-10041-6 | 2 |
3 | 988-7-301-10051-7 | 3 |
4 | 988-7-301-10051-7 | 4 |
5 | 988-7-301-10051-7 | 5 |
6 | 999-9-401-10081-8 | 6 |
7 | 999-9-401-10081-8 | 7 |
8 | 111-0-890-10092-1 | 8
|
表五,作者与书的关联表
此时的表中值存在传递依赖,存在传递依赖表示至少有一个值不依赖于主键,在此例中表三出版社的联系人不依赖于主属性,而依赖于是哪个出版社,出版社依赖于书的ISBN号,这称为传递依赖,出现这种传递依赖时会依然会出现冗余和修改不一致等情况,出现这种情况依然是要进行表的拆分,将出版社和联系人单独分离为一张表。
ISBN | 书名 | 出版日期 | 零售价 | 分类 | 出版社名称 |
978-7-302-10041-6 | 数据库设计规范 | 2008-01-01 | 50.78 | 数据库类 | 工业出版社 |
988-7-301-10051-7 | Oracle基础知识 | 2009-01-01 | 70.9 | 数据库类 | 清华大学出版社 |
999-9-401-10081-8 | Java编码规范 | 2009-3-14 | 100 | 编程类 | 电子出版社 |
111-0-890-10092-1 | JSP2.0从入门到精通 | 2008-01-10 | 50 | 编程类 | 电子出版社 |
表六书的信息表
出版社名称 | 出版社联系人 |
工业出版社 | 张三 |
清华大学出版社 | 王五 |
电子出版社 | 李四 |
表七出版社信息表
通过以上的分析,数据库的表结构满足了规范化的设计方式,出以上的分析过程我们在进行数据库设计时可以通过以下几个步骤来实现数据库的规范化设计。
1.删除所有的重复组,确定数据库表的主键或复合主键,此时满足数据库的第一范式。
2.满足第一范式后,消除数据库表中的任何部分依赖。此时满足了第二范式。
3.在满足第二范式后,消除任何可传递依赖,此时满足第三范式。
在通常情况下数据库满足第三范式后即可以满足数据设计的要求。
可以看到在数据库设计规范化的过程也就是将数据表进行拆分的过程,在拆分后可以避免插入异常,修改异常,删除异常,数据冗余等问题,但这种拆分同时也会带来另外一个问题,即在查询时一定要进行关联查询,在数据库数据量不是特别大的情况下不会产生效率问题,比如一个10万行的表和1万行的表进行关联,不会产生太大的效率问题,但是当两个100万数据量的表进行关联时,就会出现查询效率的问题,此时就要进行反规范化的设计,反规范化的设计的基本操作有如下几种方式,建立冗余字段,多表合并,建立索引,如果还存在效率问题还可以通过建立分区表,数据截转,按月、按年建立数据表等方式来进行相应的处理,在此不作过多的论述。
那么在进行数据库设计时如何来考虑数据量与数据库的效率问题,如下表关于数据量与数据库设计时的一些考虑。如果1年数据的总行数小于10000行,那么任何的设计和实现都可以。如果1年数据的总行数是100000行,那么在设计时就需要多加考虑,如果第1年的总行数是1000000行,那么在设计时就需要考虑建立冗余,多重粒度的问题,如果第一年的总行数是10000000,那么在设计时就必须考虑建立冗余,分区,分表等技术手段。
数据量与数据库设计考虑
一年数据 | 五年数据 | ||
数据量 | 策略 | 数据量 | 策略 |
10000 | 任何设计策略 | 50000 | 任何设计策略 |
100000 | 谨慎设计 | 500000 | 谨慎设计 |
1000000 | 考虑多表合并、 冗余 | 5000000 | 考虑多表合并、 冗余 |
10000000 | 必须考虑冗余、分区、分表 | 500000000 | 必须考虑冗余、分区、分表 |