避免冗余
冗余在不经意间就会发生。受登记表格的影响,可能会想在一张数据表里存放比较多的内容。比如要做一个学生宿舍借钥匙的数据表的话,会有如下设计:
mysql> desc key_loans;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| s_name | varchar(255) | YES | | NULL | |
| time | datetime | YES | | NULL | |
| room | varchar(255) | YES | | NULL | |
| returned | tinyint(1) | YES | | NULL | |
+----------+--------------+------+-----+---------+-------+
其中 s_name
是学生的名字,time
是借钥匙的时间,room
是宿舍号码,returned
用来记录该钥匙是否归还。这个表格看着挺好的,但是存在数据冗余的问题,比如一个学生借了多次钥匙,那么他的名字和宿舍号码就会在该表中不必要地出现多次,比如说下面的情况。
+----+--------+---------------------+------+----------+
| id | s_name | time | room | returned |
+----+--------+---------------------+------+----------+
| 1 | 赵云 | 2019-09-15 23:59:05 | 408 | 1 |
| 2 | 张飞 | 2019-09-15 23:59:38 | 203 | 1 |
| 3 | 赵云 | 2019-09-15 23:59:55 | 408 | 1 |
+----+--------+---------------------+------+----------+
冗余影响更新数据
如果赵云改名字了怎么办?这时候就需要把所有出现赵云的地方都改成新的名字。
冗余影响删除
如果这个表还用作保留学生信息的功能,那删除记录1以后并没有把赵云这位同学的信息都删除。
正确的方式
应该把学生姓名放到额外的表里,然后给学生一个唯一标识符。如果需要学生名字出现在查询结果中,把两个表 join
一下就可以了。
数据像石油,是资源,所以越多越好
时间数据经常可以放一放。用户的行为都伴随着发生的时间,有了这个数据我们能更好地对数据做排序、分类等处理。
通过网络 API 进来的数据带有大量的 HTTP 头部信息。IP 地址是个信息量很大的属性,假设使用 vpn 的用户是少数的话,可以通过它来定位用户的位置。User-Agent
有用户设备的信息,故意修改这个信息的终端不常见。Referer
可以知道用户在访问之前看了哪个网页,等等。