不定字段数目的数据库表设计和数据结构

简介:
不定字段数目的数据库表设计和数据结构

可能采用四种技术:

  1. 动态增加数据库表字段
  2. 预留足够的空白字段,运行时作动态影射
  3. 用xml格式保存在单字段里
  4. 改列为行,用另外一个表存放定制字段

现在我们来分析一下四种技术的优劣,不过首先可以排除的是第一点动态增加字段的方法,因为在实际操作时候几乎是不可能的(sqlserver太慢,oracle索性不支持),基本可以不讨论就排除。剩下后三点。

先来讨论预留空白字段的方法,基本原理就是在数据库表设计的时候加入一些多余的字段,看下面的代码:

CREATE   TABLE  Sample(
  name 
varchar ( 12 ),
  
  field0 
varchar ( 1 ),
  field1 
varchar ( 1 ),
  
  fieldN 
varchar ( 1 )
}

然后看实际运行时候的需要,动态分配字段给系统使用,也许需要一个这样的结构来描述分配情况:

public   class  Available
{
  
public int CurrentUnusedFieldNumber;
  
public Hashtable FieldToRealName;
}

也许某一时刻的数据状况是这样的: CurrentUnusedFieldNumber=3, 哈西表FieldToRealName包含内容是("field0"="SomeId", "field1"="AnyName", "field2=IsOk")

现在的问题是如果要配合Hibernate,如何来处理?以上段的数据使用状况为例子,如果我们的类定义是这样:

public   class  Entity01
{
  
public string Name;
  
public string SomeId;
  
public string AnyName;
  
public bool IsOk;
}

也许只需要修改一下xxx.hbm.xml,把 SomeId 和 field0 做成对应就ok了。但是在运行时我们怎么知道会有这样的类定义?除非我们做动态代码生成,自动编译也许可以,但是问题也许就到其他方面去了;如果我们不用动态定义,那么类就只能是这样:

public   class  Entity01
{
  
public string Name;
  
public Hashtable ExtraFieldAndValues;
}

使用的时候,用 entity01.ExtraFieldAndValues.setValue("AnyName", "boss") 的方式来引用,也许这样是修改最少的了,但是问题是Hibernate不支持这样的方法。

再来讨论单字段存储的方法,我们使用这样的数据库表定义

