三个经典的MySQL问题
大家好,今天给大家上3个经典的MySQL问题,希望能对大家有帮助!但是因为笔者计算机水平有限,可能会存在一些错误,烦请指出、斧正!谢谢!
- 一、在MySQL中INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有什么区别?
- 二、你会推荐使用 datetime 还是 timestamp 字段?为什么?
- 三、MyISAM 与 InnoDB,什么场景选择哪一个?
一、在MySQL中INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有什么区别?
我们有两张表:
- TableA:
- id firstName lastName
- .......................................
- 1 arun prasanth
- 2 ann antony
- 3 sruthy abc
- 6 new abc
- 复制代码
- TableB:
- id2 age Place
- ................
- 1 24 kerala
- 2 24 usa
- 3 25 ekm
- 5 24 chennai
- 复制代码
1. INNER JOIN(内连接)
这是最简单,最常见,也是最容易理解的Join,两张表使用内连接查询时,得到的结果是两张表中完全匹配的行集。
对于上述两张表,我们有:
- SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place
- FROM TableA
- INNER JOIN TableB
- ON TableA.id = TableB.id2;
- 复制代码
得到的结果即为:
- firstName lastName age Place
- ..............................................
- arun prasanth 24 kerala
- ann antony 24 usa
- sruthy abc 25 ekm
- 复制代码
得到的结果有4个字段,firstName 、 lastName 、 age 、 Place,就是我们上面SQL语句SELECT的4个字段,FROM和INNER JOIN后面的两个表名就是要内连接的两张表,ON后面就是在其中寻找共同点的字段。
2. LEFT JOIN(左连接)
左连接查询会返回左表中所有行,无论这些行是不是有任何一行在右表中匹配。
- SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place
- FROM TableA
- LEFT JOIN TableB
- ON TableA.id = TableB.id2;
- 复制代码
查询结果是:
- firstName lastName age Place
- .............................................................
- arun prasanth 24 kerala
- ann antony 24 usa
- sruthy abc 25 ekm
- new abc NULL NULL
- 复制代码
我们可以看到,TableA中所有行都过来了,即使firstName为new,lastName为abc的那一行id为6,在TableB中找不到id为6的行,仍然在结果集中存在。值得注意的是,因为其id为6,在TableB中找不到对应的id,因此其没有age和Place字段的内容。
3. RIGHT JOIN(右连接)
右连接查询会返回右表中所有行,无论这些行是不是有任何一行在左表中匹配。
- SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place
- FROM TableA
- RIGHT JOIN TableB
- ON TableA.id = TableB.id2;
- 复制代码
结果集:
- firstName lastName age Place
- ...............................................................
- arun prasanth 24 kerala
- ann antony 24 usa
- sruthy abc 25 ekm
- NULL NULL 24 chennai
- 复制代码
4. FULL JOIN(全连接)
SQL语句如下:
- SELECT TableA.firstName,TableA.lastName,TableB.age,TableB.Place
- FROM TableA
- FULL JOIN TableB
- ON TableA.id = TableB.id2;
- 复制代码
结果集为:
- firstName lastName age Place
- ...........................................................
- arun prasanth 24 kerala
- ann antony 24 usa
- sruthy abc 25 ekm
- new abc NULL NULL
- NULL NULL 24 chennai
- 复制代码
查询结果是左连接和右连接的并集。
二、你会推荐使用 datetime 还是 timestamp 字段?为什么?
正如Mysql文档描述的那样——datetime的范围是“1000-01-01 00:00:00”到“9999-12-31 23:59:59”,而timestamp的范围是 '1970-01-01 00:00:01' UTC 到 '2038-01-09 03:14:07' UTC。如果不想程序在2038年出问题,从这个方面作者建议还是使用datetime。
有一种观点是既不使用 DATETIME 也不使用 TIMESTAMP 字段。如果想将特定的一天作为一个整体来表示(例如生日),可以使用 DATE 类型,但是如果需要更具体的时间,不要使用 DATETIME 或 TIMESTAMP,而是使用 BIGINT,并简单地存储自纪元以来的毫秒数(如果使用的是 Java,则为 System.currentTimeMillis())。
这样有几个优点。其一,可以在迁移数据库时避免因为数据类型差异,比如MySQL的DATETIME类型和Oracle的DATETIME类型之间可能存在差异,timestamp类型的精度可能也存在差异,MySQL的timestamp精度不是一开始就支持毫秒精度的。其二,没有时区问题,无论是哪个时区,因为开始计算的时间不同,无论当前时间如何,跨度是一致的。其三,没有timestamp和datatime的范围问题,哪怕是datatime,8000年以后也不能用了,没准我的数据库8000年能用8000年呢。
需要注意的是,bigint是占用8个字节,而timestamp只占用4个字节。从MySQL 5.6.4开始,Datetime的存储空间变成了5个字节了(准确的说应该是5字节+0~3个字节的FSP分秒精度)。
三、MyISAM 与 InnoDB,什么场景选择哪一个?
MyISAM 和 InnoDB 之间的主要区别在于参照完整性和事务。还有其他区别,例如锁定、回滚和全文搜索。
参照完整性
参照完整性确保表之间的关系保持一致。更具体地说,当一个表(例如 Listings)有一个外键(例如 Product ID)指向另一个表(例如 Products)时,当指向的表发生更新或删除时,这些更改会级联到链接的表。在该示例中,如果重命名产品,则链接的表的外键也会更新;如果从Products表中删除产品,则指向已删除条目的 Listings 表中得到任何列表也将被删除。此外,任何 Listings 表中的新列表都必须具有指向有效的现有条目的外键。
InnoDB 是一个关系型 DBMS (RDBMS),因此具有参照完整性,而 MyISAM 则没有。
事务和原子性
使用数据操作语言 (DML) 语句管理表中的数据,例如 SELECT、INSERT、UPDATE 和 DELETE。事务将两个或多个 DML 语句组合成一个工作单元,因此要么应用整个单元,要么不应用。
MyISAM 不支持事务,而 InnoDB 支持。
如果在使用 MyISAM 表时操作被中断,该操作将立即中止,并且受影响的行(甚至每行中的数据)仍然受到影响,即使该操作没有完成。
如果一个操作在使用 InnoDB 表时被中断,因为它使用具有原子性的事务,任何没有完成的事务都不会生效,因为没有提交。
表锁定与行锁定
当查询 MyISAM 表时,正在查询的整个表将被锁定。这意味着后续查询将仅在当前查询完成后才能执行。如果您正在读取一个大表,并且有频繁的读写操作,这可能意味着大量的查询积压。
而当查询 InnoDB 表时,只有涉及的行被锁定,表的其余部分仍然可进行 CRUD 操作。这意味着查询可以在同一个表上同时运行,只要它们不使用同一行。
InnoDB 中的此功能称为并发。尽管并发性很好,但在表的范围查询时有一个缺点,因为在内核线程之间切换存在开销,我们应该对内核线程设置限制以防止服务器停止。
事务和回滚
当在 MyISAM 中执行一个操作时,更改会立刻生效;在 InnoDB 中,这些更改可以回滚。用于控制事务的最常用命令是 COMMIT、ROLLBACK 和 SAVEPOINT。
- COMMIT - 您可以编写多个 DML 操作,但只有在进行 COMMIT 时才会保存更改
- ROLLBACK - 您可以丢弃任何尚未提交的操作
- SAVEPOINT - 实现回滚到指定保存点
可靠性
MyISAM 不提供数据完整性——硬件故障、不正常的关机操作都可能导致数据损坏。这将需要修复或重建索引和表。
而InnoDB 使用事务日志、双写缓冲区和自动校验和和验证来防止数据损坏。在 InnoDB 进行任何更改之前,它会将事务之前的数据记录到一个名为 ibdata1 的系统表空间文件中。如果发生崩溃,InnoDB 将通过这些日志来自动恢复。
全文索引
InnoDB 在 MySQL 5.6.4 版本之前不支持 FULLTEXT 索引。
但是,这不是使用 MyISAM 的理由。最好使用最新版本的 MySQL 。并不是说使用 FULLTEXT 索引的 MyISAM 表不能转换为 InnoDB 表。
结论
总之,InnoDB 应该是我们默认的存储引擎。在有特定需求时可以选择 MyISAM 或其他数据类型。
三个经典的MySQL问题的更多相关文章
- 微服务实战(三):以MySQL为例,从原理上理解那些所谓的数据库军规
原文链接:微服务化的数据库设计与读写分离(来源:刘超的通俗云计算) 数据库永远是应用最关键的一环,同时越到高并发阶段,数据库往往成为瓶颈,如果数据库表和索引不在一开始就进行良好的设计,则后期数据库横向 ...
- 阿里云服务器Linux CentOS安装配置(三)yum安装mysql
阿里云服务器Linux CentOS安装配置(三)yum安装mysql 1.执行yum安装mysql命令:yum -y install mysql-server mysql-devel 2.启动mys ...
- 三招搞挂Mysql(转)
一.产生大量的undo日志 众所周知,InnoDB是一个支持MVCC的存储引擎,为了支持MVCC,InnoDB需要保存undo日志,以便对用户提供记录的历史版本.如果我们开启一个事务,反复地更新一条记 ...
- 【转】进程同步之信号量机制(pv操作)及三个经典同步问题
原文地址:http://blog.csdn.net/speedme/article/details/17597373 上篇博客中(进程同步之临界区域问题及Peterson算法),我们对临界区,临界资源 ...
- LIS(最长上升子序列)的三种经典求法
求最长上升子序列的三种经典方案: 给定一个长度为 \(N\) 的数列,求它数值单调递增的子序列长度最大为多少.即已知有数列 \(A\) , \(A=\{A_1,A_2....A_n\}\) ,求 \( ...
- 经典书籍---MySQL经典书籍下载
以下是一些经典的MySQL书籍电子版,括号内为提取码,若需自取. 欢迎阅读纸质版,尊重作者版权 高性能MySQL_中文版 [ hre3 ] 高性能MySQL_英文版[ m2xj ] MySQL技术内幕 ...
- 三种方法查看MySQL数据库的版本
1.使用-V参数 首先我们想到的肯定就是查看版本号的参数命令,参数为-V(大写字母)或者--version 使用方法: D:\xampp\mysql\bin>mysql -V 或者 D:\xam ...
- 14款经典的MySQL客户端软件
1. EMS MySQL Manager 强大的mysql管理工具,允许用户通过图形界面创建或编辑数据库对象,并提供通过sql语句管理用户和权限,通过图形界面建立sql语句,自动生成html格式的数据 ...
- JavaEE系列之(三)JDBC操作MySQL数据库
一.JDBC简介 JDBC(Java Data Base Connectivity)java数据库连接 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库 ...
- 三白话经典算法系列 Shell排序实现
山是包插入的精髓排序排序,这种方法,也被称为窄增量排序.因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元 ...
随机推荐
- 「SOL」Hamiltonian Cycle (AtCoder)
原来一般的四度图也没法快速构造哈密顿回路 QwQ # 题面 给定质数 \(P\) 和正整数 \(a,b\),构造一个长为 \(P\) 的数列 \(G=(g_1,g_2,\dots,g_P)\),满足: ...
- Delphi中纤程的使用
首先我们来看看纤程的定义 纤程(来自百科): 纤程是Windows为了将Unix服务程序更好的移植到Windows上而创建的, 线程是在Windows内核中实现的,纤程是在用户模式下实现的,内核对纤程 ...
- S32DS中链接文件及启动代码学习
S32DS中链接文件及启动代码学习 一.链接文件 <Linker Files>文件夹中有linker_flash.ld文件和linker_ram.ld文件. Linker File称为链接 ...
- echo 操作
echo打印制表符到文件: MAP_PATH=/path/for i in `cat sp.list`; do echo -e "${MAP_PATH}/${i}.${i}/${i}.fin ...
- js 基础篇--保留字
1.js把一些标识符拿出来用作自己的关键字.因此,就不能再在程序中把这些关键字用作标识符了: 1 break delete function return typeof 2 case do if sw ...
- ES6的Map和Set的了解和练习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【LeetCode - 1055】形成字符串的最短路径
1.题目描述 代码: #include <iostream> #include <string> using namespace std; const int MAX_LETT ...
- CVPixelBufferRef
在iOS里,我们经常能看到 CVPixelBufferRef 这个类型,在Camera 采集返回的数据里得到一个CMSampleBufferRef,而每个CMSampleBufferRef里则包含一个 ...
- macOS开发应用Sign(签名)和Notarizaiton(公证)
签名 可执行文件签名: codesign -f -s ${证书ID} --timestamp ${签名文件} .Pkg安装文件签名: productsign --timestamp --sign ${ ...
- 打开CMD的方式
打开Cmd的方式: 1.开始+系统+命令提示符 2.Win键+R 3.在任意文件夹下,按住Shift键+鼠标右键点击,在此处打开命令行窗口 4.资源管理的地址栏前面加上Cmd路径 管理员运行方式 :系 ...