冷月醉雪 2015-04-28
MySQL
数据库设计经验分享
其实这个经验分享并不仅仅针对
MySQL
,之所以加上这个关键字其实是为了给搜索引
擎看的,呵呵。这篇文章的目标是为了拓宽新手的思路,对于老鸟可能没什么帮助了。
文章主要涉及以下方面的内容:
1.
数据完整性约束的意义:数据的第一道防线;
2.
避免冗余字段:请不要认为这是一种弹性或者灵活性的体现;
3.
请尽可能的收集数据:这是一种境界;
4.
为什么建立索引:不仅仅是速度;
5.
事务、触发器与存储过程:这是一扇门;
数据完整性约束的意义
很多新手创建的数据库非常的简单,一堆字段扔进去就搞定了,反正脚本会搞定一切。
但是,
你有没有反思过一个问题,写脚本的也是人,是人就会犯错误,
犯了错误就可能搞乱
数据,而数据是一切应用的基础。因此,我建议你们能够静下来,细心的,花费更多的时间
来研究如何更好地设计数据库结构。
主键是必须的
这是我的第一个建议,
每个表必须具有主键,
而且最好是使用单独的一个字段作为主键,
这样从根源上扼杀了出现两条完全相同的数据的可能性。
你可能需要额外的唯一键
例如用户信息表中,
除了用户编号以外,
其登录名称也应该是唯一的,
不要指望以后可
以在程序中处理这个情况,
现在就做,
只要把它标记为唯一键,
就算程序中忘了判断也不会
让错误的数据被存储进来。
字段的类型和长度
请努力使用与数据匹配的类型和适当的长度,虽然你可以把时间保存为
varchar
类型,
但是明显还是
datetime
类型更好,因为你不可能把
2013-02-30
之类的日期保存到
datetime
类型的字段中。
字段的长度也是需要考虑的,
过长虽然比过短带来的麻烦小很多,
但是浪费
了很多空间。
默认值
尽量为字段设置默认值,例如字段
is_read
用来表示用户是否已经阅读过这条留言,
1
表示已读,
请为它设一个默认值
0
来代表未读,
而不是在日后的查询语句中通过
is_read<> 1
或者
is_read = IS NULL OR is_read = 0
来判断。
允许为
NULL
吗?
这个问题需要思考,
而不是一概允许或一概不允许这种模式化的判定。
同时,
建议不要
将
NULL
作为一个特殊的值来使用。
外键约束是必不可少的
你必须理解和开始使用外键,
并且明白外键约束的用法,
这是维护数据完整性很重要的
一环。
建立外键的同时你会对程序的业务逻辑有更清晰的认识。
正确的使用它防止误删具有
依存关系的数据,同时通过级联删除保证在删除的时候不留下任何垃圾。
避免冗余字段
千万不要认为冗余字段能够使数据表更有弹性、
更灵活。
首先来说冗余的字段必然都是
允许为
NULL
的,因为没有适合的代码为这些字段赋值(如果有的话那就不是冗余字段了,
对吗)
。这只会增加数据表的体积。事实上修改表结构仅需几分钟,真正的麻烦还是来自于
为新字段添加相应的业务逻辑。
而且事物总是在变化的,
今天你觉得未来可能会用到这个字段,
但是可能下个星期就不
这么想了,一个月之后你根本不记得当初留了这么一个字段。所以,删了吧。
尽可能的收集数据
其实这有点跑题,因为这不仅仅是数据库设计的事儿,程序员可能也要付出一些时间。
我一贯的观点就是“数据是一切应用的基础”
,尽量的收集它们,以后也许会有用(如果这
个应用有一个长远的预期的话,否则你可以忽略这点)
。
我无法想象
Google
,百度或者淘宝明天会做什么,但是我能肯定它们的业务调整的依
据就是来自这些捕获的数据。
尽可能的收集数据是指在不增加用户操作指令的前提下尽可能的收集一些相关信息。
比
如各种时间、
浏览页面的轨迹等等。
我甚至怀疑以后某些应用会收集用户击键频率这样的信
息,然后利用它来检测账号是否被盗。
此外,我觉得应该尽量在插入
/
修改
/
删除数据的时候多做一些事情,相对来说,这些操
作不那么频繁,
而且单次操作的数据量也更小。不要将压力都留给查询语句。例如,如果你
的程序中需要使用类似
SELECT *, SUM(`point`) AS `total_point` FROM `table` GROUP BY
`user_id`
的语句的话,不妨考虑为这个表增加一个
total_point
字段。
为什么建立索引
如果某个字段,或一组字段会出现在一个会被频繁调用的
where
子句中,那么它们应
该是被索引的,
这样会更快的得到结果。
同时,唯一索引的用途前面提到了,恰当的使用它
们,避免意外的发生。我个人不推荐使用全文索引,尤其对于汉字来说,全文索引的开销太
大了,
我宁可选择搜索引擎提供的站内搜索功能。
虽然搜索引擎的收录不是很及时,
但是我
觉得也不是不能接受。
再说一次,我觉得应该尽量在插入
/
修改
/
删除数据的时候多做一些事情,相对来说,这
些操作不那么频繁,而且单次操作的数据量也更小。不要将压力都留给查询语句。
事务、触发器与存储过程
哦,
事务处理其实是程序中要做的事情,
多条数据操作语句应该放入事务处理中,
我们
需要随时注意保证数据的完整。
触发器和存储过程可以减少程序中的
sql
语句数量,同时减少了程序与数据库之间通讯
带来的损耗。
特别是触发器,
它能极大的帮助我们,
本站的数据库设计中就使用了它,
例如你发表回
复或删除回复的时候会触发一个更新文档回复数量的操作。不过由于
MySQL
数据库中级联
操作无法使触发器触发的怪癖可能需要你做更多的处理才能让触发器顺利工作。
结语
请认真而仔细的设计你的数据库,
并且使表名称和字段名称都易于理解并避免混淆。
例
如,代表删除状态的字段最好命名为
trashed
表示已删除,而不是
trash
,明显的,当你看到
值为
1
的时候前者你能明白这表示已经删除了,而对于后者你恐怕就拿不准了。
你可以想象为数据库结构是软件的等比例模型,
就像是售楼处的模型一样,
它只会比实
物更漂亮而不是更丑。
所以如果你的数据库不够美观,
你的软件质量基本已经定性为不堪入
目了。
如果你有什么意见和想法可以
点击这里打开原文地址
并通过回复的方式告诉我,
只有注
册用户才能回复哦。呵呵。