关系数据库:mysql

使用 mysqladmin 删除数据库

关系型数据库的术语:

  • 数据库: 数据库是一些关联表的集合。
  • 数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
  • 列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。
  • **行:**一行(元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
  • 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
  • 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
  • **外键:**外键用于关联两个表。
  • 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
  • **索引:**使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
  • 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。

mysql是一个关系型数据库。大家对于他的理解可以抽象为一个execl,其中数据库类似于我们创建的文档。

数据表如同

在每个sheet中我们可以写一些我们想要写的数据

这里模拟数据表中的数据,不难看出:

我们的是记录了一个个体的数据,如编号为1的行会把小明这个实体的信息记录。

在下面的表格中如职务,出现的是你的工作的信息,不会出现其他信息如性别,爱好等,

mysql学什么?

  • 管理功能
  • 库的相关知识
  • 表的相关知识
  • 查询功能
  • 如何加快查询速度

管理功能:

管理功能分为三个部分

  1. 用户类管理
  2. 文件管理
  3. 数据库管理

用户类管理:

创建用户和给予权限,给予的权限取决于mysql可以进行什么类型的服务

文件管理:

这一部分涉及到了基础文件的配置,大部分不适合修改。

但有一些文件是为了方便我们去修改代码,优化代码

如:

  • log_error: 错误日志文件的路径。
  • general_log: 记录所有客户端连接和查询的日志。
  • slow_query_log: 记录执行时间超过特定阈值的慢查询。
  • log_queries_not_using_indexes: 记录未使用索引的查询。

这一类在很多时候会是我们去衡量我们设计的数据库是否合理的标准,

如:log_queries_not_using_indexes: 记录未使用索引的查询。是否可以撤去此条索引,去优化我们的代码

数据库管理:

更多是去查看数据库、数据表、数据表项、索引的内容,方便我们进行编辑

数据库:

连接mysql

每个编程语言连接数据库的方式不一样,可以根据自己的需要去针对性的找需要的,当然也需要查看自己选择的几个版本是否兼容。

进入mysql

mysql -u your_username -p
  • -u 参数用于指定用户名。
  • -p 参数表示需要输入密码。

进入mysql后,

本层可以实现的基本功能为:

  1. 查看数据库
  2. 创建数据库
  3. 删除数据库
  4. 使用数据库,"进入"数据库内
  5. 退出mysql

介绍mysqladmin:

核心语句:

mysqladmin -u your_username -p

在这一个语句后面可以这样写:

创建数据库:

mysqladmin -u your_username -p create your_database

查看状态:

mysqladmin -u your_username -p status

等等,当然核心语句还是mysqladmin -u your_username -p

查看数据库:

SHOW DATABASES;

创建数据库:

核心语句:本语句就是创建一个数据库,

CREATE DATABASE 数据库名;

下面代码:解析存在意义,

其中数据库是否已经被创建我们需要进行判断则可以使用 IF NOT EXISTS

[CHARACTER SET charset_name][COLLATE collation_name]; 可以指定字符集和排序规则

CREATE DATABASE [IF NOT EXISTS] database_name
  [CHARACTER SET charset_name]
  [COLLATE collation_name];

mysqladmin创建数据库:

mysqladmin -u your_username -p create your_database

删除数据库:

核心语句:

DROP DATABASE <database_name>;  

增加的功能:

IF EXISTS 是一个可选的子句,表示如果数据库存在才执行删除操作,避免因为数据库不存在而引发错误。

DROP DATABASE [IF EXISTS] <database_name>;

使用 mysqladmin 删除数据库

mysqladmin -u your_username -p drop your_database

使用数据库:

USE your_database;

退出mysql:

EXIT;

数据表:

学习表的前提我们需要学习数据类型,就像我们去设计execl时,那一列应该书写什么被划定好了,如:名字哪一列就不会出现数字等等

数据类型:

  • 数值类型
  • 字符串类型
  • 枚举和集合类型
  • 时间空间类型
  • 空间数据类型

数值类型:

整数型:本质上是int,可以看尾缀进行判断

区别:分配的字节大小不一样,数值范围也不一样。

类型 大小 范围(有符号) 范围(无符号) 用途
TINYINT 1 Bytes (-128,127) (0,255) 小整数值
SMALLINT 2 Bytes (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 Bytes (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 Bytes (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8 Bytes (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值
浮点数:

ps:双精度浮点会更加准确

|---------|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|----------|
| FLOAT | 4 Bytes | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 单精度 浮点数值 |
| DOUBLE | 8 Bytes | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
| DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 |

日期时间型:

这一部分根据设计的数据库去设计时间即可。

类型 大小 ( bytes) 范围 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' YYYY-MM-DD hh:mm:ss 混合日期和时间值
TIMESTAMP 4 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC 结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 YYYY-MM-DD hh:mm:ss 混合日期和时间值,时间戳

字符串类型

字符型:

注意:字符串型功能相对较强大,text是对文本的应用

二进制型:

枚举和集合:

  • ENUM: 枚举类型,用于存储单一值,可以选择一个预定义的集合。
  • SET: 集合类型,用于存储多个值,可以选择多个预定义的集合。

枚举就好像给你所有选项,让你选择一个

set就好像给你很多选择,当然你也可以做选择

空间数据类型(Spatial Data Types)

GEOMETRY, POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION: 用于存储空间数据(地理信息、几何图形等)。

约束类型:

  • 主键约束
  • 外键约束
  • 非空约束
  • 检查约束
  • 唯一约束
  • 默认约束
主键约束:

PRIMARY KEY 约束唯一标识数据库表中的每条记录 。 主键必须包含唯一 的值。 主键列不能包含 NULL 值。 每个表都应该有一个主键,并且每个表只能有一个主键。

ps:复合主键也是常使用的,复合主键可以理解成是选择几个绑在一起构成一个主键,本质还是一个主键。

唯一约束:

唯一性约束要求该列值唯一允许为空,但只能出现一个空值。唯一约束可以确保一列或者几列不出现重复值。

对比:唯一约束和主键约束:

相同点:都值都是唯一的。

不同点:主键一个表只允许设置一个,且主键不允许为空。一个表可以设置很多唯一约束,且允许一个值为null。

外键约束:

MySQL的外键约束用来在两个表数据之间建立链接 ,其中一张表的一个字段被另一张表中对应的字段约束。也就是说,设置外键约束至少要有两种表,被约束的表叫做从表(子表) ,另一张叫做**主表(父表),**属于主从关系。

非空约束:

字段值禁止为空。使用了费空约束的字段如果在添加数据时,没有指定值,数据库系统会报错。

检查约束:

check约束:用于限制 列中的值的范围

假设一个圣诞老人去满足孩子的愿望,但这个愿望一定是要可行的才可以,而这个可行的范围就是检查约束,不过这个检查约束是程序员自己设定的

默认约束:

默认约束是用于为数据表中的字段指定默认值的约束

为每个表项设置约束值。

自增约束:

设置了自增约束的列在插入新的数据会自动的进行加一

(1)一个表只能有一个自增约束

因为一个表只有一个维护自增值的变量。

(2)自增约束的列只能是整数

(3)自增约束的列必须是键列(主键,唯一键,外键),

实际中一般是主键自增最多

如何查看约束呢?

语法:

SHOW CREATE TABLE <数据表名>;

表的功能

查看所有表:

SHOW TABLES;

创建表:

语法:

CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
);
  • table_name 是你要创建的表的名称。
  • column1, column2, ... 是表中的列名。
  • datatype 是每个列的数据类型。
  • 在datatype后面可以设置约束,如默认约束等

一个表格可以在创建时加上包括主键约束在内的约束。一部分可以写在column语句后一部分则需要创建在我们创建的列后面单独拉一行书写

删除表:

DROP TABLE table_name ;    -- 直接删除表,不检查是否存在
或
DROP TABLE [IF EXISTS] table_name;
//检查表存在才进行删除操作
  • table_name 是要删除的表的名称。
  • IF EXISTS 是一个可选的子句,表示如果表存在才执行删除操作,避免因为表不存在而引发错误。

基础的增删改查

插入数据:

INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
  • table_name 是你要插入数据的表的名称。
  • column1, column2, column3, ... 是表中的列名。
  • value1, value2, value3, ... 是要插入的具体数值。

如果数据是字符型,必须使用单引号 ' 或者双引号 ",如: 'value1', "value1"。

插入多条数据:

例子:

INSERT INTO users (username, email, birthdate, is_active)
VALUES
    ('test1', 'test1@runoob.com', '1985-07-10', true),
    ('test2', 'test2@runoob.com', '1988-11-25', false),
    ('test3', 'test3@runoob.com', '1993-05-03', true);

更新数据:

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
  • table_name 是你要更新数据的表的名称。
  • column1, column2, ... 是你要更新的列的名称。
  • value1, value2, ... 是新的值,用于替换旧的值。
  • WHERE condition 是一个可选的子句,用于指定更新的行。如果省略 WHERE 子句,将更新表中的所有行。

删除数据:

DELETE FROM table_name
WHERE condition;

查询数据:

SELECT column1, column2, ...
FROM table_name
[WHERE condition]
[ORDER BY column_name [ASC | DESC]]
[LIMIT number];
  • column1, column2, ... 是你想要选择的列的名称,如果使用 * 表示选择所有列。
  • table_name 是你要从中查询数据的表的名称。
  • WHERE condition 是一个可选的子句,用于指定过滤条件,只返回符合条件的行。
  • ORDER BY column_name [ASC | DESC] 是一个可选的子句,用于指定结果集的排序顺序,默认是升序(ASC)。
  • LIMIT number 是一个可选的子句,用于限制返回的行数。

在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。

DISTINCT 关键词用于返回唯一不同的值。

SELECT DISTINCT column1, column2, ...
FROM table_name;

where小扩展:

符号比大小:
操作符 描述 实例
= 等号,检测两个值是否相等,如果相等返回true (A = B) 返回false。
<>, != 不等于,检测两个值是否相等,如果不相等返回true (A != B) 返回 true。
> 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true (A > B) 返回false。
< 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true (A < B) 返回 true。
>= 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true (A >= B) 返回false。
<= 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true (A <= B) 返回 true。
AND和OR的应用:

如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。

如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。

where三查询:
模糊查询:通过通配符、正则表达式等去快速筛查我们需要的一类数据。
SELECT column1, column2, ...
FROM table_name
WHERE column LIKE pattern;

//其中pattern一般会写入通配符
通配符 描述
% 替代 0 个或多个字符
_ 替代一个字符
[charlist] 字符列中的任何单一字符
[^charlist ] 或 [!charlist] 不在字符列中的任何单一字符

引用菜鸟教程的例子:

这一个例子其中REGEXP是正则表达式的开头,^是正则表达式中的筛查首字母,[]是找到符合条件的其中一个字符。详细可以参考正则表达式那一章

between范围搜索:

BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。

SELECT column1, column2, ...
FROM table_name
WHERE column BETWEEN value1 AND value2;
ps小贴士:

请注意,在不同的数据库中,BETWEEN 操作符会产生不同的结果!
在某些数据库中,BETWEEN 选取介于两个值之间但不包括两个测试值的字段。
在某些数据库中,BETWEEN 选取介于两个值之间且包括两个测试值的字段。
在某些数据库中,BETWEEN 选取介于两个值之间且包括第一个测试值但不包括最后一个测试值的字段。

因此,请检查您的数据库是如何处理 BETWEEN 操作符!

确切查询:in

IN 操作符允许您在 WHERE 子句中规定多个值。

之所以称他为确切查询,因为结果有且仅有出现在in中的才是被查找的

引用类比:"我喜欢吃草莓 草莓汁不行 草莓软糖也不行就像我喜欢你 长得像不行 脾气像你也不行"

出自歌曲《别笑了眼泪都掉了》

SELECT column1, column2, ...
FROM table_name
WHERE column IN (value1, value2, ...);

Limit小拓展:SQL SELECT TOP, LIMIT, ROWNUM 子句

本质上上面三个没有太大区别,不过是其他数据库不支持

SELECT TOP:SQL Server / MS Access 语法
SELECT TOP number|percent column_name(s)
FROM table_name;

实例:SELECT TOP 50 PERCENT * FROM Websites;//前50%的数据
SELECT TOP 50 * FROM Websites;   //前50条数据

LIMIT:MySQL 语法:

SELECT column_name(s)
FROM table_name
LIMIT number;

SELECT * FROM Websites LIMIT 2;   //实例

ROWNUM:Oracle 语法

SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number;


SELECT *
FROM Persons
WHERE ROWNUM <=5;     //实例

UNION用法:

MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合,并去除重复的行

UNION 操作符必须由两个或多个 SELECT 语句组成,每个 SELECT 语句的列数对应位置的数据类型必须相同。

SELECT column1, column2, ...
FROM table1
WHERE condition1
UNION  (UNION ALL)
SELECT column1, column2, ...
FROM table2
WHERE condition2
[ORDER BY column1, column2, ...];

UNION ALL:

MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合,允许出现重复的行

UNION 操作符必须由两个或多个 SELECT 语句组成,每个 SELECT 语句的列数对应位置的数据类型必须相同。

ORDER BY(排序) 语句:

SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;
  • column1, column2, ... 是你要选择的列的名称,如果使用 * 表示选择所有列。
  • table_name 是你要从中查询数据的表的名称。
  • ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ... 是用于指定排序顺序的子句。ASC 表示升序(默认),DESC 表示降序。

GROUP BY 分组语句:

ps:这个一般配合函数()aggregate_function()使用

SELECT column1, aggregate_function(column2)
FROM table_name
WHERE condition
GROUP BY column1;



//实例:

mysql> SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name;
+--------+----------+
| name   | COUNT(*) |
+--------+----------+
| 小丽 |        1 |
| 小明 |        3 |
| 小王 |        2 |
+--------+----------+
3 rows in set (0.01 sec)

使用 WITH ROLLUP:

WITH ROLLUP 可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT...)。

例如我们将以上的数据表按名字进行分组,再统计每个人登录的次数:

本例中前三行结果和上面的一样,但多了一行NULL,本质是WITH ROLLUP添加上面计数的功能又记了一次

mysql> SELECT name, SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------+--------------+
| name   | signin_count |
+--------+--------------+
| 小丽 |            2 |
| 小明 |            7 |
| 小王 |            7 |
| NULL   |           16 |
+--------+--------------+
4 rows in set (0.00 sec)

但这里结果并不完美:

mysql> SELECT coalesce(name, '总数'), SUM(signin) as signin_count FROM  employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, '总数') | signin_count |
+--------------------------+--------------+
| 小丽                   |            2 |
| 小明                   |            7 |
| 小王                   |            7 |
| 总数                   |           16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)

我们可以通过coalesce函数去对NULL进行替换。

coalesce具体是做什么的呢?

  • coalesce(name, '总数')COALESCE 函数用于返回第一个非NULL的值。在这里,当 name 为NULL时,将其替换为'总数'。这是因为 WITH ROLLUP 会生成一个额外的总计行,该行的 name 值为NULL。

但这里其实又不完美了。

我们可以进行一下别名修改。

SELECT coalesce(name, '总数') AS name, SUM(signin) AS signin_count 
FROM employee_tbl 
GROUP BY name 
WITH ROLLUP;
name signin_count
小丽 2
小明 7
小王 7
总数 16

嘻嘻,这里我们使用了别名的知识点。

那么什么是别名?别名用途是什么呢?

什么是别名?

通过使用 SQL,可以为表名称或列名称指定别名。

基本上,创建别名是为了让列名称的可读性更强。

本质就是,我嫌弃我要操作的东西名字太臭太长,我想换个我能记住,写起来方便的

作用:

  • 在查询中涉及超过一个表
  • 在查询中使用了函数
  • 列名称很长或者可读性差
  • 需要把两个列或者多个列结合在一起

下面我们以一个简单的多表查询为例子:

SELECT w.name, w.url, a.count, a.date 
FROM Websites AS w, access_log AS a 
WHERE a.site_id=w.id and w.name="菜鸟教程";

这里若我们没有Websites AS w, access_log AS a此句,我们可能就得写成:

SELECT Websites.name, Websites.url, access_log.count, access_log.date 
FROM Websites , access_log
WHERE access_log.site_id=Websites.id and Websites.name="菜鸟教程";

少了AS,多了几十个字符,这样一看AS真的很有用。

已老实求放过

连接:

  • INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。
  • **LEFT JOIN(左连接):**获取左表所有记录,即使右表没有对应匹配的记录。
  • RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。
  • 补充:FULL OUTER JOIN(mysql中没有该功能)

INNER JOIN(内连接,或等值连接):

**INNER JOIN 又称JOIN:**获取两个表中字段匹配关系的记录。

简单理解:要匹配的数据两个表都有才把记录进行连接

SELECT column1, column2, ...
FROM table1
INNER JOIN table2 ON table1.column_name = table2.column_name;

//扩展:多表连接
SELECT orders.order_id, customers.customer_name, products.product_name
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id
INNER JOIN order_items ON orders.order_id = order_items.order_id
INNER JOIN products ON order_items.product_id = products.product_id;

LEFT JOIN:

LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。

简单理解:我左边(下例中的table1)的表的记录全保存,右边的表(下例的table2)有没有无所谓,有就记没有就null,

注意:右表有的,左表没有则不保存、不连接

SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;

RIGHT JOIN(右连接):

RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。

简单理解:和左连接相反,我右边边(下例中的table2)的表的记录全保存,左边的表(下例的table1)有没有无所谓,有就记没有就null,

注意:左表有的,左表没有则不保存、不连接

SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;

补充点:FULL OUTER JOIN(mysql没有)

FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行.

FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。

简单理解就是:所有表的数据都会保存下来,可以连接、相关联就连、不行就自己开一行。

SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;

NULL处理:

MYSQL中:

方法一:替换NULL:

//COALESCE方法:

SELECT product_name, COALESCE(stock_quantity, 0) AS actual_quantity
FROM products;


//IFNULL方法:
SELECT product_name, IFNULL(stock_quantity, 0) AS actual_quantity
FROM products;

//本质上两个方法差别不大。

方法二:查询NULL:

  • IS NULL: 当列的值是 NULL,此运算符返回 true。

  • IS NOT NULL: 当列的值不为 NULL, 运算符返回 true。

  • <=>: 比较操作符(不同于 = 运算符),当比较的的两个值相等或者都为 NULL 时返回 true。

    //法一:
    SELECT * FROM employees WHERE department_id IS NULL;
    SELECT * FROM employees WHERE department_id IS NOT NULL;

    //法二:
    SELECT product_name, price
    FROM products
    ORDER BY price ASC NULLS FIRST; //本方法是将NULL值排序排到最前/最后进行筛选

    //法三:
    SELECT * FROM employees WHERE commission <=> NULL;

补充:不同数据库的替换方法的不同:

//SQL Server / MS Access中的替换方法调用  ISNULL方法

SELECT ProductName,UnitPrice*(UnitsInStock+ISNULL(UnitsOnOrder,0))
FROM Products

//Oracle中替换方法的调用    NVL方法

SELECT ProductName,UnitPrice*(UnitsInStock+NVL(UnitsOnOrder,0))
FROM Products

正则表达式的格式:

主要是:RLIKE和REGEXP方法:

SELECT column1, column2, ...
FROM table_name
WHERE column_name REGEXP 'pattern';

SELECT column1, column2, ...
FROM table_name
WHERE column_name RLIKE 'pattern';

pattern是正则表达式。

事务:

事务是关系型数据库的一个核心设计。他的出现保证了数据库的数据一致性。

事务会让事件有始有终。若有始无终则让这件事回到最原始的模样(回滚)。

试想一下:你去删除一个人的信息时,他可能在很多表都留下痕迹,事务就是保证他全部表的记录都删除了。

一般来说,事务是必须满足4个条件(ACID)::原子性(A tomicity,或称不可分割性)、一致性(C onsistency)、隔离性(I solation,又称独立性)、持久性(Durability)。

  • **原子性:**一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

  • **一致性:**在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

  • **隔离性:**数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

  • **持久性:**事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

-- 开始事务
START TRANSACTION;

-- 执行一些SQL语句
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;

-- 判断是否要提交还是回滚
IF (条件) THEN
    COMMIT; -- 提交事务
ELSE
    ROLLBACK; -- 回滚事务
END IF;

但一个事务可能非常的庞大,我们每次回滚到原点在进行是不是太费时了。所以我们可以引入一个断点的概念,即在一个位置设置一个断点,每次回滚可以回到最近执行过的那个点。

SAVEPOINT -- 用于在事务中设置保存点,以便稍后能够回滚到该点:

SAVEPOINT -- 用于在事务中设置保存点,以便稍后能够回滚到该点:
SAVEPOINT savepoint_name;


ROLLBACK TO SAVEPOINT -- 用于回滚到之前设置的保存点:
ROLLBACK TO SAVEPOINT savepoint_name;

ALTER两用法:

当我们需要修改数据表名或者修改数据表字段时,就需要使用到 MySQL ALTER 命令。

MySQL 的 ALTER 命令用于修改数据库、表和索引等对象的结构。

ALTER 命令允许你添加、修改或删除数据库对象,并且可以用于更改表的列定义、添加约束、创建和删除索引等操作。

ALTER 命令非常强大,可以在数据库结构发生变化时进行灵活的修改和调整。

/ALTER不修改具体数据。但可以修改我们表属性。//

1. 对列操作:

//对列的增删改
//增列
ALTER TABLE employees
ADD COLUMN birth_date DATE;

//改数据类型:
ALTER TABLE TABLE_NAME
MODIFY COLUMN column_name new_datatype;

//改列名:
ALTER TABLE table_name
CHANGE COLUMN old_column_name new_column_name datatype;

//删列名:
ALTER TABLE table_name
DROP COLUMN column_name;

2.对约束操作:这里删除操作一般需要确定名字是什么,故整理时选择了在增加时加入名字的例子作为整理的标准

对 NOT NULL的增删:

ALTER TABLE Persons
MODIFY Age int NOT NULL;



ALTER TABLE Persons
MODIFY Age int NULL;

对 PRIMARY KEY 的增删:

ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)


