SQL数据库和语法
增删改查
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了还未提交的事务:
- low_trx_id表示该SQL启动时,当前事务链表中最大的事务id编号,也就是最近创建的除自身以外最大事务编号;
- up_trx_id表示该SQL启动时,当前事务链表中最小的事务id编号,也就是当前系统中创建最早但还未提交的事务;
- 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索引适用范围
- 数据量少的不适合加索引
- 更新比较频繁的也不适合加索引
- 区分度低的字段不适合加索引(如性别)
SQL慢查询优化
explain + 查询SQL,根据参考信息可以进行SQL优化;
加索引、避免返回不必要的数据、适当分批量进行、优化sql结构、分库分表、读写分离
InnoDB与MyISAM的区别
- InnoDB支持事务,MyISAM不支持事务
- InnoDB支持外键,MyISAM不支持外键
- InnoDB 支持 MVCC(多版本并发控制),MyISAM 不支持
- select count(*) from table时,MyISAM更快,因为它有一个变量保存了整个表的总行数,可以直接读取,InnoDB就需要全表扫描。
- Innodb不支持全文索引,而MyISAM支持全文索引(5.7以后的InnoDB也支持全文索引)
- InnoDB支持表、行级锁,而MyISAM支持表级锁。
- InnoDB表必须有主键,而MyISAM可以没有主键
- Innodb表需要更多的内存和存储,而MyISAM可被压缩,存储空间较小,。
- Innodb按主键大小有序插入,MyISAM记录插入顺序是,按记录插入顺序保存。
- InnoDB 存储引擎提供了具有提交、回滚、崩溃恢复能力的事务安全,与 MyISAM 比 InnoDB 写的效率差一些,并且会占用更多的磁盘空间以保留数据和索引
数据库的三大范式
- 第一范式:数据表中的每一列(每个字段)都不可以再拆分。
- 第二范式:在第一范式的基础上,分主键列完全依赖于主键,而不能是依赖于主键的一部分。
- 第三范式:在满足第二范式的基础上,表中的非主键只依赖于主键,而不依赖于其他非主键。
百万级别或以上的数据删除方式
- 我们想要删除百万数据的时候可以先删除索引
- 然后批量删除其中无用数据
- 删除完成后重新创建索引
MYSQL死锁
- 如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
- 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
- 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
- 如果业务处理不好可以用分布式事务锁或者使用乐观锁
创建索引的三种方式
在执行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(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGIN和END语句内,如前所见,它们是一系列SELECT语句,用来检索值,然后保存到相应的变量(通过指定INTO关键字)
SQL数据库和语法的更多相关文章
- SQL数据库基础语法
SQL语句的概述 SQL语言的分类 数据定义语言(Data Definition Language)主要用于修改.创建和删除数据库对象,其中包括CREATE ALTER DROP语句. 数据查询语 ...
- Microsoft SQL Server学习(二)--数据库的语法
关于数据库的语法 创建数据库 样例 名词概念 编写数据库代码的注意事项 关于文件语法 实例代码 关于数据库的语法: 1.创建数据库 create database 数据库名 on primary (主 ...
- SQL中部分语法整理
1.SELECT DISTINCT 语句 关键词DISTINCT用于返回唯一不同的值. 语法: SELECT DISTINCT 列名称 FROM 表名称 2.SELECT INTO语句 SELECT ...
- SQL server存储过程语法及实例(转)
存储过程如同一门程序设计语言,同样包含了数据类型.流程控制.输入和输出和它自己的函数库. --------------------基本语法-------------------- 一.创建存储过程cr ...
- 动态sql语句基本语法--Exec与Exec sp_executesql 的区别
http://www.cnblogs.com/goody9807/archive/2010/10/19/1855697.html 动态sql语句基本语法 1 :普通SQL语句可以用Exec执行 ...
- SQL数据库之变量
--学习SQL数据库,变量是必须要掌握的概念,系统变量就是变量中最重要的变量之一,下面是SQL中系统变量的应用实例 use AdventureWorksDW exec sp_addtype 'char ...
- SQL VIEW 使用语法
之前一直都不知道VIEW有什么作用,写程序的时候也很少遇到过,复习SQL语句的时候碰到了,就记录下来吧. 什么是视图? 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列, ...
- [SQL]动态sql语句基本语法
动态sql语句基本语法 :普通SQL语句可以用Exec执行 eg: Select * from tableName Exec('select * from tableName') Exec sp_ex ...
- SQL[连载2]语法及相关实例
SQL[连载2]语法及相关实例 SQL语法 数据库表 一个数据库通常包含一个或多个表.每个表由一个名字标识(例如:"Websites"),表包含带有数据的记录(行). 在本教程中, ...
- Android - 数据存储 -在SQL数据库中保存数据
对于重复的或结构化的数据,保存到数据库中是很好的选择,比如联系人信息.这里假设你对SQL数据库大体上了解然后帮助你学习Android上的SQLite数据库.在Android数据库上需要用到的API可以 ...
随机推荐
- rclone挂载对象存储到本地
一.原理图 二.挂载步骤 1.申请对象存储资源 (略) 2.下载rclone https://rclone.org/downloads/ 3.上传服务器,解压并安装 sudo unzip rclone ...
- CSP-J入门组
setw(2) cout<<setw(2) //设置后面显示字符的宽度为2 cout<<fixed<<setprecision(6)<<变量名;//设置 ...
- kibana7.6.2内网windows系统下编译打包部署
1.在kibana根目录下执行命令: yarn build --skip-os-packages 2.报错无法下载node:将node相关文件下载放到kibana/.node_binaries/10 ...
- tidevice 报UsbmuxReplyCode.BadDevice错误解决办法
备忘 换了个新手机照常使用tidevice进行操作发现报错 tidevice.exceptions.MuxReplyError: UsbmuxReplyCode.BadDevice 查了好久,终于解决 ...
- Gin加载history模式下打包后的Vue文件,刷新找不到页面404
import ( "io/ioutil" "github.com/gin-contrib/static" "github.com/gin-gonic/ ...
- Visual Studio 2019注册码
最近在学习Visual Studio,但是晕斗士(筛子系统)提示需要注册码,否则只能试用30天,由于是学习购买就没必要了,找Google找到了一下两段注册码. 目前测试了专业版已经注册成功. Visu ...
- java使用minio上传下载文件
Minio模板类: @RequiredArgsConstructor public class MinioTemplate implements InitializingBean { private ...
- OpenEuler 中C与汇编的混合编程
2.5.1用汇编代码编程 将C代码编译成汇编代码 C代码: /**********a.c file********/ #include <stdio.h> extern int B(); ...
- 通过Jsoup,爬取车辆品牌,车系,LOGO等
@Test public void test4() throws IOException { for (int i = 65; i <= 90; i++) { String value = St ...
- CPU密集型和IO密集型与线程池的配置
CPU密集型任务应配置尽可能小的线程,如配置CPU数目+1个线程的线程池.由于IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程,如2*CPU数目.