在数据库中,经常需要用到大字段类型,如oracle中long/blob/clob,sqlserver中text/image,mysql中的text/longtext/clob/blob。
那么假如现在有一个表,记录某人发布的文档信息,字段包括:发布人,发布时间,文档标题,文档内容(实际中还会有其它字段),一般建表如下(sqlserver):
create table document(
id int identity(1,1) not null,
createuser_id int,
document_title varchar(255),
document_context text);
这张表的结构,表面上看起来,从数据库设计角度和对应的JAVA类的设计来讲,都是没有问题的。
但实际上,这里面隐藏着两个比较严重的问题!
一、不能完全跨数据库
why?问题出在需要查重(distinct)的时候。
在需要查重时,采用纯jdbc技术,则可以自定义要查重的字段,如select distinct id,createuser_id,document_title from document。而当采用hibernate时,若不想自已创建若干个新的Pojo或者使用Object[]方式来处理数据,则只能使用select distinct d from document as d这样的语句,而hibernate会将其解析为类似:select distinct id,createuser_id,document_title,document_context from document。
问题就出在这个document_context字段上!
对于mysql来讲,hibernate生成的sql是可以执行的。但对于sqlserver来讲,是不允许在text/image列上进行distinct查询的!oracle中同样不可以对clob/blob进行distinct查询。
因此系统在sqlserver/oracle上部署时,当需要查重时则会出错。当然如果你用不到查重语句,是一点不受影响的。
二、严重影响列表显示和统计的效率
影响一张表的查询速度的,除了行数,还包括表所占的物理空间的大小。此表在数据量较小时,在查询方面感觉不到明显的差异。但是如果document_context字段所存储的数据都是大段文本或较大的文件时,会导致表的物理空间迅速变大,该字段所占用的空间有可能达到整表所占空间的90%以上。在此基础上,如果行数再增加到数十万、上百万级时,整个表所占的空间将达到一个惊人的数字。
保守估计,一条记录占用的空间平均为10K的话,一万条记录将占用100M的空间,一百万条记录将占用10G!在此表上的CRUD操作,亦将变慢,查询的速度亦会受到非常大的影响 。当然通过提高服务器本身的硬件性能和优化索引,可以提高查询速度,但面对无法预知的巨大洪水,单纯加固堤坝是不保险的。
解决的方式?
曾经处理过公司内的一个老系统,表的行数达到十万左右,由于采用上面的设计方式,虽然已经尽可能优化了索引,但查询分页时,仍然需要十秒左右。我单独建了一个新表,将document_context这个字段移到新表中,在原表中加一个对应的外键列,经过处理后,分页显示响应时间降到毫秒级以内。(二进制数据的转移是无法使用普通 的数据导入导出方式的,我的方法是复制该表,然后再修改复制后的表结构)
因为这个大字段,在最常用的列表显示中是根本不需要关心的,仅当用户需要查看某一记录的具体信息时,才需要调入该字段信息。因此分表后,显著提高了分页性能。
在我现在开发的所有的系统中,我都采用了上述的方式,这样做属于未雨绸缪,一旦系统部署后再修改,可能就来不及了。
分享到:
相关推荐
- 分表情况,2:日期分表,按照目标表里面的记录日期的字段,按照日期【日、周、月、年】拆分成多个表【本代码仅考虑unix时间戳来分表,其它不支持,您可以自己思考,自己修改代码】 - 注意,支持【子表】,填入...
一个简单的oracle数据库环境下的存储过程,介绍了如何从带年月人的分表取数据
分表 JAVA 分表例子,带SQL文件 很简单的例子,就可以明白怎么分表。
springmvc +mybatis采用策略设计模式基于拦截器实现按年分表
MySQL分表及分表后插入sql语句,表为订单表,可以参考一下
kettle对数据分表插入 数据库Oracle etl工具 kettle 通过java脚本,hash算法,实现分表数据写入
资源里包含SQL文档:创建数据库和存储过程.sql 生成数据.sql 测试.sql 比较完善的大量数据分表功能代码,包含...数据按照每个月创建一个数据表,通过存储过程输入参数,按照指定日期跨表查询数据,并且可以分页查询。
excel处理工具,分表,打标签,去噪音,一小时可以达到百万级处理等级,大数据清洗和分析的好工具
sharind-jdbc样例,当中包含了按月动态分表,一个比较简单的demo,大家可以结合自己的需求进行修改,以及可以看下实现思路,仅供参考!
” subTableWay="BYMONTH" 表示从201701月份开始进行分表处理,?表示当前日期的月份,是动态的。只需配置开始日期即可,首先要确定的一点就是子表要在mysql里面真实存在,可以进行动态创建表达到子表的自动增长。...
SQL,大数据分表,SQL千万级分表,删除百万数据
数据库分库分表 数据库分库分表 数据库分库分表
利用python进行数据表分表,目的是将一个大的excel文本按照规则生成对应的小文件
2. 采用动态数据源的方式,需要分表的连接采用单独的数据库连接; 3. 下载代码后,创建对应的数据库表,进行配置即可启动运行,测试功能; 4. 可以参考其中的实现代码,根据项目特点进行有选择性的借鉴; 5. 一个...
sharding-jdbc 分库分表 CRUD
在MySQL中,当一张表的数据过大的时候,操作速度会变慢,而且给维护带来麻烦,分表设计的思想正好解决了这一问题。
在工作中,对于Excel的繁杂数据处理,不管你的数据有多乱,Ta将助你一臂之力.使用非常简单,只需按住ALT+F11后,新建一个窗体和一模块,在把相应的代码复制进去运行就有结果了.....
本文讨论的数据库分表是不改变数据库表结构的水平拆分,不讨论业务的按照纵向拆分。水平拆分数据分库和分表的核心问题是表的ID唯一,然后根据唯一的ID映射到一个物理存储位置,这个映射方案要考虑到满足数据量暴增...
mysql自带的原始分表,根据省份分表,直接导入既可使用
php分库分表