//mysql中撤销:
ALTER TABLE Persons
DROP PRIMARY KEY

//SQL Server / Oracle / MS Access中撤销:
ALTER TABLE Persons
DROP CONSTRAINT pk_PersonID

对 FOREIGN KEY的增删:

ALTER TABLE Orders
ADD CONSTRAINT fk_PerOrders
FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)



//   mysql撤销:
ALTER TABLE Orders
DROP FOREIGN KEY fk_PerOrders

//   SQL Server / Oracle / MS Access撤销:
ALTER TABLE Orders
DROP CONSTRAINT fk_PerOrders

对 CHECK的增删:

ALTER TABLE Persons
ADD CONSTRAINT chk_Person CHECK (P_Id>0 AND City='Sandnes')



//   mysql撤销:
ALTER TABLE Persons
DROP CHECK chk_Person

//   SQL Server / Oracle / MS Access撤销:
ALTER TABLE Persons
DROP CONSTRAINT chk_Person

对 DEFAULT的增删:

//增:
//MySQL:

ALTER TABLE Persons
ALTER City SET DEFAULT 'SANDNES'


//SQL Server / MS Access:

ALTER TABLE Persons
ADD CONSTRAINT ab_c DEFAULT 'SANDNES' for City



//Oracle:

ALTER TABLE Persons
MODIFY City DEFAULT 'SANDNES'


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//   mysql撤销:
ALTER TABLE Persons
ALTER City DROP DEFAULT


