本身经验杂项:html
1.tree表设计,除,id,pid,等加入treepath,有利于快速检索和直接检索,感受是二叉寻找,O(2^n)。程序员
2.系统都有权限表,这个是一个比较有名成熟的设计方案,名忘记了。算法
https://my.oschina.net/u/1052786/blog/701891数据库
3.表不少,通常系统会用到一些公共变量,抽象出字典表。安全
4.都是,表名也要有意义,分类别管理,不说了。架构
5.表里通常都有,主键:要有意义,hbase分布式的话,就知道有意义的主键是路径的检索依据,计算机的世界都是先找到资源位置再取东西,一直都在努力改进找路的问题。自动增加的主键导出时会变,要变就麻烦了。表里加些默认的字段:insert_time,insert_user,update_time,update_user,is_update(逻辑删除)。数据库设计
6.many to many 的能够拆成 many to one ,one to many的,关联关系,有的大师说很重要,由于表的设计就是世界的关联,是,然而咱们系统有关系的也不写外键,都是独立维护,好处也有,就是性能高,测试开发方便。别的吗,逻辑容易出数据bug,知道就成。分布式
7.表少(意思是抽象度高点,别来回把数据库当仓库和垃圾堆,最后的结果不是不重视,来几我的都搅搅表都毁了),字段精,那确定是,了解越深,考虑越全,抽象越高,效果越好,性能越高,没有止境。第三范式到如今没理解在说啥,好像是又不是。工具
8.系统最基本也要弄个操做日志表(操做什么了,IP,时间什么的),运行日志表(都有了)。性能
9.这个好,系统要加入表信息表,就是表说明表(书有目录,这个能够类比书的目录,存的更有用的信息些)谁加了什么表,干吗的都维护上去,都能看见,好处不少了。(id,tab_name,insert_user,insert_time,description)
10.设计表说要减小冗余,实现字表的列转行功能,避免子拉到主表。
11.存储过程能够改善执行效率,维护时候不太可见,这个不爽。触发器有点危险,性能有影响。
范式大体理解吧:
概念的单一化,即一个关系表示一个实体。有点Java面对对象的意思。
1NF: 字段是最小的的单元不可再分
2NF:知足1NF,表中的字段必须彻底依赖于所有主键而非部分主键 (通常咱们都会作到)
3NF:知足2NF,非主键外的全部字段必须互不依赖
好像平时也没注意,都这么作的。
原文及我的注释:
当您在决定开发一个数据库管理项目时,最早着手的工做就应是数据库表结构的设计了。能够这么说,表结构的设计是开发数据库管理项目的基石,一个糟糕的表结构设计,可能会严重延误您的项目开发周期,使您大量的劳动时间为此付之东流。表结构设计是数据库逻辑设计的重要组成部分,直接影响到数据库的性能,因此小编在本文对数据库(表结构)设计技巧及注意事项作一个讲解!
1.表名通常以【模块名称_具体表名】来实现,同一个模块的前缀是同样的。(Oracle大小写敏感,在SQL中能够不用"_",由于能够用大小写一块儿的写法。这也是能够的)
2.表名称不该该取得太长(通常不超过三个英文单词,不推荐使用中文拼音,总的长度不要超过30个字符)。表名使用英文的缘由,有些项目有英文版的须要,或者这个项目是给外国作的时候,使用英文是基本的要求,应该说这是一个习惯问题,多学一点英文也不是坏事
3.不使用tab或tb做为表前缀(原本就是一个表,为何还要说明)。
4.一些做为多对多链接的表,可使用两个表的前缀做为表名:如:用户登陆表User_Login,用户分组表User_GroupInfo,这两个表创建多对多关系的表名为:User_Group_Relation(关系统一用Relation)。注意一点,主键在作其余表的外键时,或者在被其余表引用时,字段说明和字段名尽可能保持一致,好比发帖表BBS_Topic里的用户字段写成UI_ID,这样跟用户信息表User_Info的主键UI_ID保持一致,看起来舒服,对应关系很明确,也不容易错,先后不一致时容易使人费解。
5.当系统中有一些少许的,重复出现的值时,使用字典表来节约存储空间和优化查询。如地区、系统中用户类型的代号等。这类值不会在程序的运行期变化,可是须要存储在数据库中。通常数据库中,都有一个数据字典表,用来保存系统所用到的基础数据,大型的字段表如省份城市区域的字典表,统一以Dictionary_做为前缀。
6.与字段有关,默认的一些特殊字段,不少表中,好比一些业务处理表中,除了添加生成的自动编号ID(通常做为主键用),该记录建立的时间CreateDate(建立时间),该记录的建立人CreatBy(注意这里,没UI_ID(用户信息表User_Info的主键UI_ID),由于还有修改人),最后修改人LastEditBy,最后修改时间LastEditDate。(这些能够直接使用中文字符,而不使用编码,提升查询的效率)
同时有的时候须要注意,删除的时候并不真的删除该记录,而是添加一个标识位,好比XX_DeleteStaus删除状态。1是有效的,0则是无效的。
7.在命名表时,用单数形式表示名称。例如,使用Employee,而不是Employees。
8.数据库中应创建这样一个表,就是数据库自己的字段信息,表的说明,也就是数据库设计文档的一个表,方便查询使用,有什么不明的能够直接从数据库查询,数据库文档丢失,注释丢失,均可以从新起做用。
9.每一个表都应该有一个主键,这个主键最好是数字,并且是递增的,有不少表的主键用32位字符编码,这样作的目的更多的是从安全考虑的。由于字符多时索引时效率低,而使用自增列也不是不多,好比添加主表和从表操做时,主表的主键是从表的外键,这个时候还有取返回值,而后再添加,不能够同时添加。主键能够用自定义的规则,大部分用MAX(ID)的作法,也能够自定义一个序列表,有点像序列,或者用时间的年月日秒具体到毫秒。关于列的命名,建议对数据类型也作一些规范,由于很容易肯定,只有四种主要类型:数字,字符,时间,逻辑值,这些在类型上和长度上均可以定好规范,统一块儿来。
10.基本表及其字段之间的关系,应尽可能知足第三范式。可是,知足第三范式的数据库设计,每每不是最好的设计。为了提升数据库的运行效率,经常须要下降范式标准:适当增长冗余,达到以空间换时间的目的。
11.若两个实体之间存在多对多的关系,则应消除这种关系。消除的办法是,在二者之间增长第三个实体。这样,原来一个多对多的关系,如今变为两个一对多的关系。要将原来两个实体的属性合理地分配到三个实体中去。这里的第三个实体,实质上是一个较复杂的关系,它对应一张基本表。通常来说,数据库设计工具不能识别多对多的关系,但能处理多对多的关系。
12.主键PK的取值方法,PK是供程序员使用的表间链接工具,能够是一无物理意义的数字串,由程序自动加1来实现。也能够是有物理意义的字段名或字段名的组合。不过前者比后者好。当PK是字段名的组合时,建议字段的个数不要太多,多了不但索引占用空间大,并且速度也慢。
13.中间表是存放统计数据的表,它是为数据仓库、输出报表或查询结果而设计的,有时它没有主键与外键(数据仓库除外)。临时表是程序员我的设计的,存放临时记录,为我的所用。基表和中间表由DBA维护,临时表由程序员本身用程序自动维护。
14.操做日志表,登陆日志表,这是数据库中必备的两个表,这个记录也须要作进一步的保存。这个有两种情形,一是具体到单个字段的操做日志,二是整个表的操做日志。
常见的几个表具体说明:操做日志表Sys_OperateLog、登陆日志表Sys_LoginLog、系统字典表Sys_Dictionary、系统字典表类型Sys_DicType。
这样的一个操做日志比较笼统,不是能具体到具体的字段值更新,若是要具体到某个具体值的更新,则须要设计新的数据库。
通常状况下须要这样几个表,系统中可能已经有了,可是咱们拿到咱们本身的数据库中来,一个是数据库列表的表(就是数据库中有几个表)(编号,建立时间,建立人,修改时间,修改人,表名,注释,是否删除),而后就是数据库表下面的字段类型(编号,建立时间,建立人,修改时间,修改人,字段名,字段类型,字段精度,字段说明,字段注释,表的编号),也就是字段列表,这时的日志操做表能够这样设计(编号,表名,被修改的字段名,修改前值,修改后值,操做人,操做时间,相关模块,操做IP)这种能记录修改记录,可是添加和删除时记录就不是很方便控制了。
还有一个就是数据字典表,我看过不少的数据库设计,类型表一个接一个,没有放在一块儿,还有的干脆写在注释里,有的根本就没有,这样某个程序员走了,这个字段就没人知道了,即便没走,本身也有可能时间长了忘掉,因此,见一个基础数据字典表的做用很是重要,其余的好比地区表(Sys_DicArea),汉语拼音表(Sys_DicCharacter)(用来汉字和拼音的转换)由于数据量较大,单独建表。这里介绍通用的数据字典表。
最后补充一些内容,通常设计数据库是这个样子的,可是不排除有些特殊的情形,为了数据的保密性,数据库的表名和字段名都是一些看似毫无心义的字符数字,好比Table1,Col1,可是有一个表是说明表,或者有对应的数据库文档设计。
补充:一些列说明了单位类型,能够在设计数据库的时候代表,好比HeightIncm,WeightInKg.这样一目了然。
防止数据库设计打补丁的方法是“三少原则”
(1)一个数据库中表的个数越少越好。只有表的个数少了,才能说明系统的E--R图少而精,去掉了重复的多余的实体,造成了对客观世界的高度抽象,进行了系统的数据集成,防止了打补丁式的设计;
(2)一个表中组合主键的字段个数越少越好。由于主键的做用,一是建主键索引,二是作为子表的外键,因此组合主键的字段个数少了,不只节省了运行时间,并且节省了索引存储空间;
(3)一个表中的字段个数越少越好。只有字段的个数少了,才能说明在系统中不存在数据重复,且不多有数据冗余,更重要的是督促读者学会“列变行”,这样就防止了将子表中的字段拉入到主表中去,在主表中留下许多空余的字段。所谓“列变行”,就是将主表中的一部份内容拉出去,另外单独建一个子表。这个方法很简单,有的人就是不习惯、不采纳、不执行。
数据库设计的实用原则是:在数据冗余和处理速度之间找到合适的平衡点。“三少”是一个总体概念,综合观点,不能孤立某一个原则。该原则是相对的,不是绝对的。“三多”原则确定是错误的。试想:若覆盖系统一样的功能,一百个实体(共一千个属性)的E--R图,确定比二百个实体(共二千个属性)的E--R图,要好得多。
提倡“三少”原则,是叫读者学会利用数据库设计技术进行系统的数据集成。数据集成的步骤是将文件系统集成为应用数据库,将应用数据库集成为主题数据库,将主题数据库集成为全局综合数据库。集成的程度越高,数据共享性就越强,信息孤岛现象就越少,整个企业信息系统的全局E—R图中实体的个数、主键的个数、属性的个数就会越少。
提倡“三少”原则的目的,是防止读者利用打补丁技术,不断地对数据库进行增删改,使企业数据库变成了随意设计数据库表的“垃圾堆”,或数据库表的“大杂院”,最后形成数据库中的基本表、代码表、中间表、临时表杂乱无章,不可胜数,致使企事业单位的信息系统没法维护而瘫痪。
“三多”原则任何人均可以作到,该原则是“打补丁方法”设计数据库的歪理学说。“三少”原则是少而精的原则,它要求有较高的数据库设计技巧与艺术,不是任何人都能作到的,由于该原则是杜绝用“打补丁方法”设计数据库的理论依据。
在给定的系统硬件和系统软件条件下,提升数据库系统的运行效率的办法是:
(1)在数据库物理设计时,下降范式,增长冗余,少用触发器,多用存储过程。
(2)当计算很是复杂、并且记录条数很是巨大时(例如一千万条),复杂计算要先在数据库外面,以文件系统方式用C++语言计算处理完成以后,最后才入库追加到表中去。这是电信计费系统设计的经验。
(3)发现某个表的记录太多,例如超过一千万条,则要对该表进行水平分割。水平分割的作法是,以该表主键PK的某个值为界线,将该表的记录水平分割为两个表。若发现某个表的字段太多,例如超过八十个,则垂直分割该表,将原来的一个表分解为两个表。
(4)对数据库管理系统DBMS进行系统优化,即优化各类系统参数,如缓冲区个数。
(5)在使用面向数据的SQL语言进行程序设计时,尽可能采起优化算法。总之,要提升数据库的运行效率,必须从数据库系统级优化、数据库设计级优化、程序实现级优化,这三个层次上同时下功夫。
主键设计:
一、不建议用多个字段作主键,单个表还能够,可是关联关系就会有问题,主键自增是高性能的。导入导出就有问题。
二、通常状况下,若是有两个外键,不建议采用两个外键做为联合住建,另建一个字段做为主键。除非这条记录没有逻辑删除标志,且该表永远只有一条此联合主键的记录。
三、通常而言,一个实体不能既无主键又无外键。在E—R图中,处于叶子部位的实体,能够定义主键,也能够不定义主键(由于它无子孙),但必需要有外键(由于它有父亲)。
主键与外键的设计,在全局数据库的设计中,占有重要地位。当全局数据库的设计完成之后,有个美国数据库设计专家说:“键,处处都是键,除了键以外,什么也没有”,这就是他的数据库设计经验之谈,也反映了他对信息系统核心(数据模型)的高度抽象思想。由于:主键是实体的高度抽象,主键与、外键的配对,表示实体之间的链接。
数据库三范式:
概念的单一化,即一个关系表示一个实体。有点Java面对对象的意思。
一范式就是属性不可分割。属性是什么?就是表中的字段。
不可分割的意思就按字面理解就是最小单位,不能再分红更小单位了。
这个字段只能是一个值,不能被拆分红多个字段,不然的话,它就是可分割的,就不符合一范式。
不过能不能分割并无绝对的答案,看需求,也就是看你的设计目标而定。
举例:
学生信息组成学生信息表,有姓名、年龄、性别、学号等信息组成。
姓名不可拆分吧?因此能够做为该表的一个字段。
但我要说这个表要在国外使用呢?人家姓和名要分开,都有特别的意义,因此姓名字段是可拆分的,分为姓字段和名字段。
简单来讲,一范式是关系数据库的基础,但字段是否真的不可拆分,根据你的设计目标而定。
二范式就是要有主键,要求其余字段都依赖于主键。
为何要有主键?没有主键就没有惟一性,没有惟一性在集合中就定位不到这行记录,因此要主键。
其余字段为何要依赖于主键?由于不依赖于主键,就找不到他们。更重要的是,其余字段组成的这行记录和主键表示的是同一个东西,而主键是惟一的,它们只须要依赖于主键,也就成了惟一的。
若是有同窗不理解依赖这个词,能够勉强用“相关”这个词代替,也就是说其余字段必须和它们的主键相关。由于不相关的东西不该该放在一行记录里。
举例:
学生信息组成学生表,姓名能够作主键么?
不能!由于同名的话,就不惟一了,因此须要学号这样的惟一编码才行。
那么其余字段依赖于主键是什么意思?
就是“张三”同窗的年龄和性别等字段,不能存储别人的年龄性别,必须是他本身的,由于张三的学号信息就决定了,这行记录归张三全部,不能给无关人员使用。
三范式就是要消除传递依赖,方便理解,能够看作是“消除冗余”。
消除冗余应该比较好理解一些,就是各类信息只在一个地方存储,不出如今多张表中。
好比说大学分了不少系(中文系、英语系、计算机系……),这个系别管理表信息有如下字段组成:
系编号,系主任,系简介,系架构。
那么再回到学生信息表,张三同窗的年龄、性别、学号都有了,我能不能把他的系编号,系主任、系简介也一块儿存着?
若是你问三范式,固然不行,由于三范式不一样意。
由于系编号,系主任、系简介已经存在系别管理表中,你再存入学生信息表,就是冗余了。
三范式中说的传递依赖,就出现了。
这个时候学生信息表中,系主任信息是否是依赖于系编号了?而这个表的主键但是学号啊!
因此按照三范式,处理这个问题的时候,学生表就只能增长一个系编号字段。
这样既能根据系编号找到系别信息,又避免了冗余存储的问题。
所谓的范式,是用来学习参考的,设计的时候根据状况,未必必定要遵照,切记。
总结: 1NF: 字段是最小的的单元不可再分 2NF:知足1NF,表中的字段必须彻底依赖于所有主键而非部分主键 (通常咱们都会作到) 3NF:知足2NF,非主键外的全部字段必须互不依赖 ??4NF:知足3NF,消除表中的多值依赖