增删改查

SELECT prod_id, prod_name, prod_price
FROM Products; SELECT *
FROM Products; //增
INSERT INTO Customers
VALUES(' ',' '); UPDATE Customers
SET cust_email = ' '
WHERE cust_id = ' '; DELETE FROM Customers
WHERE cust_id = ' ';

创建表

CREATE TABLE Products
(
prod_id CHAR(10) NOT NULL,
vend_id CHAR(10) NOT NULL,
prod_name CHAR(254) NOT NULL,
prod_price DECIMAL(8,2) NOT NULL,
prod_desc VARCHAR(1000) NULL
);

限制查询结果

这种方式只支持MySQL、 MariaDB、 PostgreSQL 或者 SQLite数据库,SQL只是大致相同

SELECT prod_name
FROM Products
LIMIT 5 OFFSET 5;

IF表达式

IF( expr1 , expr2 , expr3 )

expr1 的值为 TRUE,则返回值为 expr2

expr1 的值为FALSE,则返回值为 expr3

排序数据

ORDER BY 位于WHERE之后;数据排序默认是升序排序,为了使用降序排序,必须指定DESC关键字

SELECT * FROM Products
ORDER BY prod_name DESC;//降序排列 SELECT * FROM Products
ORDER BY prod_price, prod_name//仅在多个行具有相同的 prod_price 值时才对产品按 prod_name 进行排序。如果 prod_price 列中所有的值都是唯一的,则不会按 prod_name 排序

过滤数据

数据过滤不应该在应用层完成,首先是会消耗应用性能,另外占用额外的带宽资源。

WHERE a <= 10【条件是a小于等于10】 WHERE a <> 10【例举出a不为10的所有结果】或者 WHERE a!=10

单引号用来限定字符串。如果将值与字符串类型的列进行比较,就需要限定引号。用来与数值列进行比较的值不用引号

SELECT * FROM Products
WHERE prod_price = 3.49; WHERE prod_price IS NULL//空值检查

可以通过AND 子句或 OR 子句组合多个WHERE 条件

WHERE vend_id = 'DLL01' AND prod_price <= 4;//WHERE 子句可以包含任意数目的 AND 和 OR 操作符,AND操作符优先

CASE

CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END; CASE compare_value
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END;

IN操作符

IN 操作符用来指定条件范围,范围中的每个条件都可以进行匹配。 IN 取一组由逗号分隔、括在圆括号中的合法值

WHERE vend_id IN ( 'DLL01', 'BRS01' )

范围值检查BETWEEN AND

SELECT prod_name, prod_price
FROM Products
WHERE prod_price BETWEEN 5 AND 10;

通配符&LIKE

最常使用的通配符是百分号( %)。在搜索串中, %表示任何字符出现任意次数,但是%无法匹配NULL

另一个有用的通配符是下划线( _)。下划线的用途与%一样,但它只匹配单个字符

方括号( [])通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符

WHERE cust_contact LIKE '[JM]%'

WHERE cust_contact LIKE '[^JM]%'//否定集合

MYSQL拼接

SELECT Concat(vend_name, ' (', vend_country, ')')
FROM Vendors
ORDER BY vend_name;

算术计算

SELECT prod_id,
quantity,
item_price,
quantity*item_price AS expanded_price

聚集函数

对某些行运行的函数,计算并返回一个值;AVG()通过对表中行数计数并计算其列值之和,求得该列的平均值;COUNT()函数进行计数;SUM()用来返回指定列值的和

SELECT COUNT(*) AS num_cust
FROM Customers;

如果只需要聚集不同值,需要指定指定 DISTINCT 参数

SELECT AVG(DISTINCT prod_price) AS avg_price
FROM Products
WHERE vend_id = 'DLL01';

分组GROUP BY&HAVING

HAVING允许过滤分组

SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;

等值联结表

SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;

由没有联结条件的表关系返回的结果称为笛卡尔积(检索出的行的数目将是第一个表中的行数乘以第二个表中的行数)

内联结

内联结是查找出同时存在于两张表中的数据,

SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;

左联结&右联结

左联结,会将左侧表中的数据全部取出来

SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Orders.cust_id;

子查询

SQL 允许创建子查询( subquery),即嵌套在其他查询中的查询;

另外,如果在SELECT 语句中操作多个表,就应使用完全限定列名来避免歧义。

SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM Orders
WHERE cust_id = cust_id) AS orders
FROM Customers
ORDER BY cust_name;

事务

