
数据库设计
文章平均质量分 83
深圳gg
这个作者很懒,什么都没留下…
展开
-
字段类型设计与实际业务不符引发的问题1
在表的设计过程中,开发人员总是对字段的类型不以为然,下面来演示一个例子,按照应该设计为number的,结果设计成了varchar2,那会导致什么问题呢?下面我们来做一个实验。SQL> create table test(id varchar2(10));表已创建。SQL> declare 2 i number; 3 begin 4 for i in 1.原创 2013-06-07 16:10:19 · 1521 阅读 · 0 评论 -
数据库设计--数据的垂直拆分
如果表字段太多,如果表中有些字段比较大,即便是你只查有限的几个字段,在做表关联和全表扫的时候,由于扫描的数据块多,性能方面还是会不理想。因为oracle扫描的时候是按照块为单位扫描,读取的时候也是按块为单位读取,所以这种功能无法在SQL层面上优化的时候,可以考虑做数据的垂直切分,下面来做个试验:--制造数据不做垂直切分create table test( a number,原创 2014-05-29 14:27:37 · 1649 阅读 · 1 评论 -
数据库设计之存储多值的问题
存储多值的问题在设计数据库时是很普遍的问题,看到很多开发人员在上面吃了亏,我觉得有必要拿出来说。业务场景:一个业务单据,有多个联系人。一个设备维护工作,有多个维护班组。下面来举个例子createtable BILL( bill_id numberprimarykey, bill_name varchar2(20), bill_contentvarchar2(200原创 2014-09-22 09:17:21 · 6575 阅读 · 3 评论 -
Oracle数据库设计字段类型选择错误的隐患
数据类型不准确的一个隐患,下面来构造一张表存日期字段,一个存varchar2,一个存date,做一个测试。之前也写过两篇blog:1.字段类型设计与实际业务不符引发的问题1 2.字段类型设计与实际业务不符引发的问题2 SQL> drop table test purge;SQL> create table test as select to_char(to原创 2014-09-11 19:17:56 · 1850 阅读 · 0 评论 -
数据库设计中的14个技巧
下述十四个技巧,是许多人在大量的数据库分析与设计实践中,逐步总结出来的。对于这些经验的运用,读者不能生帮硬套,死记硬背,而要消化理解,实事求是,灵活掌握。并逐步做到:在应用中发展,在发展中应用。 1. 原始单据与实体之间的关系 可以是一对一、一对多、多对多的关系。在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体。在特殊情况下,它们可转载 2014-09-11 15:35:46 · 986 阅读 · 0 评论 -
数据库设计之外键的思考
关于是否使用外键在业界也没有统一的标准,大家争论的焦点是数据一致性和性能上。 支持使用外键方,强调如果不使用外键,数据一致性无法保证,性能消耗可以忽略。 反对使用外键方,数据一致性可以通过程序保证,性能有大问题,数据维护很麻烦,如果是大系统,整个外键的关系就像编制的一张大网。再者开发人员很难真正用好外键。 其实两种观点我都支持,现状是我基本没用过外键。没使用外键会出现原创 2014-09-23 19:51:39 · 1792 阅读 · 0 评论 -
数据库设计之主键的思考
根据第二范式,主键是必须的。主键还是是唯一的,主键也被作为外键引用建立表和表之间的关系。从这几个方面讨论主键(数据库是Oracle): 1.主键的命名 最近看到由于架构使用hibernate的原因,导致所有主键的命名是ID,我觉得非常糟糕,如部门表(department),用户表(user),角色表(role),这些表如果关联都是id之间关联,非常难辨认这个叫ID是那张表的,如原创 2014-09-23 18:06:35 · 1962 阅读 · 3 评论 -
数据库设计之EAV(实体、属性、值)
有这么一个业务,用于客户记录每天做的事情,由于是非常专业的事情,需要专业的记录本,这种记录本有20多种。实际工作中也是有20多样的记录本,记录本的格式每隔一年会有点变动。如何进行数据库设计? 有两种方案: 1.为每个记录本建单独的表。 2.动态表,把记录本的属性放入到字典中,记录本的内容以实体、属性、值的形式存储。 --存储记录本的格式 createta原创 2014-09-26 09:39:09 · 9156 阅读 · 0 评论 -
数据库设计之半结构化存储
业务场景:用户填一些单据,然后上报,完成审批。单据中有几个字段是需要统计的,业务并不复杂。 看似简单的场景,当开发人员拿出PDM设计的时候,我惊呆了,密密麻麻的有接近70张表,每张表都是一百多个字段。开发人员抱怨,花了一周的时间来做数据库设计,实在是太麻烦了。 设计方案1,我问能不能把单据进行归类,一类单据设计成一张表,用一个字段区分是那张单据,这样会减少很多表。得到的回复是原创 2014-09-28 09:33:04 · 2158 阅读 · 0 评论 -
不用触发器的理由
TOM说过他希望三样东西不曾存在:触发器,自治事务,WHEN OTHERS。 现在开发用的触发器都是表上的,FORM上的触发器是另一种东西,该用就用。每个触发器都是一个隐藏的存储过程。隐藏的代码对开发者很不友好。如果你正在看一段别人的程序,总觉得少了点什么,折腾半天原来还有些动作隐藏在触发器里!顺藤摸瓜去找了触发器,发现里面对其他表有DML,又有其他隐藏代码,是不是头很大?这种连原创 2013-08-02 09:17:03 · 5739 阅读 · 0 评论 -
数据库三范式最简单最易记的解释
书上讲了好多, 归结起来3句话:1NF:字段不可分;2NF:有主键,非主键字段依赖主键;3NF:非主键字段不能相互依赖;解释:1NF:原子性 字段不可再分,否则就不是关系数据库;2NF:唯一性 一个表只说明一个事物;3NF:每列都与主键有直接关系,不存在传递依赖;不符合第一范式的例子(关系数据库中create不出这样的表):表:字段1,转载 2014-02-21 08:58:22 · 1158 阅读 · 0 评论 -
首页排行榜的方案设计
经常会遇到这样的业务,用户进入首页之后,显示某排行榜: 总排行 本周 本月 本年 5年来 10年来或者在首页显示自系统使用以来的库存周转率等。 开发人员不管三七二十一,直接写一条SQL搞定,随着时间的推移,统计SQL越来越慢,当并发量大了之后,整个系统就快挂了。 这种业务怎么处理。最好是用中间表的方案,查统计结果即可。采用定时任务,将统计结果插入中间表。 实现的时候要注意,原创 2018-01-19 17:04:15 · 1905 阅读 · 0 评论 -
Oracle外键不加索引引起死锁
--创建一个表,此表作为子表create table fk_t as select *from user_objects;delete from fk_t where object_id is null; commit;--创建一个表,此表作为父表create table pk_t as select *from user_objects;delete from p原创 2014-05-13 15:10:18 · 2095 阅读 · 0 评论 -
数据库设计规范
数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求)。 一、数据库设计的原则1. 表设计原则(1)规范化与反规范化规范化的优点是减少了数据冗余,节约了存储空间,相应逻辑和物理的I/O次数减少,同时加快了增、删、改的速转载 2014-03-26 09:15:00 · 1005 阅读 · 0 评论 -
复合索引的前导列如何选择?
在表上建复合索引是常见的事情,那索引中键值的顺序是什么呢?通过下面的实验可以得出三个结论:--制造实验数据,并收集统计信息SQL> create table test as select * from dba_objects;SQL> create index ind_id_owner on test(object_id,owner);SQL> create index ind_o原创 2013-09-18 09:51:48 · 3768 阅读 · 0 评论 -
字段类型设计与实际业务不符引发的问题2
开发组同事发了一条SQL语句,说执行报错ORA-017220: 无效数字。 我看了下语句,没有类型转换的函数,判断一定是发生了隐形的类型转换。果然,查到一张表的字段有为null,有空格,有'/',由于发生了隐身转换,所以报错。 问题是解决了,但为什么造成这种问题呢,是我们的程序写的不好,页面端控制不严。这不是根源,根源是在做数据库设计的时候就要把握字段的类型,要让这原创 2013-06-07 18:35:24 · 1551 阅读 · 0 评论 -
数据库设计中单个字段多值的处理
在数据库设计中,有一种情况是比较头痛的,就是一条业务数据有一个字段是多个值拼起来的,如一个设备有多个维护部门。create table devcie( devcie_id number, vindicate_dept_id varchar2(100));insert into devcie values(1,'11');insert into devcie原创 2013-11-07 09:39:31 · 9045 阅读 · 2 评论 -
都是大字段clob设计不合理惹的祸
今天开发组的同事找到我,说查一张小表4587条记录,18个字段需要12s,简直不敢相信。SQL> select * from cfms_questions;已选择4587行。已用时间: 00: 00: 11.52执行计划----------------------------------------------------------Plan hash value:39原创 2013-12-27 09:07:10 · 5093 阅读 · 0 评论 -
外键不加索引引起的性能问题
外键不加索引会造成什么问题呢,下面在做个实验:SQL> drop table t_primary purge;SQL> drop table t_foreign purge;SQL> create table t_primary(id number(10) primary key);SQL> create table t_foreign(fid number(10) refere原创 2014-02-09 18:14:50 · 2270 阅读 · 0 评论 -
表设计字段最佳顺序及试验
最佳顺序是:查询经常使用的字段放在前面。 一个数据块中包含若干记录,记录中每个字段有不同的大小,所以每个字段包含两部分。前一部分是数据的长度,后一部分是数据本身。数据库引擎不知道一条记录中每个字段的偏移量,如果需要定位字段3,必须从字段1开始,接着根据字段1的长度定位到字段2。最后,根据字段2的长度来定位字段3。无论何时一条含有多个字段的记录,靠近记录开始的地方的字段定位的速度会明显快原创 2013-05-03 16:40:26 · 2584 阅读 · 0 评论 -
表设计避免使用保留字
v$reserved_words中记录的都是关键字和保留字,reserved字段内容是Y表示这个保留字在标识符中使用。下面来做个试验,创建时会报错,要想创建成功,需要加双引号。对于reserved为N的关键字,也可能会触发Oracle的bug,所以避免使用是最好的选择。 SQL> select * from v$reserved_words wherekeyword='SIZE';KE原创 2013-09-01 20:49:52 · 1612 阅读 · 0 评论 -
数据库设计中char和long两种类型不要选择
如果用char,问题非常多:1.可能浪费空间,除非正好放满。2.会导致程序员在字段前使用trunc等截掉尾部空格的函数,要优化必须建立一些函数索引。写程序还要用rpad之类的函数。3.如果char很大,很可能导致索引无法建立。4.长度一变,经常要修改程序。5.导致程序使用大量的非绑定变量。这个可能更开发语言有关,例子: c_id=‘1212’ 可以查询到结果原创 2014-03-17 16:08:32 · 2108 阅读 · 0 评论 -
clob加||隐式转换造成的性能问题
CLOB在隐式类型转换的时候,会消耗这么多的current mode read和 consistent read(同时也会引起db block change,db block gets 的飙升),也就是CPU飙升。SQL> drop table t_clob;SQL> create table t_clob(id number,cb clob);SQL> insert into t原创 2014-03-18 09:41:50 · 1704 阅读 · 0 评论 -
varchar和varchar2的区别
目前没有区别,但官方文档不支持使用varchar,强烈建议使用varchar2。 1. varchar2是oracle提供的独特的数据类型,oracle保证在任何版本中该数据类型向上和向下兼容。但不保证varchar,这是因为varchar是标准sql提供的数据类型,有可能随着sql标准的变化而改变。 2. 如果数据库不移植的话,就没有区别。如果数据要移植到别的数据库,原创 2013-01-14 20:17:40 · 8367 阅读 · 0 评论 -
数据的水平切割
早前公司有个大系统没有做数据的水平切割,导致后续的性能优化不能做到最佳,有些功能优化到7s,8s就无法继续了。这个大系统以前是分21个点部署,然后进行了大集中,只部署了一个点。 1. 在做数据的水平分割之前一定要理解系统的业务。我的系统是MIS,数据可以分为两类:一类是基础数据,一类是业务流程数据。基础数据的理解就是支撑其他业务流转的数据,如部门、人员、权限、资源库等。业务流程数据原创 2014-05-04 11:43:17 · 1504 阅读 · 0 评论 -
传统项目消息中心的设计注意的地方
今天有一条SQL占用系统负载很高,IO负载占用了30%。功能是用户登陆之后,显示未读消息的数量。由于只要点系统的功能都会查这条SQL。导致上午4个小时调用了10万次。 SELECT COUNT(1) FROM WORKBENCH_MES T1, WORKBENCH_MES_REL T2 WHERE T1.MES_ID = T2.MES_ID AND T2.RECIPIENT_ID = ...原创 2018-02-08 11:44:04 · 3286 阅读 · 0 评论