不定字段数目的数据库表设计和数据结构
可能采用四种技术:
- 动态增加数据库表字段
- 预留足够的空白字段,运行时作动态影射
- 用xml格式保存在单字段里
- 改列为行,用另外一个表存放定制字段
现在我们来分析一下四种技术的优劣,不过首先可以排除的是第一点动态增加字段的方法,因为在实际操作时候几乎是不可能的(sqlserver太慢,oracle索性不支持),基本可以不讨论就排除。剩下后三点。
先来讨论预留空白字段的方法,基本原理就是在数据库表设计的时候加入一些多余的字段,看下面的代码:
CREATETABLESample(
varchar(12),
varchar(1),
varchar(1),
varchar(1)
然后看实际运行时候的需要,动态分配字段给系统使用,也许需要一个这样的结构来描述分配情况:
publicclassAvailable
{
public int CurrentUnusedFieldNumber;
public Hashtable FieldToRealName;
也许某一时刻的数据状况是这样的: CurrentUnusedFieldNumber=3, 哈西表FieldToRealName包含内容是("field0"="SomeId", "field1"="AnyName", "field2=IsOk")
现在的问题是如果要配合Hibernate,如何来处理?以上段的数据使用状况为例子,如果我们的类定义是这样:
publicclassEntity01
{
public string Name;
public string SomeId;
public string AnyName;
public bool IsOk;
也许只需要修改一下xxx.hbm.xml,把 SomeId 和 field0 做成对应就ok了。但是在运行时我们怎么知道会有这样的类定义?除非我们做动态代码生成,自动编译也许可以,但是问题也许就到其他方面去了;如果我们不用动态定义,那么类就只能是这样:
publicclassEntity01
{
public string Name;
public Hashtable ExtraFieldAndValues;
使用的时候,用 entity01.ExtraFieldAndValues.setValue("AnyName", "boss") 的方式来引用,也许这样是修改最少的了,但是问题是Hibernate不支持这样的方法。
再来讨论单字段存储的方法,我们使用这样的数据库表定义
CREATETABLESample
varchar(12),
102400) //仅作说明而已
然后对应这样的类定义
publicclassEntity01
{
public string Name;
public string Xml;
public Hashtable ExtraNameAndValueFromXml;
我们的代码就可以这样使用:string id = entity01.ExtraNameAndValueFromXml.getValue("SomeId") 了。这样解决看起来很不错,不仅不需要Available表,而且看起来Hibernate对它的支持也很完美,但是致命的问题在于:如果保持高效的查询?除非数据库系统本身对此有支持,否则就只能用低效的substring或者like做查询,这在大批量数据中根本就不可行。
是不是折衷一下,把两种方法的优点和起来?问题有来了:怎么保持两者之间数据的同步?难道要我们用存储过程去解析xml内容?
所以,一个两难的问题,需要我们认真去解决。我们通过认真的需求分析,也许可以减少可变字段的数量,但是只要有一个可变字段或者可变的可能性存在,我们始终要去解决这个两难的问题。
期待继续讨论。
(新增部分)
还有一种方法就是改列为行,用另外一个表存放扩展字段,定义可以如下:
CREATETABLESampleFields
Integer,
varchar(30),
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文件 ,工作量也不会太大。
再研究研究看看。
不定字段数目的数据库表设计和数据结构相关推荐
- mysql 字段数量不确定_不定字段数目的数据库表设计和数据结构 | 学步园
两难的境界:不定字段数目的数据库表设计和数据结构 昨天项目组会议上讨论的关于不定字段数目的数据库表问题并没有结果,今天继续分析之后发现问题可能还更大.当时讨论的结果是可能采用四种技术: 动态增加数据库 ...
- 两难的境界:不定字段数目的数据库表设计和数据结构
http://www.cnblogs.com/BigTall/archive/2005/07/15/193401.html http://hi.baidu.com/rafale88/blog/item ...
- 【转】如何设计动态(不定)字段的产品数据库表?
因为最近要用到设计动态量表的功能,找了一篇技术上实现动态设计表字段的文章,借来用用. 原文地址:http://blog.sina.com.cn/s/blog_85295a390101dou0.html ...
- 如何设计动态(不定)字段的产品数据库表?--淘宝多产品属性字段设计方法
看到szsm博客,觉得他分析的很不错,这里把他的资料整理一下 --------------------------------------------------------------------- ...
- MySQL数据库表设计
MySQL数据库表设计 数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要 ...
- Oracle数据库表设计时的注意事项
Oracle数据库表设计时的注意事项 表是Oracle数据库中最基本的对象之一.万丈高楼从平地起,这个基础对象对于数据库来说,非常重要.因为其设计是否合理,直接跟数据库的性能相关.从Oracle数据 ...
- mysql设计积分兑换表_积分系统数据库表设计.docx
积分系统数据库表设计 文件编号:JHDZ/SJ 密 级: 云上城积分功能数据库设计文档 项目名称:<云上城>项目代号:XXX版 本:V1.0编制单位:平台运营编制日期:2014-10-08 ...
- 数据库表设计、 数据库分层、myslq水平拆分、oracle表分区
数据库表设计 数据库表结构设计方法及原则(li)数据库设计的三大范式:为了建立冗余较小.结构合理的数据库,设计数据库时必须遵循一定的规则.在关系型数据库中这种规则就称为范式.范式是符合某一种设计要求的 ...
- 万字归纳总结 | 数据库表设计与SQL编写技巧
点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"加入公众号专属技术群 前言 随着移动云平台系统业务不断增长,必然需要对各系统进行 ...
最新文章
- MVC实现简单的上传功能
- 浅谈线程池(上):线程池的作用及CLR线程池
- 在自己的网页添加谷歌地图
- Spring4.2.6+SpringMVC4.2.6+MyBatis3.4.0 整合
- zabbix监控suse linux,SuSE 系统之部署 Zabbix 监控服务
- arm 交叉编译找不到so_嵌入式杂谈之交叉编译
- git ssh创建分支_【ssh简单版git-server 1】自建git-server
- shell脚本单词去重多个文件
- 浏览器的DNS缓存查看和清除
- 安装mysql5.7,如何将之前mysql的数据库导入
- 阿里云成长记的一篇文章《阿里云的这群疯子》
- IDEA文件编码格式修改为UTF-8
- 代码大全 服装尺寸图html,最全服装尺码对照表
- 【服务器数据恢复】IBM某型号服务器RAID5磁盘阵列数据恢复案例
- linux上使用drive从google drive 下载文件和文件夹
- 毕业设计-基于微信小程序房屋安全管理系统
- [python]用爬虫下载某站小说并生成epub格式电子书(用mkepub库)
- python实现共轭梯度算法
- List<Map,Object>>怎样取出map集合中的某一个的key值?
- java滑雪,AcWing 901. 滑雪-java
热门文章
- C++实现选择排序(附完整源码)
- C++数组与指针的区别
- C++有哪些性质(面向对象特点)
- QT的QStack类的使用
- 经典C语言程序100例之七八
- Python——sys.stdout.flush()方法的作用
- android自定义url协议,Android自定义URL方案…?
- 02_Flink vs storm vs SparkStreaming、Flink vs storm对比图、实时框架如何选择
- 1、django安装,问题,创建项目,编写第一个demo
- 在 MySQL 中使用 explain 查询 SQL 的执行计划(转自: 数据分析与开发)