mysql web数据库的设计归范-2表设计原则

[职责分离原则]

职责分离原则是指在设计的时候应当考虑到数据的产生,聚合使用等原则,每个系统干自己能干的事情,每个系统只干自己的事情。一个数据表应该放在哪个系统中,通常取决于几点:

1. 谁产生这个信息:通常情况下谁产生了这个数据应当对此数据负责;也就是考虑该数据的创建,发展,销毁等全生命周期的定义,并将这个定义维护起来提供给消费者作为消费原则;

2. 谁最经常使用这个信息:如果某个系统最经常使用这个数据,最经常去修改某个数据,也应该由该系统来负责保存维护该数据;

3. 遵守高内聚,低耦合的考虑:在存放数据的时候如果考虑到数据使用原则导致了相关度非常高的数据存放在多个地方,需要多个系统来维护这个数据就有可能导致系统间的耦合性增强,应当尽量避免。

在我们设计数据库表间的关系的时候也应当遵守相同原则,职责分离降低耦合,但同时要考虑到性能情况,做到适当冗余而不导致修改逻辑复杂。

举个最常见贴子与评论的例子:

CREATE TABLE `wanted_post` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `puid` int(10) unsigned NOT NULL,
  `user_id` int(10) NOT NULL COMMENT ‘发贴用户的id‘,
  `username` varchar(50) NOT NULL COMMENT ‘发贴用户的用户名‘,
  `city` smallint(4) NOT NULL COMMENT ‘所在城市‘,
  `ip` bigint(14) NOT NULL COMMENT ‘发帖人的ip‘,
  `district_id` tinyint(2) NOT NULL COMMENT ‘所在区域的id‘,
  `district_name` varchar(20) NOT NULL COMMENT ‘行政区名字‘,
  `street_id` tinyint(2) NOT NULL COMMENT ‘所在街道(地标)的id‘,
  `street_name` varchar(20) NOT NULL COMMENT ‘小区名字‘,
  `title` varchar(255) NOT NULL COMMENT ‘帖子的标题‘,
  `description` text NOT NULL COMMENT ‘帖子详情描述‘,
  `post_at` int(11) NOT NULL COMMENT ‘用户发帖时间,数据创建的时间,使用整型存储‘,
  `refresh_at` int(11) NOT NULL COMMENT ‘帖子被修改的时间,整型存储‘,
  `show_time` int(11) NOT NULL COMMENT ‘帖子显示时间‘,
  `age_max` int(11) NOT NULL DEFAULT ‘0‘ COMMENT ‘招聘最小年龄‘,
  `age_min` int(11) NOT NULL DEFAULT ‘0‘ COMMENT ‘招聘最大年龄‘,
  `post_refresh_at` int(11) NOT NULL COMMENT ‘刷新时间‘,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_puid` (`puid`),
  KEY `user_id_index` (`user_id`),
  KEY `post_at_index` (`post_at`),
  KEY `refresh_at_index` (`refresh_at`),
  KEY `show_time_index` (`show_time`)
) ENGINE=InnoDB AUTO_INCREMENT=55295 DEFAULT CHARSET=utf8 COMMENT=‘招聘帖子表‘

CREATE TABLE `wanted_post_comment_99` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `puid` int(10) unsigned NOT NULL,
  `user_id` int(10) NOT NULL COMMENT ‘评论用户ID‘,
  `post_at` int(11) NOT NULL COMMENT ‘评论时间‘,
  `detail` text NOT NULL COMMENT ‘评论详情‘,
  PRIMARY KEY (`id`),
  KEY `user_id_index` (`user_id`),
  KEY `puidid_index` (`puid`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT=‘招聘评论分表99‘


由于评论表数据量很大,在预先做好分表,按贴子puid分成100张子表,那么当前详情页涉及sql如下:

select * from wanted_post where puid=xxxx;
select * from wanted_post_comment_99 where puid=xxxx;

这是一个简化的模型,评论多了,还要涉及分页,不可能一次性全取出来。对于上面的场景,严格尊守高内聚,低耦合的原则,不会存储冗余数据。相比较还有一种文档型数据库,例如mongo,就可以将评论与贴子存放在一起,访问的时候只需一次顺序IO操作。整体来讲表设计,要按照职责划分原则。


[在线处理与分析分离]

1. 为了保障线上数据处理的性能,将一些分析相关的数据及分析结果,应当使用单独的库来进行存储,避免在数据分析的时候导致业务数据吞吐量下降,引起系统问题。

2. 专门用于存放离线报表数据,并提供线上数据查询方法,建议将统计结果,汇总的数据都从在线处理数据库中移走。

对于上面的wanted_post求职贴子表,在线处理只能是用户在操作:浏览,修改,删除,分别对应如下sql:

select * from wanted_post where puid=xxxxx;
update wanted_post set xxx=xxx where puid=xxxx;
delete from wanted_post where puid=xxxx;

同样,对于后台统计来讲,都是些聚合操作,非常消耗性能,例如查看某一用户发贴量:

select count(*) from wanted_post where user_id=xxxx;

上面举个通用的例子,原则上要将在线用户请求和后台统计请求分开。简单来讲,对于这种需求处理如下:

  1. 将请求指向不同slave ,这种方法简单高效,缺点是数据量增大就玩不转。
  2. 建立离线报表库,专门存放统计结果,这样将计算与展示异步处理,缺点是对于实时业务响应不好。
  3. 实时拉取mysql row binlog,做数据的异构处理(tungsten, canal),将增量结果处理后(storm),保存在数据库中,基本实时。

[事务与日志分离]

用户生成内容和用户行为日志要分开,这一点很好理解,举两个例子:

  1. 游戏DB里存放玩家的基础信息,装备,属性,好友列表等等,这些放到数据库里面。但是玩家的行为日志,比如消耗金币,今天下过哪些副本,买过什么顶级装备,这些属于行为日志,应该单独存放并分析处理。
  2. 对于web用记,有好多用户置顶,刷新,竞价,展示等行为,要求实时并且量很大,一定要和贴子分开。

行为日志,需要做分析处理,并且由于时效性不宜存储在mysql中,后期维护就是地雷。

[历史可追溯]

在数据库设计的时候为了保障数据是可追溯的,应当遵循一些简单的约定,事后方便数据的查询和统计:

1. 对于状态数据,应当设计相应状态的字段来保存该数据的最后状态,同时记录下来该数据的初始创建人,时间以及该数据的最后修改人和修改时间;所以在交易数据(如订单合同),广告数据,账户表等都应该默认有状态(status),创建人(creator/creator_name),创建时间(created_at),最后修改人(modifier/modifier_name),最后修改时间(modified_at)等字段用来表明数据的当前状态,创建信息及修改信息。

2. 针对需要跟踪每次修改的数据,需要在数据发生变化的时候记录一张日志表,用于记录该数据发生变化的全生命周期。针对只需要关注关键字段变化的情况,则日志表中只需要记录关键字段变化即可,但操作人,操作类型,时间应当准确记录,日志表数据一旦生成不允许进行修改。如用户账户的充值流水,消费流水都是一些业务紧相关的日志。而审核日志,操作记录等日志则属于与业务关联较小的日志。

3. 针对所有历史需要保留的数据则需要每次变化都生成一个新的版本,比如类目信息等,对原始数据永远只做insert操作,不做delete及update操作。但这种情况仅限于极端数据历史要求极高的情况下使用。

mysql web数据库的设计归范-2表设计原则,布布扣,bubuko.com

时间: 2024-12-28 02:14:37

mysql web数据库的设计归范-2表设计原则的相关文章

数据库 一对多,多对多 表设计

做一个项目,必然是少不了数据库设计的!在学习阶段,基本都是单表.然而在实际开发过程中,一对多,多对多的表处处都是!简单整理一下,一对多,多对多表如何设计整理一下思路:     数据库实体间有三种对应关系:一对一,一对多,多对多. 一对一关系示例: 一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号. 一对多关系示例: 一个学生只属于一个班,但是一个班级有多名学生. 多对多关系示例: 一个学生可以选择多门课,一门课也有多名学生. 1.一对多关系处理:        通过学生和班级问题了解

mysql笔记--数据库基本增删改查 修改表结构

数据库基本增删改查 1. 增-添加/插入数据,insert into 插入哪张表,那些列,什么值, 语句:insert into 表名(列1,列2,列3)values (值1,值2,值3): 可以不按原列的顺序插入,也可以插入部分列,但是值与列要一一对应,不能混乱!!! 一次插入多行数据 : Insert into 表名(列1,列2)values (值1,值2),(值1,值2): 2. 改-更新数据update 更新哪张表,哪些列,哪些值 语句:update 表名 set 列1=值1,列2=值2

含有状态的表设计

订单表是我们在做开发中,经常会涉及到的一个数据库表.这篇博文来写写关于其中的状态字段的一些想法. 今天想讲下自己对订单表状态字段的值设计的一个浅薄的思考和理解. 先说下我一年前对这个状态字段的一个值设计. 0:创建 -1:买家取消 -2:卖家取消 -3:系统取消 -4:失败 1:已支付 2:已发货 3:交易完成 4:已评价 这是一个很容易就设计出来的值.也是我之前的理解:负面状态为负数,正面状态为正数,初始化状态为0. 一开始用着,感觉还没什么问题.但时间久了,需求一变更,就发现这个值设计不对劲

【数据库】Mysql中主键的几种表设计组合的实际应用效果

写在前面 前前后后忙忙碌碌,度过了新工作的三个月.博客许久未新,似乎对忙碌没有一点点防备.总结下来三个月不断的磨砺自己,努力从独乐乐转变到众乐乐,体会到不一样的是,连办公室的新玩意都能引起莫名的兴趣了,作为一只忙碌的 “猿” 倒不知正常与否. 咳咳, 正题, 今天要写一篇关于mysql的主键.索引的文章,mysql的研究博主进行还不够深入,今天讨论的主题主要是,主键对增删改查的具体影响是什么? 博主将用具体的实验说明. 如果你不了解主键,你可以先看看下面的小节,否则你可以直接跳转到实验步骤 了解

转一篇MYSQL文章《数据库表设计,没有最好只有最适合》

http://mp.weixin.qq.com/s/a8klpzM5iam0_JYSw7-U4g 我们在设计数据库的时候,是否会突破常规,找到最适合自己需求的设计方案,下面来举个例子: 常用的邻接表设计,都会添加 一个 parent_id 字段,比如区域表(国.省.市.区): CREATE TABLE Area ( [id] [int]  NOT NULL, [name] [nvarchar]  (50) NULL, [parent_id] [int]  NULL, [type] [int]  

Java学习总结(十六)——MySQL数据库(中)分组,嵌套,连接查询及外键与关系表设计

一.分组查询 1.语法:group by 分组字段1[,分组字段2,.........] [having 分组后的筛选条件]2.注意:分组字段应该与select后的查询字段一致,否则查询结果无意义3.分组查询经常会与聚合函数一起使用例:(1)先建一张商品表(以此表为例进行分组查询) (2)插入记录 (3)查询:#1.计算每一种商品单价的平均价格 查询结果:#2.计算日用品种类的平均价格 查询结果:二.连接查询1.等值连接语法:select 字段1,字段2,........ from 表A,表B,

20170105数据库表设计知识点

20170105数据库表设计知识点 ------指导老师    星哥 1.PHP(MYSQL)擅长单表操作,不要做过多无谓的连接查询 2.表字段名不要使用大驼峰命名方式,最好采用下划线,命名要和团队习惯一致,通俗易懂. 3.表级.字段都要有注释 4.MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好.甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成.另外,MyISAM 对于 SELECT COUNT(*) 这类的计算

MySQL性能调优与架构设计——第 14 章 可扩展性设计之数据切分

第 14 章 可扩展性设计之数据切分 前言 通过 MySQL Replication 功能所实现的扩展总是会受到数据库大小的限制,一旦数据库过于庞大,尤其是当写入过于频繁,很难由一台主机支撑的时候,我们还是会面临到扩展瓶颈.这时候,我们就必须许找其他技术手段来解决这个瓶颈,那就是我们这一章所要介绍恶的数据切分技术. 14.1 何谓数据切分 可能很多读者朋友在网上或者杂志上面都已经多次见到关于数据切分的相关文章了,只不过在有些文章中称之为数据的 Sharding.其实不管是称之为数据的 Shard

PHP和MySQL Web开发(第4版) by Luke Welling

Web开发是基于HTML的,但是HTML是静态的,于是我们还需要PHP这样动态的服务器端脚本语言,有了PHP还不够,我们还需要把数据存储在MySQL这样的RDBMS(关系数据库管理系统)上,PHP和MySQL都是很成熟的工具,具有高性能.低成本.易用性等优势,是Web开发的明智之选. ==== 目录 ==== 第一篇 使用PHP C01 PHP快速入门 C02 数据的存储与检索 C03 使用数组 C04 字符串操作与正则表达式 C05 代码重用与函数编写 C06 面向对象的PHP C07 错误和