瘦数据模型是一种最为臭名昭著并且问题多多的对关系数据库系统的滥用。不幸的是,有时又的确需要瘦数据模型。所谓瘦数据模型,就是简单地将每张表都设计为一种通用数据结构,用于存储名值对的集合。这非常像Java中的属性文件。有时这些表也可用于存储元数据,例如期望的数据类型等。这是必要的, 因为数据库只允许一列有一种类型定义。要更好地理解瘦数据模型,考虑下面这个典型的地址数据的示例,如表1-2所示。

表1-2典型模型中的地址数据

ADDRESSJD

STREET

CITY

STATE

ZIP

COUNTRY

1

123 Some Street

San Francisco

California

12345

USA

2

456 Another Street

New York

New York

54321

USA

很显然这个地址数据表可以进一步规I范化。例如,可以创建COUNTRY (国家)、STATE (州)、 CITY (城市)和ZIP (邮编)这样的关联表。但当前这样一个设计对于大多数应用程序来说既简
单又高效,已经足够了。除非你的需求的确非常复杂,否则这个模型应该不会有任何问题。

还是使用以上的数据,

如果将它们放入一个瘦数据模型对应的表中,

结果将如表1-3所示。

表1-3瘦数据模型中的地址数据

ADDRESSJD

FIELD

VALUE

1

STREET

123 Some Street

1

CITY

San Francisco

(续)

ADDRESS ID

FIELD

VALUE

1

STATE

California

1

ZIP

12345

1

COUNTRY

USA

2

STREET

456 Another Street

2

STATE

New York

2

ZIP

54321

2

COUNTRY

USA

这样的设计绝对是场噩梦。首先,没有任何可能对它进一步规范化了,虽然当前的模型只能 算作第一范式。其次,没有任何机会创建与COUNTRY表、CITY表、STATE表或ZIP表的关联关系了,因为我们不可能在同一列上定义多个外键。再次,如果希望执行一条涉及多个地址字段(例如,执行一个以街道和城市作为查询条件的查询语句)的“样例查询”,这样的数据实在让人头痛,它可能需要一大堆复杂的子查询。再看看更新的情况,这样的设计就性能来说也特别糟糕, 仅仅是插入一个地址就需要在同一张表上执行5条插入语句。这种情况下出现锁竞争甚至死锁的 可能性也大大增加了。此外,这个瘦数据模型中记录的数量整整是我们的规范化数据模型的5倍。 由于记录数量过大,又缺少明确的数据定义,而且更新一条记录时需要的更新语句过多,创建有 效的索引也是不可能的了。

不用再多说了,这个设计确实问题多多,我们为何要不惜一切代价避免这样的设计,原因已经再明白不过了。但话说回来,这个设计也不是毫无用处,它唯一的用武之地就在于那些需要动态字段的应用程序。有些应用程序的确有这样的需求,它允许用户对他们的记录添加额外的数据。 如果用户希望能定义新的字段,然后在应用程序运行时动态地把数据插入到这些字段中,那么这样的模型就可以工作得很好。也就是说,所有的已知数据还是应该正确地规范化,而这些额外的动态字段则可以通过关联关系与这些已知数据建立父子关系。这样的设计同样存在我们之 前讨论过的所有问题,但它们被最小化了,因为大部分数据(很可能是那些最重要的数据)都 己经被正确地规范化了。

即使在一个企业数据库中遇到了瘦数据模型,MyBatis也可以帮助你处理它。要将若干个类映射为瘦数据模型是非常困难的,甚至是根本不可能的,因为你连数据模型中可能存在哪些字段都 无法明确。此时你最好将这样的类映射为一个散列表(hashtable),而幸运的是iBATIS支持这种 映射。使用MyBatis,你不必将每一张表都映射为一个用户定义的类。MyBatis允许你将关系数据映 射为Java基本类型(primitive)、Map实例、XML还有用户定义类(如JavaBean)。这种巨大的灵 活性使得iBATIS对于包括瘦数据模型在内的复杂数据模型非常有效。

MyBatis被设计为一个混合型解决方案,它并不试图解决所有的问题,相反它只希望能解决那些最重要的问题。MyBatis从各种数据库访问工具中汲取了大量的优秀思想。像存储过程一样,所有的MyBatis语句都有一个签名,定义了语句的名字和输入输出(封装)。与内联SQL类似,MyBatis允许SQL语句按照其最自然的方式书写,并且可以直接使用语言中的变量作为输入输出参数和结 果。像动态SQL—样,MyBatis允许在运行时修改SQL。这样的查询语句可以根据用户的请求动态 构建。从对象/关系映射工具中,MyBatis借用了许多概念,包括高速缓存、延迟加载,还有更高 级的事务管理。

在一个应用程序的架构中,MyBatis适用于持久层。MyBatis也通过提供一些特性来支持其他层, 这些特性使得对所有这些层的需求的实现都变得更加容易。例如,一个Web搜索引擎可能需要搜 索结果的分页列表。MyBatis支持这种特性,因为它允许査询时指定返回结果的偏移量和行数量。这就使得分页操作可以在一个较低的层次上执行,同时保持数据库细节可以远离我们 的应用程序。

MyBatis可用于任何大小和用途的数据库。首先,MyBatis非常适合于那些较小的应用程序数据库,因为它非常容易学习和快速上手。其次,MyBatis对大型企业应用程序也非常合适,因为它没有对数据库的设计、行为或者那些可能对我们的应用程序如何使用数据库产生影响的依赖关系做 任何假设。再次,即使是对于那些在设计上存在着争议或者深陷于高层政策混乱之中的数据库, MyBatis也可以工作得很好。综上所述,MyBatis被设计得非常灵活以至于几乎可适用于任何情况了。 当然,使用MyBatis也可以为你节省大量的时间,因为你再不用写那些重复的、样本一样的代码了。

