关系模型
关系数据库建立在关系模型之上。关系模型的本质就是若干个存储数据的二维表。
表的每一行称为记录
(Record),记录一个逻辑上的数据。
表的每一列称为字段
(Column)。字段定义了数据类型(整型、浮点型、字符串、日期等),以及是否允许为 NULL。
注意
NULL表示字段数据不存在
。一个整型字段如果为 NULL 不表示它的值为 0,同样的,一个字符串型字段为 NULL 也不表示它的值为空串’’。
通常情况下,字段应该避免允许为 NULL。不允许为 NULL 可以简化查询条件,加快查询速度,也利于应用程序读取数据后无需判断是否为 NULL。
同一个表的若干记录都有若干相同的字段。
关系数据库的表与表之间需要建立一对一
,一对多
,多对多
的关系。
在关系数据库中,关系是通过
主键外键
来维护的。
主键
对于关系表,有个很重要的约束,就是任意两条记录不能重复。不能重复不是指两条记录不完全相同,而是指能够通过某个字段唯一区分出不同的记录,这个字段被称为主键
。
对主键的要求,最关键的一点是:记录一旦插入到表中,主键最好不要再修改,因为主键是用来唯一定位记录的,修改了主键,会造成一系列的影响。
选取主键的一个基本原则是:不使用任何业务相关的字段作为主键,我们一般把这个字段命名为 id。常见的可作为 id 字段的类型有:
- 自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数,这样我们就完全不用担心主键重复,也不用自己预先生成主键;
- 全局唯一 GUID 类型:使用一种全局唯一的字符串作为主键,类似 8f55d96b-8acc-4636-8cb8-76bf8abc2f57。GUID 算法通过网卡 MAC 地址、时间戳和随机数保证任意计算机在任意时间生成的字符串都是不同的,大部分编程语言都内置了 GUID 算法,可以自己预算出主键。
对于大部分应用来说,通常自增类型的主键就能满足需求。
如果使用 INT 自增类型,那么当一张表的记录数超过 2147483647(约 21 亿)时,会达到上限而出错。使用 BIGINT 自增类型则可以最多约 922 亿亿条记录。
联合主键
关系数据库实际上还允许通过多个字段唯一标识记录,即两个或更多的字段都设置为主键,这种主键被称为联合主键。对于联合主键,允许一列有重复,只要不是所有主键列都重复即可。
没有必要的情况下,尽量不使用联合主键,因为它给关系表带来了复杂度的上升。
外键
在数据表中,可以把数据与另一张表关联起来的字段对应的列称为外键
。
外键并不是通过列名实现的,而是通过定义外键约束实现的。但由于外键约束会降低数据库的性能,大部分互联网应用程序为了追求速度,并不设置外键约束,而是仅靠应用程序自身来保证逻辑的正确性。
多对多关系
实际上是通过两个一对多关系实现的,即通过一个中间表,关联两个一对多关系,就形成了多对多关系.
一些应用会把一个大表拆成两个一对一的表,目的是把经常读取和不经常读取的字段分开,以获得更高的性能。例如,把一个大的用户表分拆为用户基本信息表 user_info 和用户详细信息表 user_profiles,大部分时候,只需要查询 user_info 表,并不需要查询 user_profiles 表,这样就提高了查询速度。
索引
先创建一个后面会用到的表 students
ID | class_id | name | gender | score |
---|---|---|---|---|
1 | 1 | Lucy | 1 | 90 |
2 | 3 | Tom | 0 | 40 |
索引
是关系数据库中对某一列或多个列的值进行预排序的数据结构。通过使用索引,可以让数据库系统不必扫描整个表,而是直接定位到符合条件的记录,这样就大大加快了查询速度。
1 | ALERT TABLE students |
上述代码就创建了一个名称为 idx_score,使用列 score 的索引。索引名称是任意的。
索引如果有多列,可以在括号里依次写上,例如:
1 | ADD INDEX idx_name_score (name, score) |
对于主键,关系数据库会自动对其创建主键索引。使用主键索引的效率是最高的,因为主键会保证绝对唯一。
索引的效率
索引的效率取决于索引列的值是否散列。即该列的值如果越互不相同,那么索引效率越高。反过来,如果记录的列存在大量相同的值,例如 gender 列,大约一半的记录值是 M,另一半是 F,因此,对该列创建索引就没有意义。
使用索引的优点与缺点
索引的优点是提高了查询效率,缺点是在插入、更新和删除记录时,需要同时修改索引,因此,索引越多,插入、更新和删除记录的速度就越慢。
唯一索引
在设计关系数据表的时候,看上去唯一的列,例如身份证号、邮箱地址等,因为他们具有业务含义,因此不宜作为主键。但是,这些列根据业务要求,又具有唯一性约束:即不能出现两条记录存储了同一个身份证号。这个时候,就可以给该列添加一个唯一索引。例如,我们假设 students 表的 name 不能重复:
1 | ALERT TABLE students |
可以只对某一列添加一个唯一约束而不创建唯一索引:
1 | ALTER TABLE students |
这种情况下,name 列没有索引,但仍然具有唯一性保证。
无论是否创建索引,对于用户和应用程序来说,使用关系数据库不会有任何区别。这里的意思是说,当我们在数据库中查询时,如果有相应的索引可用,数据库系统就会自动使用索引来提高查询效率,如果没有索引,查询也能正常执行,只是速度会变慢。因此,索引可以在使用数据库的过程中逐步优化。