d5.MySq基础知识补充

180 阅读6分钟

数据库基础知识

  • 主键
  • 联合主键
  • 外键
  • 外键约束
  • 一对多
  • 多对多
  • 一对一
  • 索引的建立
  • 聚合查询
    • 分组

SQL

Structured Query Language

DDL:Data Definition Language

DDL允许用户定义数据,也就是创建表、删除表、修改表结构这些操作。通常,DDL由数据库管理员执行。

DML:Data Manipulation Language

DML为用户提供添加、删除、更新数据的能力,这些是应用程序对数据库的日常操作。

DQL:Data Query Language

DQL允许用户查询数据,这也是通常最频繁的数据库日常操作。

SQL语言关键字不区分大小写!!!但是,针对不同的数据库,对于表名和列名,有的数据库区分大小写,有的数据库不区分大小写。同一个数据库,有的在Linux上区分大小写,有的在Windows上不区分大小写。

关系模型

在关系数据库中,关系是通过主键外键 来维护的

对于关系表,有个很重要的约束,就是任意两条记录不能重复
不能重复 不是指两条记录不完全相同,而是指能够通过某个字段唯一区分出不同的记录,这个字段被称为主键

***主键: 用于 唯一标识记录

  1. 对主键的要求,最关键的一点是:记录一旦插入到表中,主键最好不要再修改
  2. 选取主键的一个基本原则是:不使用任何业务相关的字段作为主键

因此,身份证号、手机号、邮箱地址这些看上去可以唯一的字段,均不可用作主键。

  1. 自增整数类型 id 数据库自动分配 [NT自增类型,那么当一张表的记录数超过2147483647(约21亿)时,会达到上限而出错。使用BIGINT自增类型则可以最多约922亿亿条记录。]
  2. 全局唯一GUID类型 使用一种全局唯一的字符串作为主键 类似8f55d96b-8acc-4636-8cb8-76bf8abc2f57

联合主键

通过多个字段唯一标识记录,即两个或更多的字段都设置为主键 允许一列有重复,只要不是·所有主键列·都·重复即可

外键 定义两个表中 某些字段之间的关系

外键定义.png

定义外键约束

一对多

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·仅仅是一个普通的列,只是它起到了外键的作用而已

多对多

比如:一个老师可以对应多个班级,一个班级也可以对应多个老师,因此,班级表和老师表存在多对多关系 多对多关系实际上是通过·两个一对多关系实现·的,即通过一个中间表,关联两个一对多关系,就形成了多对多关系-

外键_多对多.png

一对一

一对一关系是指,一个表的记录对应到另一个表的唯一一个记录

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;