//   SQL Server / Oracle / MS Access撤销:
ALTER TABLE Persons
ALTER COLUMN City DROP DEFAULT

对 UNIQEUE的增删:

ALTER TABLE Persons
ADD CONSTRAINT uc_PersonID UNIQUE (P_Id,LastName)

//   mysql撤销:
ALTER TABLE Persons
DROP INDEX uc_PersonID

//   SQL Server / Oracle / MS Access撤销:
ALTER TABLE Persons
DROP CONSTRAINT uc_PersonID

//其中uc_PersonID就是被命名的部分

索引:

抽象理解:通过创建一个表,查询时通过这个表就能很精准的定位我们需要的消息了。

  • 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引。
  • 组合索引,即一个索引包含多个列。

注意点:

  • 索引需要占用额外的存储空间。

  • 对表进行插入、更新和删除操作时,索引需要维护,可能会影响性能。

  • 过多或不合理的索引可能会导致性能下降,因此需要谨慎选择和规划索引。

    //索引的增删改

    //增:
    CREATE INDEX index_name
    ON table_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);

    //修改:
    //之添加索引
    ALTER TABLE table_name
    ADD INDEX index_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);

    //删除:
    DROP INDEX index_name ON table_name;

    ALTER TABLE table_name
    DROP INDEX index_name;