事务用于为SQL数据库提供原子性操作

SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
SHOW VARIABLES LIKE '%AUTOCOMMIT%' #查看是否开启自动提交

Set Autocommit=0;

开启事务:SET TRANSACTION [ READ WRITE | READ ONLY ];

提交:COMMIT;

回滚:ROLLBACK

事务ACID

原子性、一致性、隔离性、持久性

MySQL 中执行事务以 begin 或者 start transaction 开始,然后执行一系列操作,最后要执行 commit 操作,事务才算结束。当然,如果进行回滚操作(rollback),事务也会结束

隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)

脏读指的是读到了其他事务未提交的数据,数据可能回滚

不可重复读指的在同一事务内,不同的时刻读到的同一批数据可能是不一样的

幻读:幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行

串行化:读的时候加共享锁,也就是其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

MVCC(多版本并发控制)

MySQL中,每一行数据会有两个隐藏字段:trx_id、rollback_pointer; 事务ID只有执行第一条更新语句后才会生成。rollback_pointer用于找到当前行的历史数据。

在可重复读的隔离级别下,Mysql只会在第一次执行查询语句的时候生成快照read-view,在读已提交的隔离级别下,每次查询语句都会重新生成快照。

MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作

Read-View中主要就是有个列表来存储我们系统中当前活跃着的读写事务,也就是begin了还未提交的事务:

  1. low_trx_id表示该SQL启动时,当前事务链表中最大的事务id编号,也就是最近创建的除自身以外最大事务编号;
  2. up_trx_id表示该SQL启动时,当前事务链表中最小的事务id编号,也就是当前系统中创建最早但还未提交的事务;
  3. trx_ids表示所有事务链表中事务的id集合。

通过这个列表来判断记录的某个版本是否对当前事务可见。

MySQL(3306)与Redis一致性问题

强一致性:写操作同时往数据库和redis上写

弱一致性:

清空缓存

构建一个服务器,实现一个定时任务,定时去查询Mysql上变化的数据,更新到redis上

通过canal服务器访问Mysql的binlog文件,将变化数据推送到MQ上,由MQ消费者同步到redis上

利用redis缓存失效策略,redis热键快速失效,保证一定延时下的数据最终一致性。当多个线程在redis上查询不到数据时,加入线程锁,只让单个线程访问Mysql,并把结果写会redis,如此被写回的线程直接访问redis即可

索引语法

show index from table_name;//查看索引

一句删除mysql中重复语句:

DELETE FROM vitae WHERE peopleId NOT IN(SELECT dt.minno FROM (SELECT MIN(peopleId) AS minno FROM vitae GROUP BY seq) dt);

MySQL整合Spring

spring.datasource.url=jdbc:mysql://localhost:3306/lou_springboot?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456

组合SQL语句

