mysql多表操作与练习笔记
- 格式:doc
- 大小:191.00 KB
- 文档页数:15
MySQL中的高级查询与多表操作技巧在数据库管理系统中,MySQL是一个被广泛使用的关系型数据库管理系统。
它提供了丰富的查询功能和多表操作技巧,使得用户能够更加灵活地操作数据,实现复杂的业务需求。
在本文中,我们将重点介绍MySQL中的高级查询与多表操作技巧,帮助读者更好地利用MySQL进行数据处理。
一、连接查询在MySQL中,连接查询是一种常见的多表查询操作。
它可以通过连接两个或多个表,根据关联条件同时从多个表中获取数据。
连接查询可以大大提高数据查询的效率和准确性。
1. 内连接查询内连接查询是连接查询中最常用的一种类型。
它通过使用INNER JOIN关键字将两个或多个表连接在一起,并根据连接条件获取匹配的数据。
例如,我们有一个学生表和一个成绩表,可以使用内连接查询获取学生表和成绩表中相关联的数据。
```sqlSELECT , scores.scoreFROM studentsINNER JOIN scores ON students.id = scores.student_id;```2. 左连接查询左连接查询是连接查询中另一种常见的类型。
它通过使用LEFT JOIN关键字连接两个或多个表,并返回左表中所有的记录和右表中与之匹配的记录。
如果右表中没有与左表匹配的记录,将返回NULL值。
例如,我们有一个部门表和一个员工表,可以使用左连接查询获取所有部门及其员工的信息。
```sqlSELECT , FROM departmentsLEFT JOIN employees ON departments.id = employees.department_id;```3. 右连接查询右连接查询和左连接查询类似,但是返回右表中所有的记录和左表中与之匹配的记录。
如果左表中没有与右表匹配的记录,将返回NULL值。
例如,我们有一个订单表和一个客户表,可以使用右连接查询获取所有订单及其客户的信息。
```sqlSELECT orders.order_num, FROM ordersRIGHT JOIN customers ON orders.customer_id = customers.id;```4. 全连接查询全连接查询是连接查询中最常用的一种类型。
mysql数据库多表查询的语法在MySQL中,多表查询是一种用于从多个表中获取数据的方法。
通过使用适当的语法和关键字,我们可以结合多个表的信息以满足特定的数据需求。
多表查询的语法如下:SELECT 列名1, 列名2, ...FROM 表名1JOIN 表名2 ON 表名1.列名 = 表名2.列名WHERE 条件;其中,SELECT语句用于指定我们要从多个表中选择的列。
我们可以指定多个列,使用逗号进行分隔。
FROM子句用于指定我们要从中检索数据的表。
JOIN关键字用于将两个或多个表连接起来。
我们需要指定连接的条件,即两个表之间的列的对应关系。
这可以通过使用ON关键字和等式条件完成。
WHERE子句可选,用于筛选满足特定条件的行。
我们可以使用各种逻辑运算符和比较运算符来定义条件。
以下是一个简单的示例,演示如何使用多表查询:SELECT orders.order_id, customers.customer_nameFROM ordersJOIN customers ON orders.customer_id = customers.customer_idWHERE order_date >= '2022-01-01';在上述示例中,我们从"orders"表和"customers"表中选择订单ID和客户名称。
我们使用"JOIN"关键字将这两个表连接起来,连接条件是订单表中的"customer_id"列与客户表中的"customer_id"列相等。
最后,我们使用"WHERER"子句筛选出日期在2022年1月1日及以后的订单。
通过理解和掌握MySQL多表查询的语法,我们可以更好地利用数据库中的多个表来满足我们的数据检索需求。
MySQL教程:多表操作和批处理方法多表操作在一个数据库中,可能存在多个表,这些表都是相互关联的。
我们继续使用前面的例子。
前面建立的表中包含了员工的一些基本信息,如姓名、性别、出生日期、出生地。
我们再创建一个表,该表用于描述员工所发表的文章,内容包括作者姓名、文章标题、发表日期。
1、查看第一个表mytable的内容mysql> select * from mytable;+----------+------+------------+-----------+| name | sex | birth | birthaddr |+----------+------+------------+-----------+| abccs | f | 1977-07-07 | china || mary | f | 1978-12-12 | usa || tom | m | 1970-09-02 | usa |+----------+------+------------+-----------+2、创建第二个表title(包括作者、文章标题、发表日期)mysql> create table title(writer varchar(20) not null,-> title varchar(40) not null,-> senddate date);向该表中填加记录,最后表的内容如下:mysql>select * from title;+--------+-------+------------+| writer | title | senddate |+--------+-------+------------+| abccs | a1 | 2000-01-23 || mary | b1 | 1998-03-21 || abccs | a2 | 2000-12-04 || tom | c1 | 1992-05-16 || tom | c2 | 1999-12-12 |+--------+-------+------------+5 rows in set (0.00sec)3、多表查询现在我们有了两个表: mytable 和title。
宋红康mysql高级篇笔记MySQL 是一款广泛应用于互联网领域的关系型数据库管理系统。
它的高级功能和优势使得它成为互联网开发者的首选。
本文将分享一些关于 MySQL 高级篇的笔记,涵盖了一些互联网技术介绍、互联网商业和技术应用方面的内容。
一、索引优化索引是提高数据库查询效率的重要手段之一。
在 MySQL 中,使用合适的索引可以显著提升查询性能。
首先,我们需要了解不同类型的索引,如主键索引、唯一索引和普通索引等。
其次,根据具体应用场景,我们可以使用覆盖索引、前缀索引、联合索引等技术进行索引优化。
此外,我们还要注意索引的维护和管理,及时进行索引的重建和优化。
二、查询优化在互联网应用中,查询是最常见的数据库操作之一。
如何编写高效的查询语句,能够快速地获取所需的数据,是每个开发者都应该关注的问题。
本节将介绍一些查询优化的技巧,例如避免使用通配符查询、合理使用 LIMIT 关键字、使用 EXPLAIN 分析查询执行计划等。
三、事务管理事务是保证数据库操作一致性和完整性的重要手段。
MySQL 支持事务的 ACID 特性,可以确保多个操作的原子性、一致性、隔离性和持久性。
本节将详细介绍如何使用事务管理,包括事务的开启、提交和回滚,以及事务并发控制的方法。
四、高级数据操作除了基本的增删改查操作,MySQL 还提供了一些高级数据操作功能,方便开发者完成复杂的数据处理任务。
本节将介绍如何使用子查询、联合查询、分组查询和多表操作等技术,实现更灵活和高效的数据操作。
五、存储引擎选择MySQL 支持多种存储引擎,如 InnoDB、MyISAM、Memory 等。
不同的存储引擎具有不同的特点和适用场景。
本节将比较各种存储引擎的优缺点,并给出存储引擎选择的建议。
六、高可用性和容灾备份在互联网应用中,数据库的高可用性和容灾备份是非常重要的。
本节将介绍如何使用主从复制、读写分离、故障转移和数据备份等技术,提高数据库的稳定性和可用性。
mysql基础笔记”MySQL是一种开源的关系型数据库管理系统,被广泛应用于Web 应用程序的数据存储和管理。
下面是关于MySQL基础的一些笔记:1. 数据库,MySQL是基于数据库的,数据库是一个用于存储和管理数据的容器。
可以创建多个数据库,每个数据库可以包含多个表。
2. 表,表是数据库中的一个组成部分,用于存储数据。
表由行和列组成,每一列代表一个数据字段,每一行代表一条记录。
3. 字段,字段是表中的列,用于存储特定类型的数据。
每个字段都有一个数据类型,如整数、字符串、日期等。
4. 主键,主键是表中的一列或一组列,用于唯一标识表中的每一行。
主键的值不能重复,且不能为空。
5. 外键,外键是表中的一列,用于建立表与表之间的关系。
外键与其他表中的主键相关联,用于确保数据的完整性和一致性。
6. 查询,查询是从数据库中检索数据的操作。
可以使用SQL语句来编写查询,SQL是结构化查询语言。
7. 插入,插入是向表中添加新记录的操作。
可以使用INSERT语句来插入数据。
8. 更新,更新是修改表中现有记录的操作。
可以使用UPDATE语句来更新数据。
9. 删除,删除是从表中删除记录的操作。
可以使用DELETE语句来删除数据。
10. 索引,索引是对表中的一列或多列进行排序的结构,用于加快数据的检索速度。
可以根据索引进行快速的查询操作。
11. 视图,视图是基于一个或多个表的查询结果,可以像表一样使用。
视图可以简化复杂的查询操作,提供更方便的数据访问方式。
12. 事务,事务是一组数据库操作的集合,要么全部执行成功,要么全部回滚。
事务可以确保数据的一致性和完整性。
13. 存储过程,存储过程是一组预编译的SQL语句,可以在数据库中进行复杂的操作。
存储过程可以提高数据库的性能和安全性。
14. 触发器,触发器是与表相关联的特殊类型的存储过程,可以在插入、更新或删除数据时自动执行。
以上是关于MySQL基础的一些笔记,希望对你有所帮助。
《快速念咒:MySQL入门指南与进阶实战》阅读记录1. 第一章数据库基础在开始学习MySQL之前,了解一些数据库的基础知识是非常重要的。
数据库是一个用于存储和管理数据的计算机软件系统,它允许用户通过关键字或特定的查询语言来检索、更新和管理数据。
在数据库中,数据是以表格的形式进行组织的,每个表格都包含了一组相关的数据项,这些数据项被称为记录。
表(Table):表是数据库中存储数据的基本单位。
每个表都有一个唯一的名称,并由行(Row)和列(Column)组成。
每一行代表一个数据记录,每一列代表一个特定的数据属性。
字段(Field):字段是表中的一列,代表了数据的一种属性。
每个字段都有一个唯一的名称和一个数据类型,用于定义该字段可以存储的数据种类。
主键(Primary Key):主键是表中的一个特殊字段,用于唯一标识表中的每一行记录。
主键的值必须是唯一的,且不能为NULL。
外键(Foreign Key):外键是一个表中的字段,它的值引用了另一个表的主键值。
外键用于建立两个表之间的联系,确保引用完整性。
索引(Index):索引是一种数据库优化技术,用于提高查询性能。
通过创建索引,数据库可以更快地定位到表中的特定记录,而不必扫描整个表。
SQL(Structured Query Language):SQL是用于与数据库进行交互的编程语言。
它包括用于数据查询、插入、更新和删除的操作符和语法结构。
理解这些基本概念是学习MySQL的前提。
通过掌握SQL语言的基本语法和操作,你将能够有效地管理和操作数据库中的数据。
在接下来的章节中,我们将深入探讨MySQL的具体应用,包括如何创建和管理数据库、表、以及如何执行复杂的查询操作。
2. 第二章数据库设计《快速念咒:MySQL入门指南与进阶实战》是一本全面介绍MySQL 数据库的书籍,其中第二章详细阐述了数据库设计的基础知识和实践技巧。
在这一章节中,作者首先介绍了数据库设计的基本概念和目标,包括数据模型、实体关系模型(ER模型)等,并解释了如何通过这些模型来描述现实世界中的数据和业务逻辑。
(转)MySQL学习笔记-redolog和binlog两阶段提交原⽂:https:///qq_38937634/article/details/113100472?utm_term=mysql%E6%97%A5%E5%BF%97%E4%B8%A4%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-2-113100472&spm=3001.4430⽂章⽬录MySQL学习笔记-redo log 和 binlog&两阶段提交1.笔记图2.⼀条更新语句是如何被执⾏的3.redo log4.binlog5.为什么要有两份⽇志?6.更新语句内部执⾏流程7.两阶段提交MySQL学习笔记-redo log 和 binlog&两阶段提交前⾯学习了⼀条查询语句的执⾏过程⼀般是经过连接器、分析器、优化器、执⾏器等功能模块,最后到达存储引擎,⽽⼀条更新语句的执⾏流程也会按照查询查询语句的流程⾛⼀遍,但更新语句会涉及到两个⽇志模块,分别是 redo log 和 binlog,这篇⽂章学习⼀下这两个⽇志的作⽤。
1.笔记图2.⼀条更新语句是如何被执⾏的连接器:负责跟客户端建⽴连接、获取权限、维持和管理连接分析器:词法分析:识别出 SQL 语句⾥⾯的字符串分别代表什么,把 SQL 语句中字符串 T 识别成“表名 T,把字符串 ID 识别成列 ID语法分析:根据词法分析的结果,语法分析器会根据语法规则,判断你输⼊的这个 SQL 语句是否满⾜ MySQL 语法优化器:优化器是在表⾥⾯有多个索引的时候,决定使⽤哪个索引,或者在⼀个语句有多表关联(join)的时候,决定各个表的连接顺序执⾏器:调⽤存储引擎提供的接⼝3.redo logWAL(Write-Ahead Logging):先写⽇志,再写磁盘当有记录需要更新时,InnoDB 引擎就会先把记录写到 redo log,并更新内存,这时更新就算完成InnoDB 的 redo log 是固定⼤⼩的,可以配置为⼀组 4 个⽂件,每个⽂件的⼤⼩是 1GB,从头开始写,写到末尾就⼜回到开头循环写Tips:write pos 表⽰当前记录的位置,写到第 3 号⽂件末尾后就回到 0 号⽂件开头,checkpoint 表⽰当前要擦除的位置,擦除记录前要把记录更新到数据⽂件如果 write pos 追上 checkpoint,表⽰ redo log 满了,这时不能再执⾏新的更新,得停下来先擦掉⼀些记录,把 checkpoint 推进⼀下crash-safe:InnoDB 就可以保证即使数据库发⽣异常重启,之前提交的记录都不会丢失4.binlogMySQL Server 层也有⾃⼰的⽇志,称为归档⽇志(binlog),binlog ⽇志只能⽤于归档redo log 是 InnoDB 引擎特有的,binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使⽤redo log 是物理⽇志,记录的是在某个数据页上做了什么修改,binlog 是逻辑⽇志,记录的是这个语句的原始逻辑,⽐如给 ID=2 这⼀⾏的 c 字段加 1redo log 是循环写的,空间固定会⽤完,binlog 是可以追加写⼊的,binlog ⽂件写到⼀定⼤⼩后会切换到下⼀个,并不会覆盖以前的⽇志5.为什么要有两份⽇志?最开始 MySQL ⾥并没有 InnoDB 引擎,MyISAM 没有 crash-safe 的能⼒,binlog ⽇志只能⽤于归档InnoDB 是另⼀个公司以插件形式引⼊ MySQL 的,使⽤另外⼀套⽇志系统 redo log 来实现 crash-safe 能⼒6.更新语句内部执⾏流程update T set c=c+1 where ID=2执⾏器先找引擎取 ID=2 这⼀⾏,ID 是主键,引擎直接⽤树搜索找到这⼀⾏,如果 ID=2 这⼀⾏所在的数据页本来就在内存中,就直接返回给执⾏器,否则,需要先从磁盘读⼊内存,然后再返回执⾏器拿到引擎给的⾏数据,把这个值加上 1,⽐如原来是 N,现在就是 N+1,得到新的⼀⾏数据,再调⽤引擎接⼝写⼊这⾏新数据引擎将这⾏新数据更新到内存中,同时将这个更新操作记录到 redo log ⾥⾯,此时 redo log 处于 prepare 状态。
第六天一,回顾1.外键: 关联关系(表与表之间: 表中字段指向另外一张表的主键)外键条件: 字段类型必须一致, 存储引擎必须为innodb外键约束:子表约束: 不能插入父表不存在的记录父表约束: 三种约束模式(district, cascade,set null), on delete set null on update cascade2.联合查询: union, 多表合并和单表不同查询条件联合查询使用order by: select语句必须使用括号; 还必须配合limit3.子查询: 查询语句中有查询语句分类: 按位置(from,where和exists), 按返回结果(用途):标量, 列,行和表4.视图: view节省SQL语句; 安全性控制视图本质: 虚拟表, 有结构无数据视图数据操作: 多表只能改, 单表可以增删改(增删有条件限制)视图算法: undefined未定义, temptable临时表和merge合并5.文件备份与还原文件备份: 存储引擎(myisam适用)单表数据备份: 只能备份数据SQL备份: 备份的是SQL指令(mysqldump.exe客户端备份)增量备份: 备份系统日志文件需求: 有一张银行账户表, 有A用户给B用户转账: A账户先减少, B账户增加. 但是A操作完之后断电了.解决方案: A减少钱, 但是不要立即修改数据表, B收到钱之后, 同时修改数据表.二,事务安全事务: transaction, 一系列要发生的连续的操作事务安全: 一种保护连续操作同时满足(实现)的一种机制事务安全的意义: 保证数据操作的完整性(存储引擎必须为innodb ,另一个可以用事务的是BDB但它收费)(事务操作只针对数据进行操作,若在事务内进行删表创表创数据库等操作,会先commit然后执行)1.事务操作事务操作分为两种: 自动事务(默认的), 手动事务①手动事务: 操作流程(data目录下的ib_logfile文件是日志文件)a.开启事务: 告诉系统以下所有的操作(写)不要直接写入到数据表, 先存放到事务日志Start transaction;(试:已经开启事务了,中途再Start transaction; ,相当于先commit再开启)(试:开启事务后,执行的查询语句,返回的是start transaction那一刻的数据经过日志内存的写操作语句加工后的结果,这时候提交事务后再查询的真实结果不一定就是这个)(试:某人开启事务的时候,对其他人的操作没有影响,其他人也可以操作数据库; 这个人开启事务的作用只是把开启事务后的写操作写入日志文件,相当于把日志内的所有操作数据的语句绑到一起再用commit提交或用rollback清空而已,把有可能不连续的操作连续起来而已)b.进行事务操作: 一系列操作李四账户减少张三账户增加c.关闭事务: 选择性的将日志文件中操作的结果保存到数据表(同步)或者直接清空事务日志(原来操作全部清空) ( 试:这两个命令都会退出事务,但commit会提交日志rollback会取消日志)1>提交事务: 同步数据表(操作成功): commit;2>回滚事务: 直接清空日志表(操作失败): rollback;2.事务原理事务操作原理: 事务开启之后, 所有的操作都会临时保存到事务日志, 事务日志只有在得到commit命令才会同步到数据表,其他任何情况都会清空(rollback, 断电, 断开连接)3.回滚点回滚点: 在某个成功的操作完成之后, 后续的操作有可能成功有可能失败, 但是不管成功还是失败,前面操作都已经成功: 可以在当前成功的位置, 设置一个点: 可以供后续失败操作返回到该位置, 而不是返回所有操作, 这个点称之为回滚点.设置回滚点语法: savepoint 回滚点名字;回到回滚点语法: rollback to 回滚点名字; (rollback to不会退出事务,但rollback会退出事务)2.自动事务处理(事务操作只针对数据进行操作,若关闭自动事务处理,再内进行删表创表创数据库等操作,会先commit再执行,帮你提交之前的操作;但之后的数据操作还是要commit 才能生效)在mysql中: 默认的都是自动事务处理, 用户操作完会立即同步到数据表中.自动事务: 系统通过autocommit变量控制Show variables like ‘autocommit’;关闭自动提交: set autocommit = off/0;再次直接写操作自动关闭之后,需要手动来选择处理: commit提交, rollback回滚注意: 通常都会使用自动事务4.事务特性事务有四大特性: ACIDA: Atomic原子性, 事务的整个操作是一个整体, 不可分割,要么全部成功,要么全部失败;C: Consistency, 一致性, 事务操作的前后, 数据表中的数据没有变化I: Isolation, 隔离性, 多方事务操作是相互隔离不受影响的.D: Durability, 持久性, 数据一旦提交, 不可改变,永久的改变数据表数据5.锁机制: innodb默认是行锁, 但是如果在事务操作的过程中, 没有使用到索引,那么系统会自动全表检索数据, 自动升级为表锁(事务内用索引定位的作写操作的时候,它会通过索引自动定位到那一条;但不用索引的话,他会全表搜索,查找所有记录;若行被锁住,别人用非索引定位没被锁住的行的话,会全表搜索会卡主,但别人用索引定位没被锁住的行时,不会被锁住)行锁: 只有当前行被锁住, 别的用户不能操作表锁: 整张表被锁住, 别的用户都不能操作三,变量变量分为两种: 系统变量和自定义变量1.系统变量系统定义好的变量: 大部分的时候用户根本不需要使用系统变量: 系统变量是用来控制服务器的表现的: 如autocommit, auto_increment_increment等①查看系统变量Show variables; -- 查看所有系统变量②查看具体变量值: 任何一个有数据返回的内容都是由select查看(试: 用select和show都可以查看变量值,只不过show查看列出的是所有变量,需要用like筛选;select查看是直接跟变量名,查看系统变量需要加两个@)Select @@变量名;③修改系统变量修改系统变量分为两种方式: 会话级别和全局级别a.会话级别: 临时修改, 当前客户端当次连接有效Set 变量名= 值;/Set @@变量名= 值;b.全局级别: 一次修改,永久生效(对所有客户端都生效,但必须重启会话才能生效)如果对方(其他)客户端当前已经连上服务器,那么当次修改无效,要退出重新登录才会生效Set global 变量名= 值; (这里不能加@@,加了报错)2.自定义变量①定义变量:系统为了区分系统变量, 规定用户自定义变量必须使用一个@符号Set @变量名= 值;②查看自定义变量:也是类似系统变量查看Select @变量名; (试:以上所有用set修改变量的方法和用select查看变量的方法,都可跟多个变量,用逗号隔开)3.在mysql中, “=”会默认的当做比较符号处理(很多地方), mysql为了区分比较和赋值的概念: 重新定义了一个新的的赋值符号: :=4.Mysql允许从数据表中获取数据,然后赋值给变量: 两种方式①方案1: 边赋值,变查看结果Select @变量名:= 字段名from 数据源; -- 从字段中取值赋值给变量名, 如果使用=会变成比较(若不用:=而用=,会把=号当比较符号, 把@变量名=字段名当成一个字段,下面的数据是他们比较的值,0或1 ; 若用:=,会每到一列就赋值一次然后显示.显示完了之后该变量的值为最后一行的那个字段的值)②方案2: 只有赋值不看结果: 要求很严格: 数据记录最多只允许获取一条: mysql不支持数组Select 字段列表from 表名into 变量列表; (字段列表和变量列表数量必须一致,记录只允许一条)所有自定义的变量都是会话级别: 当前客户端当次连接有效所有自定义变量不区分数据库(用户级别)四,触发器触发器: trigger, 事先为某张表绑定好一段代码,当表中的某些内容发生改变的时候(增删改)系统会自动触发代码,执行.触发器: 事件类型, 触发时间, 触发对象事件类型: 增删改, 三种类型insert,delete和update(试:在一个表上做3个触发器,分别为after的增删改,若你用一条insert或delete或update语句插入或删除或改动了多条数据,动了几条,他们就会触发对应的触发器几次,没成功不触发; 若没有唯一键或主键冲突的时候,replace和insert的作用一样,触发器行为也一样)(试:有主键冲突情况下Replace的触发行为,完全等价于先delete再insert,哪怕replace的新数据与原表中需要替换的旧数据一模一样,也相当于先删旧的再添新的;一条sql语句replace多条记录,等价于把该条sql语句拆分成多条sql语句运行的效果!!!)(replace操作在唯一键或主键冲突时永远相当于先删再添,如果表中有多个字段都有唯一键,你要插入的一条数据跟表中的多条记录都冲突了,那么会先把那多条记录删掉,再把新数据添进表中,完成后delete触发器触发多次,inset触发器触发一次!)(用insert into…on duplecate key update…: 在主键和唯一键冲突时,运行了更新操作的话,就会update触发器触发一次;没冲突运行了插入操作就会insert触发器触发一次)(若某条增删改语句加了触发器,当你运行增删改的时候,本身的增删改是没问题的,但他即将触发的事件因为某种原因(如超范围或唯一键约束等)运行不了,那么那个增删改也不能运行,触发事件也不会发生,可以这么理解,触发导火线和将触发的事件,要不就都发生要不就都不发生)触发时间: 前后: before和after (和上面3种的组合方式一共有6种)触发对象: 表中的每一条记录(针对行)一张表中只能拥有一种触发时间的一种类型的触发器: 最多一张表能有6个触发器1.创建触发器在mysql高级结构中: 没有大括号, 都是用对应的字符符号代替触发器基本语法:①-- 临时修改语句结束符(试:这是会话级别)Delimiter 自定义符号-- 后续代码中只有碰到自定义符号才算结束(这条语句没有结束符)②--创建触发器(试: 把触发器装在某个表上,触发后的执行语句不能对这个表进行操作,因为此表触发了触发器,触发器内容没执行完的时候就被锁住了)(试:触发器触发后的执行语句不能是查询操作,因为触发触发后不允许有返回值,触发器触发后的执行语句也不能是删表操作)Create trigger 触发器名字触发时间事件类型on 表名for each rowBegin -- 代表左大括号: 开始……-- 里面就是触发器的内容: 每行内容都必须使用语句结束符: 分号End -- 代表右带括号: 结束自定义符号-- 语句结束符③-- 将临时修改修正过来Delimiter ;2.查看触发器查看所有触发器或者模糊匹配Show triggers [like ‘pattern’];可以查看触发器创建语句Show create trigger 触发器名字; (试:这只能查看当前数据库的索引触发器)所有的触发器都会保存一张表中: Information_schema.triggers3.使用触发器触发器: 不需要手动调用, 而是当某种情况发生时会自动触发.(订单里面插入记录之后)4.修改触发器&删除触发器触发器不能修改,只能先删除,后新增.Drop trigger 触发器名字;5.触发器记录触发器记录: 不管触发器是否触发了,只要当某种操作准备执行, 系统就会将当前要操作的记录的当前状态和即将执行之后新的状态给分别保留下来, 供触发器使用: 其中, 要操作的当前状态保存到old中, 操作之后的可能形态保存给new.Old代表的是旧记录,new代表的是新记录删除的时候是没有new的; 插入的时候是没有oldOld和new都是代表记录本身: 任何一条记录除了有数据, 还有字段名字.使用方式: old.字段名/ new.字段名(new代表的是假设发生之后的结果)查看触发器的效果如果触发器内部只有一条要执行的SQL指令, 可以省略大括号(begin和end)Create trigger 触发器名字触发时间事件类型on 表名for each rowSQL指令;触发器: 可以很好的协调表内部的数据处理顺序和关系. 但是从PHP角度出发, 触发器会增加数据库维护的难度, 所以较少使用触发器.五,代码执行结构(if-then-else和while好像都只能在procedure或是function里用??)代码执行结构有三种: 顺序结构, 分支结构和循环结构1.分支结构分支结构: 事先准备多个代码块, 按照条件选择性执行某段代码.在mysql中只有if分支基本语法If 条件判断then……;-- 满足条件要执行的代码;[Else……; ] -- 不满足条件要执行的代码;End if;触发器结合if分支: 判断商品库存是否足够,不够不能生成订单. mysql内没有专门的语句的阻止某条sql语句的发生,所以可以在不希望某条语句发生的触发器内if后面跟一条语法错误的语句,暴力终止,触发器内的语句执行不了了,那么原来触发触发器的语句也就执行不了了.(试:下例其实也可以直接把库存的类型改成int signed,就不需要加这种验证了)效果2.循环结构循环结构: 某段代码在指定条件执行重复执行. While循环(没有for循环) (还有个循环叫loop,跟while是一样的,所以只讲一个)①语法结构:While 条件判断do……;-- 满足条件要执行的代码……;-- 变更循环条件End while;②循环控制: 在循环内部进行循环判断和控制Mysql中没有对应continue和break. 但是有替代品.Iterate: 迭代, 类似continue, 后面的代码不执行, 循环重新来过Leave: 离开, 类似break,整个循环接收使用方式: Itrate/leave 循环名字;③定义循环名字:循环名字:while 条件do……; -- 循环体……;-- 循环控制Leave/iterate 循环名字;End while;六,函数函数: 将一段代码块封装到一个结构中, 在需要执行代码块的时候, 调用结构执行即可.(代码复用) 函数分为两类: 系统函数和自定义函数1.系统函数系统定义好的函数, 直接调用即可.任何函数都有返回值, 因此函数的调用是通过select调用.Mysql中,字符串的基本操作单位(最常见的是字符)怎么查看操作手册:打开操作手册在左边的目录里选中要查询的大类,再点击一下右边的正文处ctrl+f输入查询内容查询常用系统函数:Substring: 字符串截取(字符为单位)char_length: 字符长度Length: 字节长度Instr: 判断字符串是否在某个具体的字符串中存在, 存在返回位置,不存在返回0;(位置都是从1开始)Lpad: 左填充, 将字符串按照某个指定的填充方式,填充到指定长度(字符)(填就从左边开始填; 不够原始长度也是从左边开始读,读到指定长度为止)(Rpad:右填充) (填也是从左边开始填,不够原始长度也是读从左边开始读到指定长度)Insert: 替换,找到目标位置,指定长度的字符串,替换成目标字符串Strcmp: compare,字符串比较(区不区分大小写跟校对集有关,默认的校对集不区分大小写) (类似java中String的compareTo方法,但小返回-1,大返回1,等于返回0)2.自定义函数(试: 只对当前数据库有效,只要不删永久有效,非会话级别) (试:函数体内写select查询语句输出会报错,但用于赋值不会报错)(试:函数内不能增删表,不然报错;函数可以对某表内的数据进行写操作;但函数内不能有查询后的输出语句,可以有查询后的赋值语句!!)(试:函数不能什么都不加,直接调用,如: Function(); )(调用函数的时候中途报错退出函数的话,报错之前的代码有效!!!)函数要素: 函数名, 参数列表(形参和实参), 返回值, 函数体(作用域)①创建函数:创建语法: (这里也是,如果函数里只有一条语句,则begin和end可以省略不写) (自定义函数必须有返回值)Delimiter 结束符Create function 函数名([形参列表]) returns 数据类型-- 规定要返回的数据类型Begin……;-- 函数体……;-- 返回值: return 类型(指定数据类型);End结束符Delimiter ;定义函数自定义函数与系统函数的调用方式是一样: select 函数名([实参列表]);②查看函数查看所有函数: show function status [like ‘pattern’];查看函数的创建语句: show create function 函数名;③修改函数&删除函数函数只能先删除后新增,不能修改.Drop function 函数名;④函数参数参数分为两种: 定义时的参数叫形参, 调用时的参数叫实参(实参可以是数值也可以是变量)形参: 要求必须指定数据类型Function 函数名(形参名字字段类型) returns 数据类型在函数内部使用@定义的变量在函数外部也可以访问,在函数外部@定义的全局变量函数内也能使用,但类型不兼容的全局变量赋值给局部变量,在函数调用的时候会报错④作用域Mysql中的作用域与js中的作用域完全一样(任何变量只要你要修改,就要用set关键字)全局变量可以在任何地方使用; 局部变量只能在函数内部使用.全局变量: 使用set关键字定义, 使用@符号标志(跨数据库也能使用)局部变量: 使用declare关键字声明, 没有@符号: 所有的局部变量的声明,必须在函数体开始之前七,存储过程存储过程简称过程,procedure, 是一种用来处理数据的方式.存储过程是一种没有返回值的函数.(存储过程与函数不同,他里面可以放查询语句,里面也可以增删表,也可以增删数据库) (存储过程只对当前数据库有效,非会话级别)(调用存储过程,执行的中途报错退出了的话.错误之前的代码有效!!!)1.创建过程Delimiter 结束符Create procedure 过程名字([参数列表])Begin……; -- 过程体End结束符Delimiter ;2.查看过程函数的查看方式完全适用于过程: 关键字换成procedure 查看所有过程: show procedure status [like ‘pattern’];查看过程创建语句: show create procedure 过程名;3.调用过程过程没有返回值: select是不能访问的.过程有一个专门的调用关键字: call4.修改过程&删除过程过程只能先删除,后新增Drop procedure 过程名;5.过程参数函数的参数需要数据类型指定, 过程比函数更严格.过程还有自己的类型限定: 三种类型In: 数据只是从外部传入给内部使用(值传递): 可以是数值也可以是变量Out: 只允许过程内部使用(不用外部数据), 给外部使用的.(引用传递: 外部的数据会被先清空才会进入到内部): 只能是变量Inout: 外部可以在内部使用,内部修改也可以给外部使用: 典型的引用传递: 只能传变量①基本使用Create procedure 过程名(in 形参名字数据类型, out 形参名字数据类型, inout 形参名字数据类型)调用: out和inout类型的参数必须传入变量,而不能是数值正确调用: 传入变量存储过程对于变量的操作(返回)是滞后的: 是在存储过程调用结束的时候,才会重新将内部修改的值赋值给外部传入的全局变量.测试: 传入数据1,2,3: 说明局部变量与全局变量无关最后: 在存储过程调用结束之后, 系统会将局部变量重复返回给全局变量(out和inout)。
mysql学习笔记(⼀)之mysqlparameter基础琐碎总结-----参数化查询参数化查询(Parameterized Query )是指在设计与数据库链接并访问数据时,在需要填⼊数值或数据的地⽅,使⽤参数 (Parameter) 来给值,这个⽅法⽬前已被视为最有效可预防SQL注⼊攻击 (SQL Injection) 的攻击⼿法的防御⽅式。
下⾯将重点总结下Parameter构建的⼏种常⽤⽅法。
说起参数化查询当然最主要的就是如何构造所谓的参数:⽐如,我们登陆时需要密码和⽤户名,⼀般我们会这样写sql语句,Select * from Login where username= @Username and password = @Password,为了防⽌sql注⼊,我们该如何构建@Username和@Password两个参数呢,下⾯提供六种(其实⼤部分原理都是⼀样,只不过代码表现形式不⼀样,以此仅作对⽐,⽅便使⽤)构建参数的⽅法,根据不同的情况选⽤合适的⽅法即可:说明:以下loginId和loginPwd是户登陆时输⼊登陆⽤户名和密码,DB.conn是数据库连接,⽤时引⼊using System.Data.SqlClient命名空间⽅法⼀:SqlCommand command = new SqlCommand(sqlStr, DB.conn);command.Parameters.Add("@Username", SqlDbType.VarChar);command.Parameters.Add("@Pasword", SqlDbType.VarChar);command.Parameters["@Username"].Value = loginId;command.Parameters["@Pasword"].Value = loginPwd;⽅法⼆:SqlCommand command = new SqlCommand();command.Connection = DB.conn;mandText = sqlStr;command.Parameters.Add(new SqlParameter("@Username", loginId));command.Parameters.Add(new SqlParameter("@Pasword", loginPwd));⽅法三:Sqlcommand cmd=new Sqlcommand(sqlStr, DB.conn);cmd.parameters.add("@Username",DbType.varchar).value=loginId;cmd.parameters.add("@Pasword",DbType.varchar).value=loginPwd;⽅法四:Sqlcommand cmd=new Sqlcommand(sqlStr, DB.conn);cmd.parameters.addwithvalue("@Username",loginId);cmd.parameters.addwithvalue("@Pasword",loginPwd);⽅法五:Sqlcommand cmd=new Sqlcommand(sqlStr, DB.conn);SqlParameter para1=new SqlParameter("@Username",SqlDbType.VarChar,16);para1.Value=loginId;cmd.Parameters.Add(para1);SqlParameter para2=new SqlParameter("@Pasword",SqlDbType.VarChar,16);para2.Value=loginPwd;cmd.Parameters.Add(para2);⽅法六:SqlParameter[] parms = new SqlParameter[]{new SqlParameter("@Username", SqlDbType.NVarChar,20),new SqlParameter("@Pasword", SqlDbType.NVarChar,20),};SqlCommand cmd = new SqlCommand(sqlStr, DB.conn);// 依次给参数赋值parms[0].Value = loginId;parms[1].Value = loginPwd;//将参数添加到SqlCommand命令中foreach (SqlParameter parm in parms){cmd.Parameters.Add(parm);}法和实现⽅法的不同,也可以说是语法糖,但后记:鉴于园友对dedeyi,⿁⽕飘荡,guihwu的疑问,我在写⼀个说明。
mysql多表操作与练习数据库备份与恢复◆数据库备份◆数据库恢复多表操作◆多表设计◆外键介绍与创建◆多表查询介绍◆多表查询-内连接◆多表查询-外连接◆多表查询-子查询SQL练习【内容:数据库备份与恢复】数据库备份数据库的备份是指将数据库转换成对应的sql文件。
数据库导出sql脚本的命令如下:●mysqldump –u用户名–p密码数据库名>生成的脚本文件路径;以上备份数据库的命令中需要用户名和密码,即表明该命令要在用户没有登录的情况下使用数据库恢复数据库的恢复指的是使用备份产生的sql文件恢复数据库,即将sql文件中的sql语句执行就可以恢复数据库内容。
因为数据库备份只是备份了数据库内容,所以备份产生的sql文件中没有创建数据库的sql语句,在恢复数据库之前需要自己动手创建数据库。
●在数据库外恢复mysql -u root -p 数据库名< 文件路径注意:要求数据库必须先创建出来.●.在数据库内恢复source SQL脚本路径:使用这种方式恢复数据,首先要登录数据库【重点总结】备份Mysqldump –u root –p abc mydb>c:/mydb.sql恢复1.mysql –u root –p mydb<c:/mydb.sql2.source c:/mydb.sql掌握多表设计掌握外键的作用及创建方式了解多表查询原理及迪卡尔积掌握内连接掌握外连接掌握子查询【内容:多表操作】多表设计当我们要完成一个软件系统时,需要把系统中的实体抽取出来,形成概念模型。
例如部门、员工都是系统中的实体。
概念模型中的实体最终会成为Java中的类、数据库中的表。
今天我们需要了解的概念模型包括以下两个:●对象模型:针对java中的实体类,例如我们之前学习的domain层中的User类等;●关系模型:对应数据库中的表。
在java中有以下三个关系描述:●is a:例如猫是动物,表示继承关系;●has a:例如人有两只手,表示的是类与成员的关系;●use a:表示类与方法之间的关系;我们今天主要关注的是第二个关系:类与成员的关系。
这种关联关系可以分为如下三种:●一对一关联:例如身份证与人就是一对一的关系,一个人只有一个身份证,一个身份证号只属于一个人。
●一对多关联:例如用户与订单,一个用户可以拥有多个订单,多个订单可以属于同一个用户,这是一个很明显的一对多关联。
●多对多关联:例如商品与订单,一个订单中可以包含多个商品,而一个商品也可以存在于多个订单中,这就是一个多对多关联。
概念模型在java中对应这实体类,在实体类中使用成员变量完成关联关系,而且一般都是双向关联,以下是java中实体类与成员之间的关联关系,如下所示:一对一关联//身份证类一的一方public class IDCard {private Person person; //身份证关联人类一对一}//人类一的一方public class Person {private IDCard idcard; //人类关联身份证类一对一}一对多关联//用户一的一方public class User {private List<Order> orders; //用户可以有多个订单,在用户中关联订单}//订单多的一方public class Order {private User user; //多个订单可以属于一个用户,在订单中关联用户}多对多关联// 订单多的一方public class Order {private List<Product> products;//订单中可以包含多个商品,订单关联商品// 商品多的一方public class Product {private List<Order> orders;//一个商品可以包含在多个订单中在商品关联订单}外键约束概念模型在数据库中就对应数据表,那么表与表之间的关系也包括:一对一,一对多,多对多。
而表与表之间关系是通过外键来维护的。
外键约束特性如下:●外键必须是另一表或自身表的主键的值;●外键可以重复;●外键可以为空;●一张表中可以有多个外键。
表之间关联关系●一对一person表CREATE TABLE person(id INT PRIMARY KEY AUTO_INCREMENT,NAME V ARCHAR(20) -- 姓名)idcard表CREATE TABLE idcard(id INT PRIMARY KEY AUTO_INCREMENT,num V ARCHAR(20) -- 身份证号)上述是我们创建的person表与idcard表,它们之间是一对一关系,那么我们怎样来描述一个人只有一个身份证,而一个身份证只能属于一个人哪?我们只需要在任意一张表中添加一个外键字段,与主表中的主键字段对应就可以描述其一对一的关系。
person表CREATE TABLE person(id INT PRIMARY KEY AUTO_INCREMENT,NAME V ARCHAR(20), -- 姓名idcard_id int)idcard表CREATE TABLE idcard(id INT PRIMARY KEY AUTO_INCREMENT,num V ARCHAR(20), -- 身份证号pid int)●一对多用户表id INT PRIMARY KEY AUTO_INCREMENTNAME V ARCHAR(20))订单表CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT,price DOUBLE,)上述是订单与用户表,一个用户是可以有多个订单的,它们是很明显的一个一对多(多对一)的关系,那么我们怎样在表中描述它们的对应关系。
CREATE TABLE USER(id INT PRIMARY KEY AUTO_INCREMENTNAME V ARCHAR(20))CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT,price DOUBLE,uid INT)多对多订单表CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT,price DOUBLE)商品表CREATE TABLE products(id INT PRIMARY KEY AUTO_INCREMENT,NAME V ARCHAR(30))订单与商品之间是一个很明显的多对多关系,那么我们怎样在表中描述它们的关系订单表CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT,price DOUBLE)商品表CREATE TABLE products(id INT PRIMARY KEY AUTO_INCREMENT,NAME V ARCHAR(30))订单与商品关联表-中间表oid INT,pid INT,PRIMARY KEY(oid,pid))总结:对于一对一关系,我们在表中描述时,可以在任意一方描述对于一对多关系,我们在表中描述时,在多的一方描述对于多对多关系,我们在表中描述时,会产生一个中间表外键约束作用:通过外键约束可以保证数据的完整性。
我们以用户与订单(一对多关联)来说明一下关于外键约束作用:-- 用户表CREATE TABLE USER(uid INT PRIMARY KEY AUTO_INCREMENT, -- 用户编号NAME V ARCHAR(20) -- 用户姓名)-- 订单表CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT, -- 订单编号money DOUBLE, -- 订单总价receiveraddress V ARCHAR(50), -- 订单收货地址uid INT -- 用户id)我们向表中插入数据INSERT INTO USER V ALUES(NULL,"tom");INSERT INTO USER V ALUES(NULL,"fox");INSERT INTO orders V ALUES(NULL,1000,"北京",1);INSERT INTO orders V ALUES(NULL,2000,"上海",1);INSERT INTO orders V ALUES(NULL,3000,"广州",2);INSERT INTO orders V ALUES(NULL,4000,"深圳",2);通过数据很明显可以看出,tom有两个订单,订单编号为1,2.fox有两个订单,订单编号为3,4 那么我们执行下面这条sql:DELETE FROM USER WHERE uid=1;这时,我们会发现,在user表中已经将uid=1的用户删除了,但是在orders表中还存在uid=1的用户的订单,破坏了数据的完完整性。
(不应该出现无用户的订单)那么如果我们修改一下表结构,将orders表中的uid设置成外键,在看一下结果。
对于添加外键方式我们可以在创建表时添加,也可以在表创建后在添加外键。
●表创建后添加外键ALTER TABLE orders ADD CONSTRAINT FK_UID FOREIGN KEY(uid) REFERENCES USER(uid);注意:上面操作中已经将uid=1的用户删除了,所以在添加外键时,会报错,将数据重新添加或重新建表就可以。
●创建表时指定外键CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT, -- 订单idmoney DOUBLE, -- 订单总价receiveraddress V ARCHAR(50), -- 订单收货地址uid INT, -- 用户idCONSTRAINT FK_UID FOREIGN KEY orders(uid) REFERENCES USER(uid) )当我们给orders表中的uid添加外键后,我们在执行DELETE FROM USER WHERE uid=1;会发现报错Query : delete from user where uid=1Error Code : 1451Cannot delete or update a parent row: a foreign key constraint fails (`mydbtest`.`orders`, CONSTRAINT `FK_UID` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`))原因就是因为我们添加了外键,所以我们在删除主表中数据时,要先将子表中数据删除后,才可以删除主表数据。