MySQL三范式
发表于|更新于|SQL
|总字数:337|阅读时长:1分钟|浏览量:
数据库三范式
第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
第二范式:2NF是对记录的唯一性约束,要求记录有唯一标识,即实体的唯一性;
第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
范式化
优点:可以尽量的减少数据冗余,使得更新快,体积小
缺点:对于查询需要多个表进行关联,减少写的效率增加读的效率,更难进行索引优化
反范式化
优点:可以减少表的关联,可以更好的进行索引优化
缺点:数据冗余以及数据异常,数据的修改需要更多的成本
归纳
| 方式 | 第一范式 | 第二范式 | 第三范式 |
|---|---|---|---|
| 约束 | 原子性 | 唯一性 | 冗余性 |
| 优点 | 更新快 | 体积小 | 减少数据冗余 |
| 缺点 | 对于查询需要多个表进行关联 | 减少写的效率增加读的效率 | 更难进行索引优化 |
| (反)优点 | 可以减少表的关联 | 可以更好的进行索引优化 | - |
| (反)缺点 | 数据冗余以及数据异常 | 数据的修改需要更多的成本 | - |
文章作者: Michael
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Michael's Blog!
相关推荐

2019-04-20
MySQL 数据类型选型
一句话 选最小的、能装下你数据的类型。 类型小 = 索引小 = 内存命中率高 = 快。 一、整数类型 类型 字节 范围(无符号) 用途 TINYINT 1 0 ~ 255 状态枚举、布尔 SMALLINT 2 0 ~ 65535 较小计数 MEDIUMINT 3 0 ~ 1677w 较少用 INT 4 0 ~ 42亿 大多数主键、ID BIGINT 8 0 ~ 1844亿亿 雪花 ID、大表主键 1234-- ❌ 用户性别用 INTgender INT-- ✅ 用 TINYINTgender TINYINT UNSIGNED COMMENT '0未知 1男 2女' INT(11) 里的 11 不是长度!只是显示宽度(已废弃),实际仍是 4 字节。 二、字符串类型 类型 长度 适用 CHAR(n) 固定 n 字符 MD5、UUID、固定位手机号 VARCHAR(n) 可变 ≤ n 大多数字符串 TEXT (4 种) 长文本 文章正文,不要建普通索引 ENUM 枚举 不推荐,...

2019-03-20
控制并发
Mysql内部通过锁机制实现对资源的并发访问控制,保证数据的一致性,锁机制的类型和引擎的种类有关,MyISAM中默认支持的表级锁有两种:共享读锁和独占写锁。表级锁在MyISAM和InnoDB的存储引擎中都支持,但是InnoDB默认支持的是行锁。 MyISAM锁机制Mysql中可以通过以下sql来显示的在事务中显式的进行加锁和解锁操作: 123456// 显式的添加表级读锁LOCK TABLE 表名 READ// 显示的添加表级写锁LOCK TABLE 表名 WRITE// 显式的解锁(当一个事务commit的时候也会自动解锁)unlock tables; (1)MyISAM表级写锁:当一个线程获取到表级写锁后,只能由该线程对表进行读写操作,别的线程必须等待该线程释放锁以后才能操作。 (2)MyISAM表级共享读锁:当一个线程获取到表级读锁后,该线程只能读取数据不能修改数据,其它线程也只能加读锁,不能加写锁。 InnoDB锁机制InnoDB和MyISAM不同的是,InnoDB支持行锁和事务,InnoDB中除了有表锁和行级锁的概念,还有Gap Lock(间隙锁)、Next-key ...