SELECT * FROM account
WHERE NAME IN(
SELECT NAME FROM account GROUP BY NAME HAVING COUNT(*)>1 这里不能有封号,另外GROUP BY后面只能加 Having
AND
id NOT IN(12)

读出所有不重复的数据

SELECT * FROM ACCOUNT WHERE ID NOT IN(
SELECT ID FROM ACCOUNT
GROUP BY NAME HAVING COUNT(*)>1
)

但是,在MySQL中,不能先select出同一表中的某些值,再update这个表(在同一语句中),否则会出现1093错误

InnoDB引擎

InnoDB支持事务、外键,采用聚集索引结构(数据索引不分离),不保存表的行数。

在InnoDB中,表数据文件本身就是按照B+Tree组织的一个单索引结果文件,在B+树中,叶节点包含了完整的数据结构,InnoDB表必须要有主键,没有MySql底层会有一套方法维护一套主键。同时主键最好是自增整型,减小比较的消耗和减小插入消耗。

B+树索引可以很好支持范围查找,而hash索引和B树对范围查找并不友好。

MySQL分布式存储

读写分离

基于主从复制架构,由从库分担读压力,主库将变更写入 binlog 日志,然后从库连接到主库之后,从库有一个 IO 线程,将主库的 binlog 日志拷贝到自己本地,写入一个 relay 中继日志中。接着从库中有一个 SQL 线程会从中继日志读取 binlog,然后执行 binlog 日志中的内容,保证从库和主库数据的一致性。

集群:

分库分表,将数据存放在不同的集群中,分担数据库写压力

数据存储方案:

一些关系型字段信息的存储方案: Oracle、MySQL

文档数据存储方案:MongoDB

图片数据存储方案:FastDFS、TFS、GFS、HDFS、oss

搜索引擎: solr、elasticsearch、Isearch

热点数据、日志系统:Redis、Tair

拓扑结构图:Neo4j、InfoGrid

SQL索引失效

1.当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效

2.在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描

3.在索引列上使用 IS NULL 或 IS NOT NULL操作可能导致索引失效

4.like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效

5.or语句前后没有同时使用索引。

SQL索引适用范围

  1. 数据量少的不适合加索引
  2. 更新比较频繁的也不适合加索引
  3. 区分度低的字段不适合加索引(如性别)

SQL慢查询优化

explain + 查询SQL,根据参考信息可以进行SQL优化;

加索引、避免返回不必要的数据、适当分批量进行、优化sql结构、分库分表、读写分离

InnoDB与MyISAM的区别

  1. InnoDB支持事务,MyISAM不支持事务
  2. InnoDB支持外键,MyISAM不支持外键
  3. InnoDB 支持 MVCC(多版本并发控制),MyISAM 不支持
  4. select count(*) from table时,MyISAM更快,因为它有一个变量保存了整个表的总行数,可以直接读取,InnoDB就需要全表扫描。
  5. Innodb不支持全文索引,而MyISAM支持全文索引(5.7以后的InnoDB也支持全文索引)
  6. InnoDB支持表、行级锁,而MyISAM支持表级锁。
  7. InnoDB表必须有主键,而MyISAM可以没有主键
  8. Innodb表需要更多的内存和存储,而MyISAM可被压缩,存储空间较小,。
  9. Innodb按主键大小有序插入,MyISAM记录插入顺序是,按记录插入顺序保存。
  10. InnoDB 存储引擎提供了具有提交、回滚、崩溃恢复能力的事务安全,与 MyISAM 比 InnoDB 写的效率差一些,并且会占用更多的磁盘空间以保留数据和索引

数据库的三大范式

  1. 第一范式:数据表中的每一列(每个字段)都不可以再拆分。
  2. 第二范式:在第一范式的基础上,分主键列完全依赖于主键,而不能是依赖于主键的一部分。
  3. 第三范式:在满足第二范式的基础上,表中的非主键只依赖于主键,而不依赖于其他非主键。

百万级别或以上的数据删除方式

  1. 我们想要删除百万数据的时候可以先删除索引
  2. 然后批量删除其中无用数据
  3. 删除完成后重新创建索引

MYSQL死锁

  1. 如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
  2. 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
  3. 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
  4. 如果业务处理不好可以用分布式事务锁或者使用乐观锁

创建索引的三种方式

在执行CREATE TABLE时创建索引

CREATE TABLE `employee` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`date` datetime DEFAULT NULL,
`sex` int(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

使用CREATE INDEX命令创建

create (unique) index 索引名 on 表名(列名);

CREATE INDEX 索引名 ON 表名(列名,列名,。。。);//创建联合索引,联合索引底层也是B+树,比较原则是先比较第一个字段,然后再比较第二个字段。所以只有使用最左前缀法则才会走联合索引

唯一索引

添加唯一性索引的数据列可以为空,但是只要存在数据值,就必须是唯一的。主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。当在查询中使用主键索引时,它还允许快速访问数据。数据不能为空

存储过程

Mysql5 开始支持存储过程

DROP PROCEDURE IF EXISTS produce_name();  -- 没有括号()

//存储过程语法
DELIMITER ;;
CREATE PROCEDURE `select_students_count`()
BEGIN
SELECT count(id) from students;
END;;
DELIMITER ; //带参数的存储过程
DELIMITER ;; CREATE PROCEDURE `select_students_by_city_count`(
in _city varchar(225)
)
BEGIN
SELECT count(id) from students where city = _city;
END;;
DELIMITER ; //带输入输出参数的存储过程
DELIMITER ;; CREATE PROCEDURE `select_students_by_name`(
in _name varchar(225), -- 输入参数
out _city varchar(225), -- 输出参数
inout _age int(11) -- 输入输出参数
)
BEGIN SELECT city from students where name = _name and age = _age into _city; END;;
DELIMITER ;

MySQL支持IN(传递给存储过程),OUT(从存储过程传出)和INOUT(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGINEND语句内,如前所见,它们是一系列SELECT语句,用来检索值,然后保存到相应的变量(通过指定INTO关键字)

SQL数据库和语法的更多相关文章

  1. SQL数据库基础语法

    SQL语句的概述 SQL语言的分类 数据定义语言(Data Definition Language)主要用于修改.创建和删除数据库对象,其中包括CREATE  ALTER  DROP语句. 数据查询语 ...

  2. Microsoft SQL Server学习(二)--数据库的语法

    关于数据库的语法 创建数据库 样例 名词概念 编写数据库代码的注意事项 关于文件语法 实例代码 关于数据库的语法: 1.创建数据库 create database 数据库名 on primary (主 ...

  3. SQL中部分语法整理

    1.SELECT DISTINCT 语句 关键词DISTINCT用于返回唯一不同的值. 语法: SELECT DISTINCT 列名称 FROM 表名称 2.SELECT INTO语句 SELECT ...

  4. SQL server存储过程语法及实例(转)

    存储过程如同一门程序设计语言,同样包含了数据类型.流程控制.输入和输出和它自己的函数库. --------------------基本语法-------------------- 一.创建存储过程cr ...

  5. 动态sql语句基本语法--Exec与Exec sp_executesql 的区别

    http://www.cnblogs.com/goody9807/archive/2010/10/19/1855697.html 动态sql语句基本语法 1   :普通SQL语句可以用Exec执行   ...

  6. SQL数据库之变量

    --学习SQL数据库,变量是必须要掌握的概念,系统变量就是变量中最重要的变量之一,下面是SQL中系统变量的应用实例 use AdventureWorksDW exec sp_addtype 'char ...

  7. SQL VIEW 使用语法

    之前一直都不知道VIEW有什么作用,写程序的时候也很少遇到过,复习SQL语句的时候碰到了,就记录下来吧. 什么是视图? 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列, ...

  8. [SQL]动态sql语句基本语法

    动态sql语句基本语法 :普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_ex ...

  9. SQL[连载2]语法及相关实例

    SQL[连载2]语法及相关实例 SQL语法 数据库表 一个数据库通常包含一个或多个表.每个表由一个名字标识(例如:"Websites"),表包含带有数据的记录(行). 在本教程中, ...

  10. Android - 数据存储 -在SQL数据库中保存数据

    对于重复的或结构化的数据,保存到数据库中是很好的选择,比如联系人信息.这里假设你对SQL数据库大体上了解然后帮助你学习Android上的SQLite数据库.在Android数据库上需要用到的API可以 ...

随机推荐

  1. rclone挂载对象存储到本地

    一.原理图 二.挂载步骤 1.申请对象存储资源 (略) 2.下载rclone https://rclone.org/downloads/ 3.上传服务器,解压并安装 sudo unzip rclone ...

  2. CSP-J入门组

    setw(2) cout<<setw(2) //设置后面显示字符的宽度为2 cout<<fixed<<setprecision(6)<<变量名;//设置 ...

  3. kibana7.6.2内网windows系统下编译打包部署

    1.在kibana根目录下执行命令: yarn build  --skip-os-packages 2.报错无法下载node:将node相关文件下载放到kibana/.node_binaries/10 ...

  4. tidevice 报UsbmuxReplyCode.BadDevice错误解决办法

    备忘 换了个新手机照常使用tidevice进行操作发现报错 tidevice.exceptions.MuxReplyError: UsbmuxReplyCode.BadDevice 查了好久,终于解决 ...

  5. Gin加载history模式下打包后的Vue文件,刷新找不到页面404

    import ( "io/ioutil" "github.com/gin-contrib/static" "github.com/gin-gonic/ ...

  6. Visual Studio 2019注册码

    最近在学习Visual Studio,但是晕斗士(筛子系统)提示需要注册码,否则只能试用30天,由于是学习购买就没必要了,找Google找到了一下两段注册码. 目前测试了专业版已经注册成功. Visu ...

  7. java使用minio上传下载文件

    Minio模板类: @RequiredArgsConstructor public class MinioTemplate implements InitializingBean { private ...

  8. OpenEuler 中C与汇编的混合编程

    2.5.1用汇编代码编程 将C代码编译成汇编代码 C代码: /**********a.c file********/ #include <stdio.h> extern int B(); ...

  9. 通过Jsoup,爬取车辆品牌,车系,LOGO等

    @Test public void test4() throws IOException { for (int i = 65; i <= 90; i++) { String value = St ...

  10. CPU密集型和IO密集型与线程池的配置

    CPU密集型任务应配置尽可能小的线程,如配置CPU数目+1个线程的线程池.由于IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程,如2*CPU数目.