CREATE   TABLE  Sample
(
  Name 
varchar ( 12 ),
  Xml CLOB(
102400 //  仅作说明而已
)

然后对应这样的类定义

public   class  Entity01
{
  
public string Name;
  
public string Xml;

  
public Hashtable ExtraNameAndValueFromXml;
}

我们的代码就可以这样使用:string id = entity01.ExtraNameAndValueFromXml.getValue("SomeId") 了。这样解决看起来很不错,不仅不需要Available表,而且看起来Hibernate对它的支持也很完美,但是致命的问题在于:如果保持高效的查询?除非数据库系统本身对此有支持,否则就只能用低效的substring或者like做查询,这在大批量数据中根本就不可行。

是不是折衷一下,把两种方法的优点和起来?问题有来了:怎么保持两者之间数据的同步?难道要我们用存储过程去解析xml内容?

所以,一个两难的问题,需要我们认真去解决。我们通过认真的需求分析,也许可以减少可变字段的数量,但是只要有一个可变字段或者可变的可能性存在,我们始终要去解决这个两难的问题。

期待继续讨论。

(新增部分)

还有一种方法就是改列为行,用另外一个表存放扩展字段,定义可以如下:

CREATE   TABLE  SampleFields
(
  idSample 
Integer ,
  fieldName 
varchar ( 30 ),
  fieldValue 
varchar ( 100 )
)

其中idSample关联到Sample表的id字段(我没有写出来)。这样的话,Hibernate很容易支持,也可以支持Sql的查询,而且可以支持把内容放到Hashtable中去,看起来是目前最好的方式了。但是在大容量数据的时候,SampleFields表的数据会是主表数据量的N倍(看定制的字段数目多少而定),同样存在有很严重的性能问题。

哪位高人还能再给一个方案?

---------2005-7-22新增-----------
很多朋友给出了很好的建议,其中蛙蛙池塘 给出了一个表结构,因为看起来不甚方便,我把类图画出来如下:

图所表示的内容简单来说是这样:
1。一个很宽的表ProductAttributeValues,包含用到的几乎所有可能的类型的值,但是每次只能用一个类型的值
2。将可变的列转为行,存放到上表中
3。为了存放类型定义和一些下拉列表的内容,设计了ProductAttributeTemplates和关联的其他表
4。ProductListItems中存放Product中所有项的说明和顺序。

这种思路其实就是把产品的“知识级”(设计模式用语)和“操作级”都表现出来了,如果要划分,则图的左上角三个表属于“操作级”,其余的属于“知识级”。
wljcan 网友建议我去看《设计模式》的“观察模式”,我发现上图其实就是一种和“观察模式”相似的设计。《设计模式》看了很久都没能看下去,不过这几天正在看“观察模式”,等有心得了,再来看看能不能对上图的结构修改一下。

怡红公子 提醒说oracle和sql server对xml字段其实已经不错了,所以找了一下,但是真的是既产品中恐怕还是不敢用,不知道性能如何。虽然采用xml方式是我最推崇的方法。而且一旦采用xml方式存储,恐怕就会有changyu 网友提醒的数据类型问题,要存一个图片的话恐怕就歇菜了(当然也不是说xml中就一定不能存图片)。

不过我现在觉得xml字段还是要的,作为辅助存储手段,因为毕竟未来查询起来可能会更方便些,然后结合“观察模式”也就是类似上图的方法作为主要的存储手段,虽然有一些冗余,结合我的
使用 NVelocity 解析 PowerDesigner 的cdm文件 ,工作量也不会太大。

再研究研究看看。


本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/archive/2011/04/15/2017009.html,如需转载请自行联系原作者


目录
相关文章
|
9月前
|
存储 搜索推荐 关系型数据库
深度探讨数据库索引的数据结构及优化策略
深度探讨数据库索引的数据结构及优化策略
|
9月前
|
存储 SQL 关系型数据库
关系型数据库数据结构化存储
【5月更文挑战第8天】关系型数据库数据结构化存储
115 6
|
5月前
|
前端开发 数据库
数据库表设计生成代码
BizWorks ToolKit插件集成Mybatis-Plus代码生成工具,支持从数据库表生成代码,便于研发过程中数据模型变更后的代码同步。本文介绍批量生成代码的方法、配置说明及项目示例。配置文件`*.mp.yaml`用于描述生成行为,可放置于`src/main/resource/bizworks/mybatis-plus/`路径下。配置包括数据库信息、输出目录及包名等。通过IDEA右键菜单即可启动代码生成。具体配置和示例详见文档。
56 2
|
9月前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
601 0
|
5月前
|
前端开发 数据库 开发者
数据模型(数据库表设计)生成代码
BizWorks ToolKit 插件集成 Mybatis-Plus 代码生成工具,支持从数据库表批量生成代码,简化开发流程。本文详细介绍配置方法及项目示例,包括配置文件格式、生成选项及具体操作步骤,帮助开发者快速实现代码同步更新。配置文件 `.mp.yaml` 支持自定义输出目录、生成组件等,适用于多种项目结构。
68 0
|
6月前
|
存储 SQL 数据库
数据库与数据结构设计
数据库与数据结构设计【8月更文挑战第22天】
68 0
|
7月前
|
SQL 自然语言处理 网络协议
【Linux开发实战指南】基于TCP、进程数据结构与SQL数据库:构建在线云词典系统(含注册、登录、查询、历史记录管理功能及源码分享)
TCP(Transmission Control Protocol)连接是互联网上最常用的一种面向连接、可靠的、基于字节流的传输层通信协议。建立TCP连接需要经过著名的“三次握手”过程: 1. SYN(同步序列编号):客户端发送一个SYN包给服务器,并进入SYN_SEND状态,等待服务器确认。 2. SYN-ACK:服务器收到SYN包后,回应一个SYN-ACK(SYN+ACKnowledgment)包,告诉客户端其接收到了请求,并同意建立连接,此时服务器进入SYN_RECV状态。 3. ACK(确认字符):客户端收到服务器的SYN-ACK包后,发送一个ACK包给服务器,确认收到了服务器的确
223 1
|
8月前
|
关系型数据库 MySQL 数据库
关系型数据库MySQL开发要点之多表设计案例详解代码实现
关系型数据库MySQL开发要点之多表设计案例详解代码实现
97 2
|
7月前
|
存储 SQL 关系型数据库
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
|
8月前
|
弹性计算 负载均衡 NoSQL
NoSQL数据库如何支持动态数据结构?
【6月更文挑战第11天】NoSQL数据库如何支持动态数据结构?
67 2

热门文章

最新文章