数据库基础总结
把之前学过的SQL
的知识复习一遍,记一下难点。
数据类型
- 数值类型
INT
、FLOAT
- 字符串类型
CHAR
、TEXT
- 日期和时间类型
DATE
、TIMESTAMP
- 复合类型
ENUM
、SET
其中一个ENUM
类型只允许从一个集合中取得一个值;而SET
类型允许从一个集合(元素不能重复的)中取得任意多个值
主键
- 任意两行都不具有相同的主键值
- 每一行都必须具有一个主键值(主键列不允许
NULL
值),虽然不一定需要 - 主键列中的值不允许修改或更新
- 主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)。
Select
命令排序
- SELECT 要返回的列或表达式
- FROM 从中检索数据的表
- WHERE 行级过滤
- GROUP BY 分组说明
- HAVING 组级过滤
- ORDER BY 输出排序顺序
不同的值
DISTINCT
返回所有学生的年龄
1 | SELECT DISTINCT age |
LIMIT
检索记录行 6、7、8
1 | SELECT DISTINCT age |
检索前 5 个记录行
1 | SELECT DISTINCT age |
顺序
ORDER BY
按照排列对象二进制的编码从小到大排序
Comparing the ASCII one by one until difference found, or, one reach the end of the string, it’s the same logic in other program languages.
DESC
倒序
从贵到便宜排列
1 | SELECT DISTINCT age |
与或
SQL
先处理AND
在处理OR
HAVING 和 WHERE
WHERE
过滤行、HAVING
过滤分组
WHERE
在数据分组前进行过滤,HAVING
在数据分组后进行过滤
WHERE
排除的行不包括在分组中,这可能会改变HAVING
子句中基于这些值过滤掉的分组
子查询
可以把一条SELECT
语句返回的结果用于另一条SELECT
语句的WHERE
子句
1 | SELECT cust_id |
在SELECT语句中,子查询总是从内向外处理
作为子查询的SELECT语句只能查询单个列,企图检索多个列将返回错误
作为计算字段使用子查询
查询一个顾客的订单数量
1 | SELECT COUNT(*) AS orders |
查询所有顾客的订单数量
1 | SELECT cust_name, |
联结
如果数据存储在多个表中,怎样用一条SELECT
语句就检索出数据呢?答案是使用联结:
- 内联结
- 外联结
- 交叉联结
假设有以下两个表,其中a.id
同b.parent_id
存在关系:
A表
id | name |
---|---|
1 | 张三 |
2 | 李四 |
3 | 王五 |
B表
id | job | paremt |
---|---|---|
1 | 23 | 1 |
2 | 34 | 2 |
3 | 34 | 4 |
- 内联结根据每个表共有的列的值匹配两个表中的行
1 | SELECT a.*,b.* FROM a INNER JOIN b on a.id=b.parent_id |
返回结果:
1 张三 1 23 1
2 李四 2 34 2
- 左向外连接的结果集包括指定的左表的所有行,如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空
1 | SELECT a.*,b.* FROM a LEFT JOIN b on a.id=b.parent_id |
返回结果:
1 张三 1 23 1
2 李四 2 34 2
3 王五 null
- 右向外连接的结果集包括指定的右表的所有行,如果左表的某行在右表中没有匹配行,则将为左表返回空值
1 | SELECT a.*,b.* FROM a RIGHT JOIN b on a.id=b.parent_id |
返回结果:
1 张三 1 23 1
2 李四 2 34 2
null 3 34 4
- 完整外部连接返回左表和右表中的所有行
1 | SELECT a.*,b.* FROM a FULL JOIN b on a.id=b.parent_id |
返回结果:
1 张三 1 23 1
2 李四 2 34 2
null 3 34 4
3 王五 null
- 交叉联结,两个表的数据进行组合
1 | SELECT a.*,b.* FROM a CROSS JOIN b |
返回3*3=9
条数据
- 自联结,一个表出现多次
UNION
可用UNION
操作符来组合数条SQL
查询。利用UNION
,可给出多条SELECT
语句,将它们的结果组合成一个结果集(不能重复)
如果需要重复,使用UNION ALL
INSERT
正常添加行
1 | INSERT INTO Customers |
移植多行
1 | INSERT INTO Customers(cust_id, |
复制表
1 | SELECT * |
UPDATE & DELETE
正常更新行
1 | UPDATE Customers |
正常删除表
1 | DELETE FROM Customers |
使用外键的好处是防止删除某个关系需要用到的行:
例如,要从Products
表中删除一个产品,而这个产品用在OrderItems
的已有订单中,那么DELETE语句将抛出错误并中止
存储过程
管理事务
- 检查数据库中是否存在相应的顾客,如果不存在,添加他;
- 提交顾客信息;
- 检索顾客的
ID
; - 在
Orders
表中添加一行; - 如果向
Orders
表添加行时出现故障,回退; - 检索
Orders
表中赋予的新订单ID
; - 对于订购的每项物品,添加新行到
OrderItems
表; - 如果向
OrderItems
添加行时出现故障,回退所有添加的OrderItems
行和Orders
行
约束
- 主键
PRIMARY KEY
- 外键
REFERENCES XX(XX)
- 唯一约束
UNIQUE
- 检查约束
CHECK(xx > xx)
唯一约束和主键的区别
- 表可包含多个唯一约束,但每个表只允许一个主键。
- 唯一约束列可包含
NULL
值。 - 唯一约束列可修改或更新。
- 唯一约束列的值可重复使用。
- 与主键不一样,唯一约束不能用来定义外键。
索引
- 索引改善检索操作的性能,但降低了数据插入、修改和删除的性能。在执行这些操作时,DBMS必须动态地更新索引。
- 索引数据可能要占用大量的存储空间。 并非所有数据都适合做索引。取值不多的数据(如州)不如具有更多可能值的数据(如姓或名),能通过索引得到那么多的好处。
- 索引用于数据过滤和数据排序。如果你经常以某种特定的顺序排序数据,则该数据可能适合做索引。
- 可以在索引中定义多个列(例如,州加上城市)。这样的索引仅在以州加城市的顺序排序时有用。如果想按城市排序,则这种索引没有用处。
安全
- 对数据库管理功能(创建表、更改或删除已存在的表等)的访问;
- 对特定数据库或表的访问;
- 访问的类型(只读、对特定列的访问等);
- 仅通过视图或存储过程对表进行访问;
- 创建多层次的安全措施,从而允许多种基于登录的访问和控制;
- 限制管理用户账号的能力。