有时我们希望查询的是不需要重复的记录,在这时我们可以加入,unique进行修饰。

//增(创建)

CREATE UNIQUE INDEX index_name
ON table_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);
   
//改(增加索引)
ALTER table table_name 
ADD CONSTRAINT unique_constraint_name UNIQUE (column1, column2, ...);

//删
 ALTER TABLE testalter_tbl DROP INDEX c;

查看索引信息:

mysql> SHOW INDEX FROM table_name\G
........
  • SHOW INDEX: 用于显示索引信息的关键字。
  • FROM table_name: 指定要查看索引信息的表的名称。
  • \G: 格式化输出信息。

临时表:

MySQL 临时表在我们需要保存一些临时数据时是非常有用的。

临时表只在当前连接可见,当关闭连接时,MySQL 会自动删除表并释放所有空间

在 MySQL 中,临时表是一种在当前会话中存在的表,它在会话结束时会自动被销毁。

创建临时表:

CREATE TEMPORARY TABLE temp_table_name (
  column1 datatype,
  column2 datatype,
  ...
);

其余的增删改查操作都和正常的表差不多,故可以看上面的内容回忆。

SELECT INTO:插入要新建的表

通过 SQL,您可以从一个表复制信息到另一个表。

SELECT INTO 语句从一个表复制数据,然后把数据插入到另一个新表中。

