数据库设计之存储多值的问题

存储多值的问题在设计数据库时是很普遍的问题,看到很多开发人员在上面吃了亏,我觉得有必要拿出来说。

业务场景:一个业务单据,有多个联系人。一个设备维护工作,有多个维护班组。下面来举个例子

createtable BILL

(

bill_id numberprimarykey,

bill_name varchar2(20),

bill_contentvarchar2(200),

contact_idnumber--来至于user表的user_id

);

1. 在起初的设计中,联系人只有一个,后来需求有变化了,联系人又多个。有几种方案:

方案一:在加几个字段,contact_id1,contact_id2,contact_id3...。

方案二:吧contact_id的number类型改为varchar2,多值一起存储,值与值之间用分割符隔开(如逗号)。

方案三:再加一张表bill_contact

createtable bill_contact

(

bill_id number,

contact_idnumber

);

altertable BILL_CONTACT

addconstraint pk_bill_contactprimarykey
(BILL_ID,CONTACT_ID);

2. 对比几个方案

方案一显然不合适,不知道建几个字段合适,就算知道最多有几个联系人,查询起来也很麻烦。查询单中包含联系人100和101的记录,

select *from bill_contact

where (contact_id =100and
contact_id1 =101)

or (contact_id =101and contact_id1
=100);

查询单中包含联系人100的记录,

select *from bill_contact

where (contact_id =100or
contact_id1 =101 or….);

方案二的优点在于方便,开发人员只需要改动少量的代码,普遍被开发人员采纳。a. 但好景不长,分析、统计功能非常难做,如需要列出在某一段时间内某一位联系人的所有单据;统计出每张单据联系人的数目等。

b. 查询也会变得不高效,类型不一致导致隐式转换,索引失效。

c. 修改起来复杂,需要额外在代码中写一段逻辑处理。

d. 有的系统主键用的是32位UUID,如果联系人又10位,那这个字段长度得是500,有点恐怖。

select *from bill_contact

where contact_idlike‘100,%‘

or contact_id like‘%,100‘

or contact_id like‘%,100,%‘;

早前针对这种问题我专门写过优化的方案,数据库设计中单个字段多值的处理

方案三恰好是弥补了方案二的众多确定,开发人员总是担心表关联的性能太差,其实是多余的,因为此时能走到索引。还有一个好处就是可以对联系人的信息进行扩展,如是第一联系人,还是第二联系人,这是方案二无法实现的。改造对于开发人员来说工作量比方案二要大。

select *from bill_contact a, bill_contact b

where a.bill_id = b.bill_id

and b.contact_idin (100,101);

3. 多值的问题如何抉择呢?

方案一肯定是不要选的。

方案二适合于对多值列没有分析统计,没有查询。

方案三是我心中理想的方案,虽然它可能会造成一些工作量。

时间: 2024-10-11 07:36:52

数据库设计之存储多值的问题的相关文章

一个缺陷管理系统数据库设计和界面设计分析

在Winform方面,基于业务的不同,我们可以利用工具的效率,快速做很多不同的业务系统,前期做了一个缺陷管理系统,想把单位的测试业务规范下,也好统计和分析每个版本的缺陷信息,本篇整理这些数据库设计和界面设计的相关内容,做一个介绍,希望给大家一个对比参照的案例进行学习了解. 1.缺陷管理系统的业务分析 在很多缺陷管理系统里面,我们往往需要管理的就是缺陷信息的记录,以及缺陷记录的开闭过程,从而实现了测试人员->开发人员->测试人员的整个闭环过程. 一般情况下,缺陷管理系统可以部署在局域网内,或者公

SQL SERVER学习2——数据库设计