2020-03-20
性能优化方案
数据量比较大,批量操作数据入库 耗时操作考虑异步处理 恰当使用缓存 优化程序逻辑、代码 SQL优化 压缩传输内容 考虑使用文件/MQ等其他方式暂存,异步再落地DB 跟产品讨论需求最恰当,最舒服的实现方式 本文会提到52条SQL语句性能优化策略。 1、对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引。 2、应尽量避免在where子句中对字段进行null值判断,创建表时NULL是默认值,但大多数时候应该使用NOT NULL,或者使用一个特殊的值,如0,-1作为默认值。 3、应尽量避免在where子句中使用!=或<>操作符,MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。 4、应尽量避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,可以使用UNION合并查询:select id from t where num=10 union all select...

2019-03-20
分库分表
分库分表 并发量决定是否需要分库, 数据量决定是否需要分表。 分区分片 按时间范围归档分区 按用户ID取模分表, 按shardingkey来分片; 数据量太大的场景 mysql表的数据量一般控制在千万级别,如果再大的话,就要考虑分库分表。 除了分表外,列举了面对海量数据业务的一些常见优化手段 缓存加速 读写分离 垂直拆分 分库分表 冷热数据分离 ES助力复杂搜索 NoSQL NewSQL 分表后ID如何保证全局唯一 分库分表后,多张表共用一套全局id,原来单表主键自增方式满足不了要求。 我们需要重新设计一套id生成器。 特点:全局唯一、高性能、高可用、方便接入。 UUID 数据库自增ID 数据库的号段模式,每个业务定义起始值、步长,一次拉取多个id号码 基于Redis,通过incr命令实现ID的原子性自增。 雪花算法(Snowflake) 市面的一些开源框架,如:百度(uid-generator),美团(Leaf), 滴滴(Tinyid)等 分表后可能遇到的问题 分表后,与单表的最大区别是有分表键sharding_key,用来路由具...

2019-03-20
MySQL主键
主键使用自增ID还是UUID?能说说原因吗? 自增ID和UUID作为主键的考虑主要有两方面, 一个是性能 另一个就是存储的空间大小, 一般没有特定的业务要求都不推荐使用UUID作为主键。 因为使用UUID作为主键插入并不能保证插入是有序的,有可能会涉及数据的挪动,也有可能触发数据页的分裂,因为一个数据页的大小就是16KB,这样插入数据的成本就会比较高。 而自增ID作为主键的话插入数据都是追加操作,不会有数据的移动以及数据页的分裂,性能会比较好。 另一方面就是存储空间, 自增主键一般整形只要4个字节,长整形才占8字节的大小空间, 而使用UUID作为主键存储空间需要16字节的大小,会占用更多的磁盘, 在二级索引中也会存出一份主键索引,这样多占用消耗的空间就是两倍,性能低, 所以不推荐使用。 自增id是连续的,插入过程也是顺序的,总是插入在最后,减少了页分裂,有效减少数据的移动。 所以尽量不要使用字符串(如:UUID)作为主键。

2019-03-20
MySQL - MVCC
MVCC叫做多版本控制,实现MVCC时用到了一致性视图,用于支持读提交和可重复读的实现。 对于一行数据若是想实现可重复读取或者能够读取数据的另一个事务未提交前的原始值,那么必须对原始数据进行保存或者对更新操作进行保存,这样才能够查询到原始值。 在Mysql的MVCC中规定每一行数据都有多个不同的版本,一个事务更新操作完后就生成一个新的版本,并不是对全部数据的全量备份,因为全量备份的代价太大了: 如图中所示,假如三个事务更新了同一行数据,那么就会有对应的v1、v2、v3三个数据版本,每一个事务在开始的时候都获得一个唯一的事务id(transaction id),并且是顺序递增的,并且这个事务id最后会赋值给row trx_id,这样就形成了一个唯一的一行数据版本。 实际上版本1、版本2并非实际物理存在的,而图中的U1和U2实际就是undo log日志(回滚日志),这v1和v2版本是根据当前v3和undo log计算出来的。 InnoDB引擎就是利用每行数据有多个版本的特性,实现了秒级创建“快照”,并不需要花费大量的是时间。
评论
公告
欢迎来到 Michael 的博客 · 记录代码、思考与生活