SELECT *
INTO newtable [IN externaldb]
FROM table1;


或:
SELECT column_name(s)
INTO newtable [IN externaldb]
FROM table1;

上面的方法mysql无法使用。当然mysql可以用另一个方法创建。

CREATE TABLE 新表
AS
SELECT * FROM 旧表 

INSERT INTO SELECT(插入已有表)

复制整个表

INSERT INTO table2
SELECT * FROM table1;

复制需要的列:这里表格已经被创建,我们需要指定要存的也要指定存哪里。

INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;

sql知识点之视图:SQL CREATE VIEW 语句

本知识点在查mysql知识点没看到,如果是学习mysql,我也不清楚能不能用得上。不过在sql标准中能查到。

CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
  • CREATE VIEW: 声明你要创建一个视图。
  • view_name: 指定视图的名称。
  • AS: 指定关键字,表示视图的定义开始。
  • SELECT column1, column2, ...: 指定视图中包含的列,可以是表中的列或计算列。
  • FROM table_name: 指定视图从哪个表中获取数据。
  • WHERE condition: 可选部分,用于指定筛选条件,限制视图中的行。

**注释:**视图总是显示最新的数据!每当用户查询视图时,数据库引擎通过使用视图的 SQL 语句重建数据。

简单理解:我们在查找一些东西的时候,我们需要写select语句,要添加where查询,每次都这样太麻烦了,我们能不能提前设置好一个东西,只要打几个字母就可以把我们想的查的全搞好。