讨论了 MyBatis的理念和起源。后面将仔细解释什么是MyBatis以及它是如何工作的。

系列文章:

MyBatis知多少(1)

MyBatis知多少(2)

MyBatis知多少(3)

MyBatis知多少(4)MyBatis的优势

MyBatis知多少(5)业务对象模型

MyBatis知多少(6)表现层与业务逻辑层

MyBatis知多少(7)持久层

MyBatis知多少(8)关系型数据库

MyBatis知多少(9)不同类型的数据库

MyBatis知多少(10)应用程序数据库

MyBatis知多少(11)企业数据库

MyBatis知多少(12)私有数据库

MyBatis知多少(13)MyBatis如何解决数据库的常见问题

MyBatis知多少(14)分散的数据库系统

MyBatis知多少(15)数据模型的更多相关文章

  1. MyBatis知多少(26)MyBatis和Hibernate区别

    iBatis和Hibernate之间有着较大的差异,但两者解决方案很好,因为他们有特定的领域.我个人建议使用MyBatis的,如果: 你想创建自己的SQL,并愿意维持他们. 你的环境是由关系数据模型驱 ...

  2. MyBatis知多少(26)调试

    这是很容易,同时与iBATIS的工作程序进行调试. iBATIS有内置的日志支持,并适用于下列日志库,并在这个顺序搜索他们. Jakarta Commons日志记录(JCL). Log4J JDK 日 ...

  3. MyBatis知多少(25)动态SQL

    使用动态查询是MyBatis一个非常强大的功能.有时你已经改变WHERE子句条件的基础上你的参数对象的状态.在这种情况下的MyBatis提供了一组可以映射语句中使用,以提高SQL语句的重用性和灵活性的 ...

  4. MyBatis知多少(24)存储过程

    使用MyBatis配置来调用存储过程.为了理解这一章,首先需要了解我们是如何在MySQL中创建一个存储过程. 在继续对本节学习之前,可以自行学习MySQL存储过程. 我们已经在MySQL下有EMPLO ...

  5. MyBatis知多少(23)MyBatis结果映射

    resultMap的元素是在MyBatis的最重要和最强大的元素.您可以通过使用MyBatis的结果映射减少高达90%的JDBC编码,在某些情况下,可以让你做JDBC不支持的事情. ResultMap ...

  6. MyBatis知多少(22)MyBatis删除操作

    本节从表中使用MyBatis删除记录. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( id INT NOT NULL auto_increment, f ...

  7. MyBatis知多少(21)更新操作

    上一章展示了如何使用MyBatis对表进行读取操作.本章将告诉你如何在一个表中使用MyBatis更新记录. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( ...

  8. MyBatis知多少(20)MyBatis读取操作

    上篇展示了如何使用MyBatis执行创建操作表.本章将告诉你如何使用MyBatis来读取表. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( id INT ...

  9. MyBatis知多少(19)MyBatis操作

    若要使用iBATIS执行的任何CRUD(创建,写入,更新和删除)操作,需要创建一个的POJO(普通Java对象)类对应的表.本课程介绍的对象,将“模式”的数据库表中的行. POJO类必须实现所有执行所 ...

随机推荐

  1. atitit 提升数据库死锁处理总结

    atitit 提升数据库死锁处理总结 正常的来说,锁上都是自动的..不用官.. 正常来讲,insert时不需要加rowlock,就默认是rowlock了, #-----锁的自动转换原理.(正常的不用理 ...

  2. JNI技术基础(1)——从零开始编写JNI代码

    众所周知,Java程序的最大特点就是其跨平台的特性,编写的上层应用程序可以不加任何修改甚至不用重新编译而运行于不同的平台上,然而,Java本身也存着这一个弊端,那就是性能上相对要差一些,在对性能要求比 ...

  3. Spring之@Configuration配置解析

    1.简单的示例: @Configuration @EnableConfigurationProperties({DemoProperties.class}) public class DemoConf ...

  4. Vue.js进阶

    <!-- 动态Props --><!DOCTYPE html> <html lang='utf-8'> <head> <meta charset= ...

  5. Linux 下Shell 脚本几种基本命令替换区别

    Shell 脚本几种基本命令替换区别 前言:因为工作需要,需要编写 shell script .编写大量 shell script 时,累计了大量经验,也让自己开始迷糊几种函数输出调用的区别.后面和 ...

  6. mac工具收藏

    1.office字体兼容 http://mac.pcbeta.com/thread-32703-1-1.html

  7. typeid详解

    在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“ ...

  8. windows & mac 安装lua

    mac从源码编译安装是最方便的,lua源码不足两万行,编译几秒钟的事. 打开terminal,依次输入以下命令: curl -R -O http://www.lua.org/ftp/lua-5.2.3 ...

  9. 使用6to5,让今天就来写ES6的模块化开发!

    http://es6rocks.com/2014/10/es6-modules-today-with-6to5/?utm_source=javascriptweekly&utm_medium= ...

  10. 使用sqlserver的游标功能来导数据的常见写法

    一定要自己试过才知道么? 你也没试过吃屎,你怎么知道屎不能吃,难道你试过啊...(没有愤怒的意思) ),),) declare cursor_data CURSOR FOR SELECT [UserN ...