MySql中表和列的设计

3NF(范式)

表的范式,首先符合1NF、才可以满足2NF,进一步满足3NF

  • 第一范式: 表的列具有原子性(不可分解)

  • 第二范式: 表的记录唯一

  • 第三范式: 表中不应该存在冗余数据

1NF

指代信息可以明确的表示某一含义,只要是关系型数据库,就会自动满足1NF

数据库的分类:

关系型数据库:mysql/oracle/sql server/sysbase

非关系型数据库:面向对象和集合

NoSql数据库:MongoDB(面向文档)

2NF

如果表的记录是唯一的,就满足了二范式,通常由主键完成(一般自增长 auto_increment,主键不包含业务逻辑,比较稳定)

3NF

如果一列数据,可以通过其他数据组合获取出来,就不应该单独设置一个字段。 比如,订单的总价格,或者一下的设计:

适当的反三范式

在 1:N 的情况下,为了提高效率,可能会在1这张表中设计一些字段,提高执行效率。

此图也是,虽然冗余了,但是同样提高了效率

列类型的选择

字段类型优先级

整型 > date,time > char,varchar > blob

原因

整型,time/date 运算较快,并且节省空间

char/varchar需要考虑字符集的转换与排序时的 校对集(顺序规定),速度慢

blob 无法使用内存临时表,会在磁盘中建立临时表进行排序等操作,速度最慢

类型大小够用就行

原因:大的字段占用内存,并且影响速度

以 varchar(10), varchar(300) 存储的内容相同,但是在表联查时,varchar(300)将会占用更多的内存

尽量避免使用null

原因

  1. null不利于索引,要用特殊的字节来标注,将会占用更多的字节。

  2. 查询不方便,需要使用 is null,is not null来判断

测试:两张表,一张允许null,一张不允许,查看表的占用空间

-- 不允许为null
drop table if exists t3;
drop table if exists t4;
create table t3 (
    name char(1) not null default '',
    key(name)
) charset utf8;
-- 允许为null
create table t4 (
    name char(1),
    key(name)
) charset utf8;
insert into t3 values('a'), ('');
insert into t4 values('a'), (NULL);

使用Enum

  1. Enum内部是使用整形存储的,效率高

  2. Enum列与Enum列关联速度最快

  3. Enum列比 varchar/char 的弱势:enum需要在取出时做出响应的转化,需要时间

  4. Enum列比 varchar/char 的优势:当char非常长时,enum依然是固定长度;数据量大时,占优势

  5. enum与char/varchar关联,因为要转化,速度要比enum->enum, char->char 要慢。但是当数据量特别大时,可以节省IO

文件、图片等大文件使用文件存储系统

数据库只存放文件的路径,图片和文件存放在文件系统中,或者存放在一台服务器上。

最后更新于