数据库字段设计

1.为什么要设置主键?
答:在一张表中,可以确定一条唯一记录的属性集(这个属性集中的元素可能有一个,两个,三个甚至更多)称为超键;如果属性集中只有一个元素,则通过这个属性集就可以确认一条唯一的记录,这样的属性集称为候选键;从候选键中选择某一个属性集即可作为主键。由上述内容可知超键、候选键、主键集合包含关系为:超键>候选键>主键。
但是一张表中可以有主键、也可以没有;但如果是表结构比较复杂、数据量庞大的表,则建议设置主键,否则会眼中影响CRUD操作的效率,因为没有安全的方法保证值涉及到相关的行。

2.聚集索引是怎么确定的?
答:如果设置了主键,则InnoDB会选择主键作为聚集索引,如果不设主键,则会选择第一个NOT NULL的唯一索引作为聚集索引,如果以上两个条件都不满足,则会选择长度为6个字节的ROWID作为聚集索引。

3.键是用自增还是UUID?
答:首先,InnoDB使用聚集索引,所有的数据存储在主索引的叶子节点上,这就要求同一叶子节点(大小为一个磁盘页或者内存页)内的各条记录需要按照主键顺序来存放,因此每当有一条数据添加进数据库时,MySQL需要根据其主键大小为其查找适当的位置来存放,如果页面达到装载因子(15/16),则会开辟一个新的节点来存放。
因此,如果使用自增长主键,那么每次插入新纪录时,则只需要把这条记录添加到当前索引节点的后续位置;但如果使用UUID作为主键,则每次插入新的记录时,首先需要根据主键的大小在主索引的所有叶子节点内查找合适的位置,然后移动查找到的位置之后的记录,这就造成了移动记录的开销和空间碎片,后续需要通过optimize table来优化。
所以在使用InnoDB存储引擎时,如果没有特别的需要,建议使用与业务无关的自增字段作为主键。

4.主键为什么不推荐有业务含义?
答:归根结底,具有业务含义的主键可能发生改变,如果发生改变,则需要根据主键的值在主索引的叶子节点内重新排序,这就可能造成行数据的大规模移动,带来很大的时间开销,同时,这种变化会带来页分裂,但是在页分裂的时候,InnoDB会在B+索引树上加锁,从而导致锁抢用的现象。
页分裂:页分裂发生在insert(主键不递增)或update操作下,通常来说,B+索引树的叶子节点的大小为一个内存页或者磁盘页,当进行上述操作时,会造成当前页的数据大小超出页大小,这就会造成需要创建一页新页来存放数据,而这个新页则需要根据页顺序进行排列,这就造成:假如原先的页顺序是10-11-12,对11页进行insert或update操作,数据大小超出页大小,则需要新增一页来保存,按理来说,新增的一页页号应该为12,但是12页已经存在,假设14页不存在,创建新页14,调整链表的前后指针,形成10-11-14-12的页顺序,这样在物理存储上页是混乱的,并且这个页很大概率在不同的区。要调整这种混乱的页顺序,可以使用optimize table来理顺表,另一种就是页合并。
页合并:当我们在数据库中删除一行记录时,并不会立即删除,而是现在要删除的行设置一个标记位,代表该行记录可被覆盖,当页中被标记的记录数量达到页大小的50%,则该页就会在其相邻页寻找是否可以将两页合并以优化空间,同时对记录更新也可能出现这种情况。

5.货币字段存储用什么类型?
答:货币类型推荐使用decimal来存储,因为使用double和float存储,当数值比较大的时候,可能存在微小的误差。

6.时间字段用什么类型?
答:timestamp(占4个字节,该字段能存储的范围是:1970-01-01 08:00:01至2038-01-19 11:14:07,但是其优点是:该字段保存的时间带有时区,一旦系统的时区发生改变,该字段的值就会自动更新,适合用来做跨时区的应用)
datetime(占8个字节,该字段的存储范围是:1000-01-01 00:00:00至9999-12-31 23:59:59,其缺点是时间是绝对的,不会随着系统时区更新)
bigInt(占8个字节,存放时间戳,缺点就是时间展示不直观)

7.为什么不在数据库中存储文件,视频,图片等?
答:数据库中可以使用text,blob来存储大文件,但我们通常来说都把文件、视频存在在文件系统中,而在数据库中存放存储路径,其主要原因是:
(1)MySQL内存临时表不支持text、blob等类型,处理时会非常缓慢。
(2)数据库大,内存占用比较高,维护麻烦。
(3)binlog太大,如果是主从同步,会导致主从同步效率问题。

8.如果一张表中如大字段,且该字段不会频繁更新,以读为主,是拆成子表还是存放在一起?
答:如果拆成子表,则会带来连表查询消耗,如果存放在一起,则会带来查询性能,所以视情况而定,但如果数据量特别大,建议拆成子表。

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值