数据库基础知识
- 主键
- 联合主键
- 外键
- 外键约束
- 一对多
- 多对多
- 一对一
- 索引的建立
- 聚合查询
- 分组
SQL
Structured Query Language
DDL:Data Definition Language
DDL允许用户定义数据,也就是创建表、删除表、修改表结构这些操作。通常,DDL由数据库管理员执行。
DML:Data Manipulation Language
DML为用户提供添加、删除、更新数据的能力,这些是应用程序对数据库的日常操作。
DQL:Data Query Language
DQL允许用户查询数据,这也是通常最频繁的数据库日常操作。
SQL语言关键字不区分大小写!!!但是,针对不同的数据库,对于表名和列名,有的数据库区分大小写,有的数据库不区分大小写。同一个数据库,有的在Linux上区分大小写,有的在Windows上不区分大小写。
关系模型
在关系数据库中,关系是通过主键和外键 来维护的
对于关系表,有个很重要的约束,就是任意两条记录不能重复。
不能重复 不是指两条记录不完全相同,而是指能够通过某个字段唯一区分出不同的记录,这个字段被称为主键。
***主键: 用于 唯一标识记录
- 对主键的要求,最关键的一点是:记录一旦插入到表中,主键最好不要再修改
- 选取主键的一个基本原则是:不使用任何业务相关的字段作为主键
因此,身份证号、手机号、邮箱地址这些看上去可以唯一的字段,均不可用作主键。
- 自增整数类型 id 数据库自动分配 [NT自增类型,那么当一张表的记录数超过2147483647(约21亿)时,会达到上限而出错。使用BIGINT自增类型则可以最多约922亿亿条记录。]
- 全局唯一GUID类型 使用一种全局唯一的字符串作为主键 类似
8f55d96b-8acc-4636-8cb8-76bf8abc2f57
联合主键
通过多个字段唯一标识记录,即两个或更多的字段都设置为主键 允许一列有重复,只要不是·所有主键列·都·重复即可
外键 定义两个表中 某些字段之间的关系
定义外键约束
一对多
ALTER TABLE students
ADD CONSTRAINT fk_class_id
FOREIGN KEY (class_id)
REFERENCES classes (id)
在 students 表征 添加外键约束名称为 fk_class_id (随意起名)
指定 class_id 作为外键字段
指定 这个外键关联到 classeses 表中的 id字段(及classes的主键)
通过定义外键约束,关系型数据库可以保证无法插入无效的数据,即如果classes表不存在id=999的记录,students就无法插入class_id=99的记录
大部分互联网应用程序为了追求速度,并不设置外键约束,而是仅靠应用程序自身来保证逻辑的正确性。这种情况下,·class_id·仅仅是一个普通的列,只是它起到了外键的作用而已
多对多
比如:一个老师可以对应多个班级,一个班级也可以对应多个老师,因此,班级表和老师表存在多对多关系
多对多关系实际上是通过·两个一对多关系实现·的,即通过一个中间表,关联两个一对多关系,就形成了多对多关系-
一对一
一对一关系是指,一个表的记录对应到另一个表的唯一一个记录
students表的每个学生可以有自己的联系方式,如果把联系方式存入另一个表contacts,我们就可以得到一个“一对一”关系
| id | student_id | mobile |
| 1 | 1 | 138xxxxx123 |
| 2 | 2 | 138xxxxx456 |
| 3 | 5 | 138xxxxx789 |
这里有疑问: 既然时一对一关系 ,直接给students表增加一个moble字段不就解决问了吗????
回答时: 如果业务允许的话,完全可以。
但是,但是! 有的时候 有的学生没有电话,那么如果是有一对一关系表,那么contacts表中就不存在相应的记录,否则 students 中的mobile字段就为null(或者其他)。
实际上一对一关系准确的说 是 contacts 表 一对一 对应students 表
高端设计:
把一个大表拆分成两个一对一的表,目的是把经常读取的跟不经常读取的字段分开,以以获得更高的性能,
例如:
把一个大的用户表分拆为用户基本信息表user_info和用户详细信息表user_profiles,大部分时候,只需要查询user_info表,并不需要查询user_profiles表,这样就提高了查询速度。
索引
提高查询速度 索引是关系数据库中对某一列或多个列的值进行预排序的数据结构。通过使用索引,可以让数据库系统不必扫描整个表,而是直接定位到符合条件的记录,这样就大大加快了查询速度。
ALTER TABLE students
ADD INDEX idx_score (score);
- 在 students 表中 添加 索引名称为 idx_score 的索引 索引列为score 这样在查询该字段是就可以提高速度
- 可以创建多个索引 在括号中都好分割 (score,name)
索引的效率取决于索引列的值是否散列,即该列的值如果越互不相同,那么索引效率越高。反过来,如果记录的列存在大量相同的值,例如gender列,大约一半的记录值是M,另一半是F,因此,对该列创建索引就没有意义
主键索引的效率是最高的,因为主键会保证绝对唯一。
唯一索引 UNIQUE
一些看上去唯一的列 比如身份证号/邮箱地址等 但是因为有业务含义,不宜作为主键 但是这些列根据业务需求,又具有唯一性 ,不能出现相同的值 此时需要一个唯一索引
ALTER TABLE students
ADD UNIQUE INDEX uni_name (name);
为students 表添加 索引名称为 uni_name 的索引 添加到 name 字段上
也可以只对某一列添加一个唯一约束而不创建唯一索引:
ALTER TABLE students
ADD CONSTRAINT uni_name UNIQUE (name);
创建 或者 不创建索引的区别就是在与 查询速度的区别
聚合查询
可以在 where 筛选之后使用
SELECT COUNT(*) boys FROM students WHERE gender = 'M';
-
聚合查询的WHERE条件没有匹配到任何行,
COUNT()会返回0,而SUM()、AVG()、MAX()和MIN()会返回NULL: -
COUNT 计算某一列符合条件的记录个数
-
SUM 计算某一列的合计值,该列必须为数值类型
-
AVG 计算某一列的平均值,该列必须为数值类型
-
MAX 计算某一列的最大值
-
MIN 计算某一列的最小值
分组
SELECT class_id, COUNT(*) num FROM students GROUP BY class_id;
class_id相同的列先分组,再分别计算- 按照
class_id分组 返回每个class_id的个数 - 在 SELECT 中添加 name 字段后 会报错,聚合查询中,只能放入分组的列
-
但是 可以进行多个字段的分组
SELECT class_id, gender, COUNT(*) num FROM students GROUP BY class_id, gender;
-