数据库设计是数据库知识中比较重要的部分,我们需要了解数据库设计的基本步骤,E-R图的画法. 数据库设计的基本概述 检验一个数据库设计好坏的标准就是,看他是否能够方便的执行各种数据检索和处理操作,并且有利于数据的控制管理和维护. 数据库设计步骤 设计数据库规范中比较著名的是"新奥尔良方法"(这个可不是做新奥尔良鸡腿的方法哦),Now Orleans,总计4个阶段: 需求分析(分析用户要求,制作数据流图和判定图) 概念结构设计(信息分析和定义,制作E-R图) 逻辑结构设计(设计实现,关系型

数据库设计之EAV(实体、属性、值)

有这么一个业务,用于客户记录每天做的事情,由于是非常专业的事情,需要专业的记录本,这种记录本有20多种.实际工作中也是有20多样的记录本,记录本的格式每隔一年会有点变动.如何进行数据库设计?    有两种方案: 1.为每个记录本建单独的表. 2.动态表,把记录本的属性放入到字典中,记录本的内容以实体.属性.值的形式存储.    --存储记录本的格式 createtable note_dictionary ( dictionary_id number, dictionary_type varcha

数据库设计之半结构化存储

业务场景:用户填一些单据,然后上报,完成审批.单据中有几个字段是需要统计的,业务并不复杂. 看似简单的场景,当开发人员拿出PDM设计的时候,我惊呆了,密密麻麻的有接近70张表,每张表都是一百多个字段.开发人员抱怨,花了一周的时间来做数据库设计,实在是太麻烦了. 设计方案1,我问能不能把单据进行归类,一类单据设计成一张表,用一个字段区分是那张单据,这样会减少很多表.得到的回复是,没法归类,方案1行不通. 设计方案2,做个Excel模板,审批的时候就在excel上审批,问题是有字段要做统计,行不通.

从零开始编写自己的C#框架(9)——数据库设计与创建

对于千万级与百万级数据库设计是有所区别的,由于本项目是基于中小型软件开发框架来设计,记录量相对会比较少,所以数据库设计时考虑的角度是:与开发相结合:空间换性能:空间换开发效率:减少null异常......当然不同的公司与项目要求不同,初学者要学会适应不同的项目开发要求,使用本框架开发时,必须严格按照本章节的要求来设计数据库,不然可能会产生不可控的异常. 从零开始编写自己的C#框架 数据库设计规范   文件状态: [√] 草稿 [  ] 正式发布 [  ] 正在修改 文件标识: C#框架 当前版本

数据库设计的三大范式

数据库设计的三大范式 为了建立冗余较小.结构合理的数据库,设计数据库时必须遵循一定的规则.在关系型数据库中这种规则就称为范式.范式是符合某一种设计要求的总结.要想设计一个结构合理的关系型数据库,必须满足一定的范式. 在实际开发中最为常见的设计范式有三个: 1.第一范式 第一范式是最基本的范式.如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式. 第一范式的合理遵循需要根据系统的实际需求来定.比如某些数据库系统中需要用到"地址"这个属性,本来直接将"

机房收费系统——数据库设计说明书

GB8567--88 数据库设计说明书 1      引言 优质数据库在处理大数据的程序或系统中是有非常重要的作用的,所以对于数据库的设计有很多的要求和规定.首先数据库要有很好的可维护性.灵活性,并且数据库的算法逻辑性也要有一定的优化性,这样可以对资源进行有效利用,并且处理数据的时间也会缩短. 1.1   编写目的 由于上机的人越来越多,产生的上机数据越来越多,原始的保存方式已经不能满足数据存储的需要,所以使用数据库对各种记录进行存储.并且数据库可以节省很多的资源,如人力.时间.空间等. 数据库

数据库设计 Step by Step (2)——数据库生命周期

引言:数据库设计 Step by Step (1)得到这么多朋友的关注着实出乎了我的意外.这也坚定了我把这一系列的博文写好的决心.近来工作上的事务比较繁重,加之我期望这个系列的文章能尽可能的系统.完整,需要花很多时间整理.思考数据库设计的各种资料,所以文章的更新速度可能会慢一些,也希望大家能够谅解. 系列的第二讲我们将站在高处俯瞰一下数据库的生命周期,了解数据库设计的整体流程 数据库生命周期 大家对软件生命周期较为熟悉,数据库也有其生命周期,如下图所示. 图(1)数据库生命周期 数据库的生命周期

数据库设计中主键问题

转自: http://www.jb51.net/article/40933.htm 数据库主键在数据库中占有重要地位.主键的选取策略决定了系统是否可靠.易用.高效.本文探讨了数据库设计过程当中常见的主键选取策略,并剖析了其做主键的优缺点,提出了相应的解决问题的方法 在基于关系型数据库设计时候,通常要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行记录的属性或属性组,一个表只能有一个主键,但可以有多个候选索引.因为主键可以唯一标识某一行记录,所以可以确保执行数据更新.删除.修改时不出现错误