数据库设计时优化的注意事项

数据库设计

1 需求

  • 表结构
  • 字段类型、是否允许为null、是否有默认值
  • 索引设计
  • 数据库引擎的选择

2 注意事项

  • 为了查询效率,可以做冗余字段设计(空间换时间的思想,属于一种反范式设计)

  • 字段类型的选择

    • 整型的存储大小与显示大小

      mysql的字段,unsigned int(3), 和unsinged int(6), 能存储的数值范围是否相同。如果不同,分别是多大?

      我们建立下面这张表:

      CREATE TABLE `test` (
          `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
          `i1` int(3) unsigned zerofill DEFAULT NULL,
          `i2` int(6) unsigned zerofill DEFAULT NULL,
          PRIMARY KEY (`id`)
      ) ENGINE=MyISAM DEFAULT CHARSET=utf8
      

在这里插入图片描述

发现,无论是int(3), int(6), 都可以显示6位以上的整数。但是,当数字不足3位或6位时,前面会用0补齐。

手册解释是这样的:

> MySQL还支持选择在该类型关键字后面的括号内指定整数值的显示宽度(例如,INT(4))。该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。

也就是说,int的长度并不影响数据的存储精度,长度只和显示有关,为了让大家看的更清楚,我们在上面例子的建表语句中,使用了zerofill。

最终答案:**存储范围相同**。
  • char 与 varchar 的选择

    • char 不可变,查询效率高,可能造成存储浪费
    • varchar 可变,查询效率不如char,节省空间

常见MySQL数据类型

类 型大 小描 述
CAHR(Length)Length字节定长字段,长度为0~255个字符
VARCHAR(Length)String长度+1字节或String长度+2字节变长字段,长度为0~65 535个字符
TINYTEXTString长度+1字节字符串,最大长度为255个字符
TEXTString长度+2字节字符串,最大长度为65 535个字符
MEDIUMINTString长度+3字节字符串,最大长度为16 777 215个字符
LONGTEXTString长度+4字节字符串,最大长度为4 294 967 295个字符
TINYINT(Length)1字节范围:-128127,或者0255(无符号)
SMALLINT(Length)2字节范围:-32 768~32 767,或者0~65 535(无符号)
MEDIUMINT(Length)3字节范围:-8 388 608~8 388 607,或者0~16 777 215(无符号)
INT(Length)4字节范围:-2 147 483 648~2 147 483 647,或者0~4 294 967 295(无符号)
BIGINT(Length)8字节范围:-9 223 372 036 854 775 808~9 223 372 036 854 775 807,或者0~18 446 744 073 709 551 615(无符号)
FLOAT(Length, Decimals)4字节具有浮动小数点的较小的数
DOUBLE(Length, Decimals)8字节具有浮动小数点的较大的数
DECIMAL(Length, Decimals)Length+1字节或Length+2字节存储为字符串的DOUBLE,允许固定的小数点
DATE3字节采用YYYY-MM-DD格式
DATETIME8字节采用YYYY-MM-DD HH:MM:SS格式
TIMESTAMP4字节采用YYYYMMDDHHMMSS格式;可接受的范围终止于2037年
TIME3字节采用HH:MM:SS格式
ENUM1或2字节Enumeration(枚举)的简写,这意味着每一列都可以具有多个可能的值之一
SET1、2、3、4或8字节与ENUM一样,只不过每一列都可以具有多个可能的值
  • 索引

    • 主键 Primary Key

    • 外键 Foreign Key

      • 保持数据完整性
      ALTER TABLE tbl_name
          ADD [CONSTRAINT [symbol]] FOREIGN KEY
          [index_name] (index_col_name, ...)
          REFERENCES tbl_name (index_col_name,...)
          [ON DELETE reference_option]
          [ON UPDATE reference_option]
      

      例如:

      ALTER TABLE `user_resource` CONSTRAINT `FKEEAF1E02D82D57F9` FOREIGN KEY (`user_Id`) REFERENCES `sys_user` (`Id`)
      

      CASCADE

      在父表上update/delete记录时,同步update/delete掉子表的匹配记录

      • ON DELETE:删除主表时自动删除从表。删除从表,主表不变
      • ON UPDATE:更新主表时自动更新从表。更新从表,主表不变

      SET NULL

      在父表上update/delete记录时,将子表上匹配记录的列设为null (要注意子表的外键列不能为not null)

      • ON DELETE:删除主表时自动更新从表值为NULL。删除从表,主表不变
      • ON UPDATE:更新主表时自动更新从表值为NULL。更新从表,主表不变

      NO ACTION

      如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作

      • ON DELETE:从表记录不存在时,主表才可以删除。删除从表,主表不变
      • ON UPDATE:从表记录不存在时,主表才可以更新。更新从表,主表不变

      RESTRICT

      同no action, 都是立即检查外键约束

      SET DEFAULT

      父表有变更时,子表将外键列设置成一个默认的值 但Innodb目前不支持

    • 索引 Key / Index

      • 提升查询效率,减慢增删改速度
    • 唯一约束 Unique

      • 保证数据不重复
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不走小道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值