视图就是这么来的,本质上他就是提前把你select语句封好,调用视图就是调用这一整串select语句

导入/导出数据:

导出:

SELECT column1, column2, ...
INTO OUTFILE 'file_path'
FROM your_table
WHERE your_conditions;

导入:

mysql 命令导入:

mysql -u your_username -p -h your_host -P your_port -D your_database

//your_username、your_host、your_port、your_database
 分别为你的 MySQL 用户名、主机、端口和数据库。

source方法导入:

mysql> create database abc;      # 创建数据库
mysql> use abc;                  # 使用已创建的数据库 
mysql> set names utf8;           # 设置编码
mysql> source /home/abc/abc.sql  # 导入备份数据库

重点:SQL注入

sql注入的概念:

所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。

MySQL 注入是指攻击者通过恶意构造的输入,成功地执行恶意的 SQL 查询,这通常发生在用户输入未经适当验证或转义的情况下,攻击者试图在输入中插入 SQL 代码,以执行意外的查询或破坏数据库。

我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。

防范 SQL 注入:

  • 使用参数化查询或预编译语句: 使用参数化查询(Prepared Statements)可以有效防止 SQL 注入,因为它们在执行查询之前将输入数据与查询语句分离。

  • 输入验证和转义: 对用户输入进行适当的验证,并使用合适的转义函数(如mysqli_real_escape_string)来处理输入,以防止恶意注入。

  • 最小权限原则: 给予数据库用户最小的权限,确保它们只能执行必要的操作,以降低潜在的损害。

  • 使用ORM框架: 使用对象关系映射(ORM)框架(如Hibernate、Sequelize)可以帮助抽象 SQL 查询,从而降低 SQL 注入的风险。

  • 禁用错误消息显示: 在生产环境中,禁用显示详细的错误消息,以防止攻击者获取有关数据库结构的敏感信息。

