前言:

在我们项目开发中,数据库及表的设计可以说是非常重要,我遇到过很多库表设计比较杂乱的项目,像表名、字段名命名混乱、字段类型设计混乱等等,此类数据库后续极难维护与拓展。我一直相信只有优秀的库表设计才能发挥出MySQL最大的性能,前面有篇文章也分享了数据库的使用规范,本篇文章主要讲几个库表设计的小技巧,希望对大家有所启发。

1.int类型的选用

整型字段类型包含 tinyintsmallintmediumintintbigint 五种,占用空间大小及存储范围如下图所示:

存储字节越小,占用空间越小。所以本着最小化存储的原则,我们要尽量选择合适的整型,下面给出几个常见案例及选择建议。

  • 根据存储范围选择合适的类型,比如人的年龄用 unsigned tinyint(范围 0~255,人的寿命不会超过 255 岁);海龟就必须是smallint,但如果是太阳的年龄,就必须是int。
  • 若存储的数据为非负数值,建议使用 UNSIGNED 标识,可以扩大正数的存储范围。
  • 短数据使用 TINYINT 或 SMALLINT,比如:人类年龄,城市代码。
  • 存储状态变量的字段用 TINYINT ,比如:是否删除,0代表未删除 1代表已删除。
  • 主键列,无负数,建议使用 INT UNSIGNED 或者 BIGINT UNSIGNED;预估字段数字取值会超过 42 亿,使用 BIGINT 类型。

下面给出建表语句示范:

CREATE TABLE  `tb_int` (
`increment_id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`stu_age` tinyint unsigned NOT NULL COMMENT '学生年龄',
`is_deleted` tinyint unsigned DEFAULT '0' COMMENT '0:未删除 1:删除',
`col1` bigint NOT NULL COMMENT 'bigint字段',
PRIMARY KEY (`increment_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='int测试表';

2.时间类型的选用

时间字段类型可以选用datetime和timestamp,下面用一张表展示下二者的区别:

timestamp翻译为汉语即"时间戳",它是当前时间到 Unix元年(1970 年 1 月 1 日 0 时 0 分 0 秒)的秒数,占用4个字节,而且是以UTC的格式储存,它会自动检索当前时区并进行转换。datetime以8个字节储存,不会进行时区的检索。也就是说,对于timestamp来说,如果储存时的时区和检索时的时区不一样,那么拿出来的数据也不一样。对于datetime来说,存什么拿到的就是什么。下面给出几个常见案例及选择建议。

  • 根据存储范围来选取,比如生产时间,保质期等时间建议选取datetime,因为datetime能存储的范围更广。
  • 记录本行数据的插入时间和修改时间建议使用timestamp。
  • 和时区相关的时间字段选用timestamp。
  • 如果只是想表示年、日期、时间的还可以使用 year、 date、 time,它们分别占据 1、3、3 字节,而datetime就是它们的集合。

如果timestamp字段经常用于查询,我们还可以使用MySQL内置的函数FROM_UNIXTIME()UNIX_TIMESTAMP(),将日期和时间戳数字来回转换,转换后可以用 INT UNSIGNED 存储时间,数字是连续的,占用空间更小,并且可以使用索引提升查询性能。下面给出示范建表语句及时间戳相关转换SQL:

CREATE TABLE `tb_time` (
`increment_id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`col1` datetime NOT NULL DEFAULT '2020-10-01 00:00:00' COMMENT '到期时间',
`unix_createtime` int unsigned NOT NULL COMMENT '创建时间戳',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`increment_id`),
KEY `idx_unix_createtime` (`unix_createtime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='time测试表'; # 插入数据
insert into tb_time (unix_createtime,create_time) values
(UNIX_TIMESTAMP(now()),now()); # 时间戳数字与时间相互转换
select UNIX_TIMESTAMP('2020-05-06 00:00:00')
select FROM_UNIXTIME(1588694400)

3.存储IP值

IP值一般使用char或varchar进行存储,但是当进行查找和统计时,字符类型不是很高效。MySQL数据库内置了两个IP相关的函数INET_ATON()INET_NTOA(),可以实现 IP 地址和整数类型的转换。转换后使用可以INT UNSIGNED 来存储IP,转换后的数字是连续的,提高了查询性能,占用空间更小。

CREATE TABLE `tb_ip` (
`increment_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`name` varchar(100) NOT NULL COMMENT '姓名',
`inet_ip` int(10) unsigned NOT NULL COMMENT 'IP',
PRIMARY KEY (`increment_id`),
KEY `idx_inet_ip` (`inet_ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ip测试表'; # 插入数据
insert into `tb_ip` (`name`,`inet_ip`) values
('wang',INET_ATON('192.168.0.1')),('lisi',INET_ATON('192.168.0.2')); # 相互转换
select INET_ATON('192.168.0.1');
select INET_NTOA(3232235521);

总结:

本篇文章分享了几个库表设计及字段类型选取的建议。这些案例都是常常见到的场景,对于int类型及时间类型的选取,本文也根据常见场景给出相关建议,希望大家读完这篇文章有所收获。其实库表设计是件复杂的事情,需要在项目前期多方人员共同规划讨论。还是那句话,只有优秀的库表设计才能发挥出MySQL最大的性能。

MySQL库表设计小技巧的更多相关文章

  1. MySql数据表设计,索引优化,SQL优化,其他数据库

    MySql数据表设计,索引优化,SQL优化,其他数据库 1.数据表设计 1.1数据类型 1.2避免空值 1.3text类型优化 2.索引优化 2.1索引分类 2.2索引优化 3.SQL优化 3.1分批 ...

  2. IOS开发之代理的设计小技巧

    1.关于代理对象的设计小技巧 在设计一个类,需要通过代理和协议来从外部获取需要的动态的数据.那么在这里设计使用代理会有两种方法. <第一种方法> 也是比较常见的: 在你设计的类中,声明一个 ...

  3. python Mysql 库表

    Mysql 库表    创建 学生信息库表  学生成绩 库表

  4. 超强干货,11个灰常实用的AI设计小技巧!

    11个超级实用的AI设计小技巧!涉及到很多的实用操作,纯干货经验总结,灰常值得收藏,赶快转走学起来吧! ​编辑:千锋UI设计

  5. javascript自动填写表单小技巧

    javascript自动填写表单小技巧 在平时开发过程中,或者在访问某些站点,经常要频繁地填写一大堆表单时,我们可以利用javascript,写一段脚本,预先把要填的信息准备好,然后模拟点击按钮的动作 ...

  6. Mysql 库表操作初识

    Mysql 库表操作初识 终端登录mysql 这里只演示win下, cmd 终端. 至于怎么在win下, linux, mac安装, 感觉这是一个入门级的百度搜索问题, 安装都搞不定, 确实有点尴尬, ...

  7. mysql库表优化实例

    一.SQL优化 1.优化SQL一般步骤 1.1 查看SQL执行频率 SHOW STATUS LIKE 'Com_%'; Com_select:执行SELECT操作的次数,一次查询累加1.其他类似 以下 ...

  8. 数据库设计-Mysql数据库表设计的过程中几个关键点

    一.表设计过程中应该注意的数据类型 1)更小的通常更好 控制字节长度 2)使用合适的数据类型: 如tinyint只占8个位,char(1024)与varchar(1024)的对比,char用于类似定长 ...

  9. mysql操作sql的小技巧

    本篇集中整理一下执行sql的小技巧,这种方式不仅带来了操作上的便捷,也可以保证数据可以数据的安全性. 1:查询数据(保证查询性能) 首先想先解释一下 SELECT * 和 SELECT t.id , ...

随机推荐

  1. Django中间件(中间件版登陆验证、访问频率限制)

    一.介绍 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的功能. ...

  2. python网络编程-TCP服务端的开发

    #TCP服务端开发 2 #方法说明 3 """ 4 bind(host,port)表示绑定端口号,host是ip地址,ip地址一般不进 行绑定,表示本机的任何一个ip地址 ...

  3. 云原生的弹性 AI 训练系列之一:基于 AllReduce 的弹性分布式训练实践

    引言 随着模型规模和数据量的不断增大,分布式训练已经成为了工业界主流的 AI 模型训练方式.基于 Kubernetes 的 Kubeflow 项目,能够很好地承载分布式训练的工作负载,业已成为了云原生 ...

  4. python学习9 函数的基础知识

    1.函数的定义 def  func(): 2.函数的调用 func() 3.函数的返回值 #1.没有返回值 # (1)不写return # (2)只写return后面的代码不在继续执行,返回空,代表结 ...

  5. concurrentHashMap扩容相关方法详解

    上一个博客中说到了concurrentHashMap的put操作,在put操作之后如果添加了节点,我们首先会把全局的节点数+1,如果满足了扩容条件,我们则进行扩容 我们先从addCount方法说起 / ...

  6. HarmonyOS三方件开发指南(15)-LoadingView功能介绍

    目录: 1. LoadingView组件功能介绍2. Lottie使用方法3. Lottie开发实现4.<HarmonyOS三方件开发指南>系列文章合集 1. LoadingView组件功 ...

  7. [GDKOI2021] 提高组 Day 2 总结

    [ G D K O I 2021 ]    提 高 组    D a y   2    总 结 不明的感觉今天的题比昨天的简单些,感觉今天爆炸的可能性很低. 嗯,于是乎,就很自信地打完了比赛.然后下午 ...

  8. 经典变长指令SIB

    前言 ModR/M字段是用来进行内存寻址的,可当地址形如DS:[EAX + ECX*2 + 12345678]时,仅仅靠ModR/M字段,是描述不出来的. 这时就在ModR/M后面增加一个SIB字节, ...

  9. 201871010203-陈鹏昱 实验二 个人项目—《D{0-1}KP问题》项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 运用科学高效的方法学习软件工程的理论和知识 这个作业在哪些方面帮助我实现学习目标 掌握软件项目个人开发流程,掌握G ...

  10. 仅使用css实现点击 控制元素的显示与隐藏!

    视频教程:https://www.bilibili.com/video/BV1uE411Q7tx?p=15&spm_id_from=pageDriver 大致方法:在被点击的元素后面 放一个c ...