个人原文:www.hijerry.cn/p/6196.htmlphp
数据也是Web应用最重要的部分,而数据库刚好也是Web应用最容易出瓶颈的地方。通过几年的学习、实践我逐渐总结出了一套本身的数据库设计、实践原则,有一些是参考企业的,同时本身的优化方法也在里面。html
Mysql
是目前的主流数据库之一,几乎能够承担起全部Web站点的数据处理操做(经过集群、主从等优化手段)。mysql
大型应用会使用Oracel
做为数据库(好比银行、证券、电信)。sql
另外值得一提的是NOSQL
,因为它的灵活性高于关系型数据库,因此经常使用于做为缓存系统,如MemCache、Redis。数据库
目前JS全栈流派会使用MongoDB做为后台数据库。即使如此,我仍是推荐使用关系型数据库做为主数据库,而NOSQL做为辅助数据库。缓存
如下的设计都是基于Mysql
的。框架
关系型数据库的范式有六种,这是理论上的。数据库设计
在实际开发中,每每达到第三范式便可,并添加一些冗余字段以方便查询。函数
创建逻辑上的主外键,但不创建硬性的主外键关系。学习
逻辑上的主外键意味着主外键关系的维护交于程序来完成,而不是数据库系统。这样能够避免主外键冲突而引发的没必要要bug。
尽可能不使用组合主键。
在为一个字段指定类型时,尽可能使用整数类型
。由于查询效率高,存储空间小。
整数类型字段,尽可能使用 unsigned
。若是确实须要表示负数,那就用有符号的整数类型。
若是字段长度已知,务必使用char
而不是varchar
。varchar
容易产生数据碎片,影响效率。好比存储MD5哈希值。
尽可能避免可空
字段,并给字段设置默认值。NULL
是一个很是恶心的东西,可能会引发索引分裂,而且有时候会引发意料以外的BUG。
不要随意创建索引,应当根据慢查询创建适当的索引。好比常常须要排序、分组的字段,能够创建索引。
把组合主键、值惟一的字段创建为惟一索引。
尽可能使用数据量比较少的索引。好比在整数类型上创建,而不是在文本类型上。这也意味着,在对 text
等数据量比较大的字段创建索引时,应取字段的前面几个字符创建索引便可,而不是创建全文索引。
尽可能选择取值范围更大的字段创建索引。好比咱们不该该在 性别
字段上创建索引,由于它的取值太有限了。
尽可能扩展索引,而不是创建一个新的。好比已有索引(user_id),如今要创建class_id的索引,能够考虑创建为(user_id, class_id)。
索引的创建是否恰当,最终取决于查询速度是否提升了。因此建议根据慢查询日志来创建适当的索引。
尽可能使用utf8mb4
编码,这是四字节的UTF-8编码,是符合标准意义的。而utf8
编码是用三字节存的,因此不能保存emoji表情。
尽可能避免大SQL查询。
尽可能基于索引查询。
比起构造一个复杂的SQL查询作一次查询,简单、短小的基于索引的屡次查询效率会更高。
这张表取自个人毕业设计,先看表结构:
上面全部的整数类型都是 unsigned
类型的
id
主键字段必有type
标识用户类型。unsigned tinyint(0~255)足矣。login
登陆名。必须是变长的,由于这是用户设置的,最多不超过 32
字符。telephone
手机号码。也能够用 bigint
存储。也能够用 char(11)
来存,也能够用 char(13)
来存(区号2位),这里用了 varchar(24)
是考虑到不一样国家长度也不同,干脆用变长字符来存了。email
邮箱地址。目前最长的邮箱是 32
字符,理论最长是 320
字符,这里折中取了 128
字符。password
密码。这里是是使用 Hash:make
方法生成的,最长只有 60
位,因此长度是 60
,而且为了不编码问题,使用 binary
字段来存储。gender
性别。也可使用 enum
存储,但强烈不推荐,更况且只是用来存储整数形式的内容。因此直接用 tinyint
类型。register_ip
、last_login_ip
。ipv4地址。32
位的ipv4地址正好能够用一个int类型保存。php里使用ip2long
函数便可完成转换。若是遇到 ipv6
地址,就须要用 binary(16)
来存了。create_time
、 update_time
、delete_time
是Laravel框架所使用的用于记录数据时间的字段,因此没办法设置为了 能够为空
。看看索引:
UNIQUE KEY `type` (`type`,`login`)
复制代码
这主要用于区分不一样类型的用户。