高性能的MySQL(4)Schema设计 - 面向对象网,数据库,mysql,学习,对象 - 面向对象技术开发

面向对象技术开发

会员投稿 投稿指南 站长资讯通告:
您的位置: 首页 > 数据库 > MYSQL > 正文

高性能的MySQL(4)Schema设计

来源: www.bianceng.cn 阅读:

一、设计中的陷阱

1、太多的列

MySQL的存储引擎API工作时需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码为各个列。这是一个代价很高的操作,转换的代价依赖于列的数量,列太多的话,转换代价就会很高。

2、太多的关联

一个粗略的经验法则,如果希望查询和并发行好,单个查询不要超过10个表的关联。

3、过度的枚举

修改一个枚举列的值时,需要alter table的阻塞操作,代价很高。

4、避免不可能的值

CREATE TABLE date_test(
    dt DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00');

二、混用范式和反范式

最常见的反范式数据的方法是复制或者缓存,在不同的表中存储相同的特定列。缓存衍生值,比方说某个帖子的评论总数。混用的目的是在关联查询和增删改操作上做一个性能的折中考虑。

三、缓存表和汇总表

缓存表来存储那些某个主表上的一部分列数据,用来提供高效的查询操作。

汇总表保存的是使用GROUP BY语句聚合数据的表。

建立这些表是为了减少在主表上因为某些查询需要加很多特殊的索引。

当重建汇总表或缓存表时,通常需要保证数据在操作时仍然可用。这就需要通过使用“影子表”。

drop table if exists my_summary_new,my_summary_old;
create table my_summary_new like my_summay;
#导入数据
rename table my_summary to my_summary_old,my_summary_new to my_summary;

四、计数器

如果在表中保存计数器,在更新计数器时可能碰到并发问题,所以创建一张独立的表存储计数器通常是个好主意。

假设有一个计数器表,只有一行数据,记录网站的点击次数

\

网站的每次点击都会导致对计数器更新

update hit_counter set cnt = cnt + 1;

问题在于,对于任何想要更新这一行的事务来说,这条记录会有全局的写锁,这会使事务只能串行执行。要获得更高的并发行,可以将计数器保存在多行中,每次随机选择一个行更新。

create table hit_counter(

   id tinyint unsigned not null primary key,

   cnt int unsigned not null

) engine = innodb;

然后预先增加100行数据,当更新的时候随机选择一条记录来更新

update hit_counter set cnt=cnt+1 where id= rand()*100;

这样的统计结果就变成了

select sum(cnt) from hit_counter;

一个常见的需求是每隔一段时间开始一个新的计数器,这个时候需要简单的修改一下表的设计

\

Tags:
相关文章列表: