数据库设计优化

物理设计:

  1. 物理设计要做什么?
    • 选择合适的数据库管理系统。
    • 考虑因素:成本,业务场景,开发语言,功能,操作系统等。
数据库类型 成本 开发语言 支持系统 业务场景

Oracle

商业型 php,java,python等 windows/liunx系统 企业级
SQLServer 商业型 .NET,C#等 只支持windows系统 企业级
MySQL 开源型 php,java,python等 windows/liunx系统 中小型
PgSQL 开源型 php,java,python等 windows/liunx系统 中小型

2.定义数据库,表及字段,要符合命名规范。

    • 选择存储引擎:这里以MySQL为例
存储引擎 索引 事务 锁粒度 主要应用 忌用
MyISAM 支持 不支持 支持并发插入的表级锁 select,insert高负载 读写并用
InnoDB 支持 支持 支持MVCC的行级锁 事务处理
MEMORY 支持 不支持 表锁 中间计算,静态数据 大型数据集,持久性存储
Archive 不支持 不支持 行级锁 日志记录,聚合分析,只支持select,insert操作 随机读取,删除
Ndb cluster 支持 支持 行级锁 高可用集群 典型引用
    • 表及字段命名规范

      1. 可读性:命名可读性强

        • 举例:列名nickname和nick_name相比,后者更加清晰明了,看起来更加舒服一点。
      2. 表意性:见名知意
        • 举例:列名col1和user_name相比,后者更加具有直观性,可以让我们一眼就知道当前列名所代表的意思和可能的数据类型
      3. 敏感性:不能与数据库专有字段命名冲突
        • 举例:MySQL中 有user表,所以我们自己创建用户表时,尽量不使用user命名,可以加一个前缀比如数据库缩写_user。

3.根据选择的数据库管理系统选择合适的数据类型

    • 常用数据类型及占用空间
列类型 存储空间
TINYINT 1个字节
SMALLINT 2个字节
MEDIUMINY 3个字节
INT 4个字节
BINGINT 8个字节
DATE 3个字节
DATETIME 8个字节
TIMESTAMP 4个字节
CHAR(M) M字节,1<= M <=255
VARCHAR(M) L+1字节,在此 L < = M 和  1 <=M <= 255
FLOAT 4字节
DOUBLE 8字节
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2
    • 字段类型的选择的原则
  1. 当一个列可以选择多种数据类型的时候,优先考虑数字类型,其次是日期类型和二进制类型,最后是字符类型。
  2. 对于相同的数据类型,应考虑占用空间较小的数据类型。
    • 字段类型的选择的原则依据
  1. 在对数据进行比较(查询条件,JOIN条件及排序)操作时,同样的数据,字符处理往往比数字处理效率要低,因为字符要参考数据字典进行比较,数字就不需要。
  2. 在数据库中,数据处理以页为单位,列的长度越小,一页中存储的数据就越多,加载相同的数据时的页数就相对较小,速度会更快。
    • 如何具体选择字段类型?
  1. char和varchar该如何选择?

    • char用于数据长度差不多是一致的,基本都在一个小区间内波动或者列中最大数据长度小于50字节。
    • varchar用于数据长度变化较大,不能预知其具体长度的数据。
  2. decimal和float该如何选择?
    • decimal用于存储精确数据,精度最高,但是占用空间很大。
    • float占用空间比decimal小,适用于非精确数据,但会丢失数据精度。
  3. 时间类型如何存储?
    • 使用int:int 是从 1970 年开始累加的,但是 int 支持的范围是 1901-12-13 到 2038-01-19 03:14:07,如果需要更大的范围需要设置为 bigInt。但是这个时间不包含毫秒,如果需要毫秒,还需要定义为浮点数。
    • 使用timestamp:记录经常变化的更新 / 创建 / 发布 / 日志时间 / 购买时间 / 登录时间 / 注册时间等,并且是近来的时间,够用,时区自动处理,比如说做海外购或者业务可能拓展到海外。
    • 使用datetime:记录固定时间如服务器执行计划任务时间 / 健身锻炼计划时间等,在任何时区都是需要一个固定的时间要做某个事情。
    • 数据库设计的其他注意事项
  1. 如何选择主键?

    • 区分业务主键和数据库主键:

      • 业务主键:用于标识业务数据,进行表与表之间的关联。
      • 数据库主键:为了优化数据存储和查找。若没有设置数据库主键,则InnoDB引擎会自动生成6个字节的隐含主键。
    • 考虑主键是否要自动顺序增长:部分数据库是按照主键的顺序逻辑存储的。
    • 主键的字段类型所占用的空间要尽可能小:对于使用聚集索引方式存储的表,每个索引都会附加上主键信息。
  2. 避免使用外键(避免使用数据库来提供外键约束功能):限于互联网项目
    • 在高并发业务中,使用外键约束会降低数据导入的效率,增加维护成本。
    • 建议使用逻辑外键,事实上在数据库中并没有设置外键约束,但在项目上都认为这是外键。由程序来维护外键约束,而不是数据库服务器本身来实现该功能。
    • 相关联的列要建立索引,增加查找效率。
    • 该怎么创建表就怎么创建表,只是没有了FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)该条外键约束命令。

例如:使用数据库创建外键约束:

CREATE TABLE `m_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主键‘,
  `user_name` varchar(50) NOT NULL DEFAULT ‘‘ COMMENT ‘用户名‘,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `m_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主键‘,
  `total_price` decimal(10,2) NOT NULL DEFAULT ‘0.00‘,
  `user_id` int(11) NOT NULL DEFAULT ‘0‘,
  PRIMARY KEY (`id`),
  CONSTRAINT `for_indx_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

不使用数据库创建外键约束:

CREATE TABLE `m_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主键‘,
  `user_name` varchar(50) NOT NULL DEFAULT ‘‘ COMMENT ‘用户名‘,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `m_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘主键‘,
  `total_price` decimal(10,2) NOT NULL DEFAULT ‘0.00‘,
  `user_id` int(11) NOT NULL DEFAULT ‘0‘,
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 3.避免使用触发器

    • 触发器是一个隐藏的存储过程,因为它不需要参数,不需要显示调用,往往在你不知情的情况下已经做了很多操作,无形中增加了系统的复杂性。
    • 涉及到复杂的逻辑的时候,触发器的嵌套是避免不了的,如果再涉及几个存储过程,再加上事务等等,很容易出现死锁现象。
    • 存储过程的致命伤在于移植性,存储过程不能跨库移植,在后期系统升级维护时难度加大。

    4.谨慎使用预留字段

    • 无法准确的知道预留字段的类型。
    • 无法知道预留字段中所存储的内容。
    • 后期维护预留字段的成本高。

      建议:

    1. “按需设计”,在经过详细有效的分析之后,在数据表中只放置必要的字段,而不要留出大量的备用字段。
    2. 如果数量很少,而且信息的性质与原表密切相关,那么就可以直接在原表上动态增加字段,并将相关的数据更新进去
    3. 如果数量较大,或者并非是原表对象至关重要的属性,那么就可以新增一个表,然后通过键值连接起来。

4.反范式化设计。

    • 什么是反范式化?

      • 适当的违反的范式的要求,允许少量的数据冗余,用空间换取时间。
    • 优点:增加查询效率。

原文地址:https://www.cnblogs.com/zhuyeshen/p/11994023.html

时间: 2024-10-06 15:25:42

数据库设计优化的相关文章

高并发,大容量,高性能数据库设计优化

1.数据存储 a.集中式---->分布式 复制m/s.切分 a.1切分 垂直切分(按功能模块) 难点:跨域的表关联--->应用程序 事务---------->分布式的事务(单独数据源的小事务,然后通过程序控制) 某些表访问剧增----->读写分离 读写分离(异构数据源之间的读写分离) 相同数据源,只需要master/slave 难点:异构数据源之间的全量复制问题 异构数据源之间的增量同步问题(解析日志) 水平切分(按记录切分---->找规则) a.2 数据切分及整合的中间件

&lt;&lt;MySchool数据库设计优化&gt;&gt; 内部测试

1) 在SQL Server 中,为数据库表建立索引能够( C ). A. 防止非法的删除操作 B. 防止非法的插入操作 C. 提高查询性能 D. 节约数据库的磁盘空间 解析:索引的作用是通过使用索引,大大提高数据库的检索速度,改善数据库性能 2) 在SQL SERVER中,创建一个表使用(  C)语句. A. INSERT B. DROP C. CREATE D. ALERT 解析:A :insert 插入数据.   B: drop 进行删除操作 D:alter 添加约束 3) 在SQL SE

数据库设计优化经验谈

慎用游标(Cursor)  游标提供了对特定集合中逐行扫描的手段,一般使用游标来逐行遍历数据,根据取出数据条件的不同进行不同的操作.而对于多表和大表中定义的游标(大的数据集合)循环很容易使程序进入一个漫长的等待甚至死机,笔者在某市“住房公积金管理系统”进行日终账户滚积数计息处理时,对一个10万个账户的游标处理时导致程序进入了一个无限期的等待(后经测算需48小时才能完成)(硬件环境:Alpha/4000 128MB RAM ,SCO Unix ,Sybase 11.0).经修改程序并改用UPDAT

SQL Server 数据库性能优化(转载)

原文地址:http://www.cnblogs.com/sydeveloper/archive/2013/04/03/2992881.html 一.数据库设计优化 1.不要使用游标. 使用游标不仅占用内存,而且还用不可思议的方式锁定表,它们可以使DBA所能做的一切性能优化等于没做.游标里每执行一次fetch就等于执行一次select. 2.创建适当的索引 每当为一个表添加一个索引,select会更快,可insert和delete却大大变慢,因为创建了维护索引需要许多额外的工作. (1)采用函数处

SQL Server 数据库性能优化

1. 查看执行时间和cpu set statistics time on select * from Bus_DevHistoryData set statistics time off 执行后在消息里可以看到 2. 查看查询对I/O的操作情况 set statistics io on select * from Bus_DevHistoryData set statistics io off 执行之后的结果: 扫描计数:索引和表执行次数 逻辑读取:数据缓存中读取的页数 物理读取:从磁盘中读取的

[转] SQL Server 数据库性能优化

分析比较执行时间计划读取情况 1. 查看执行时间和cpu set statistics time on select * from Bus_DevHistoryData set statistics time off 执行后在消息里可以看到 2. 查看查询对I/O的操作情况 set statistics io on select * from Bus_DevHistoryData set statistics io off 执行之后的结果: 扫描计数:索引和表执行次数 逻辑读取:数据缓存中读取的

数据库如何优化

一.数据库设计优化 1.不要使用游标. 使用游标不仅占用内存,而且还用不可思议的方式锁定表,它们可以使DBA所能做的一切性能优化等于没做.游标里每执行一次fetch就等于执行一次select. 2.创建适当的索引 每当为一个表添加一个索引,select会更快,可insert和delete却大大变慢,因为创建了维护索引需要许多额外的工作. (1)采用函数处理的字段不能利用索引 (2)条件内包括了多个本表的字段运算时不能进行索引 3.使用事务 对于一些耗时的操作,使用事务可以达到很好的优化效果. 4

架构设计:系统存储(8)——MySQL数据库性能优化(4)

================================ (接上文<架构设计:系统存储(7)--MySQL数据库性能优化(3)>) 4-3.InnoDB中的锁 虽然锁机制是InnoDB引擎中为了保证事务性而自然存在的,在索引.表结构.配置参数一定的前提下,InnoDB引擎加锁过程是一样的,所以理论上来说也就不存在"锁机制能够提升性能"这样的说法.但如果技术人员不理解InnoDB中的锁机制或者混乱.错误的索引定义和同样混乱的SQL写操作语句共同作用,那么导致死锁出现的

架构设计:系统存储(9)——MySQL数据库性能优化(5)

=================================== (接上文<架构设计:系统存储(9)--MySQL数据库性能优化(5)>) 4-3-3-3.避免死锁的建议 上一篇文章我们主要介绍了MySQL数据库中锁的基本原理.工作过程和产生死锁的原因.通过上一篇文章的介绍,可以确定我们需要业务系统中尽可能避免死锁的出现.这里为各位读者介绍一些在InnoDB引擎使用过程中减少死锁的建议. 正确使用读操作语句 经过之前文章介绍,我们知道一般的快照读是不会给数据表任何锁的.那么这些快照读操作