写在最后:

其实SQL还有许多内容,如函数等。没总结,但若我们发现一些我们解决不了的,我们可以自行查询

相关推荐
搬码后生仔9 分钟前
SQLite 是一个轻量级的嵌入式数据库,不需要安装服务器,直接使用文件即可。
数据库·sqlite
码农君莫笑10 分钟前
Blazor项目中使用EF读写 SQLite 数据库
linux·数据库·sqlite·c#·.netcore·人机交互·visual studio
江上挽风&sty12 分钟前
【Django篇】--动手实践Django基础知识
数据库·django·sqlite
奥顺互联V13 分钟前
一次性部署:使用Docker部署PHP应用
大数据·mysql·开源·php
向阳121816 分钟前
mybatis 动态 SQL
数据库·sql·mybatis
胡图蛋.17 分钟前
什么是事务
数据库
小黄人软件20 分钟前
20241220流水的日报 mysql的between可以用于字符串 sql 所有老日期的,保留最新日期
数据库·sql·mysql
张声录125 分钟前
【ETCD】【实操篇(三)】【ETCDCTL】如何向集群中写入数据
数据库·chrome·etcd
无为之士31 分钟前
Linux自动备份Mysql数据库
linux·数据库·mysql
小汤猿人类44 分钟前
open Feign 连接池(性能提升)
数据库