mysql交集并集差集:
数据库三范式:
-
简而言之:1.字段不可再拆分,比如(联系人这样的字段就包含姓名,电话就不行);2.主键必须是一个字段,不能就是多个字段才能确认唯一性;3.一张表中的外键不能是那张表的非主键字段:https://www.cnblogs.com/xiaozengzeng/p/10720226.html
mysqlclient和pymsql:
Ubuntu18.04 pip安装mysqlclient时报错MySQLdb/_mysql.c:38:10: fatal error: Python.h: 没有那个文件或目录,解决:
-
安装mysqlclient 需要安装两个依赖包:
(1)sudo apt-get install python-dev libmysqlclient-dev # Debian / Ubuntu
(2)sudo apt-get install python3-dev # Debian / Ubuntu,更多看下面链接
mysql乐观锁和悲观锁的实现:
mysql中的mvcc的使用
什么是MVCC
InnoDB的MVCC实现机制
MVCC可以认为是行级锁的一个变种,它可以在很多情况下避免加锁操作,因此开销更低。MVCC的实现大都都实现了非阻塞的读操作,写操作也只锁定必要的行。InnoDB的MVCC实现,是通过保存数据在某个时间点的快照来实现的。一个事务,不管其执行多长时间,其内部看到的数据是一致的。也就是事务在执行的过程中不会相互影响。下面我们简述一下MVCC在InnoDB中的实现。
InnoDB的MVCC,通过在每行记录后面保存两个隐藏的列来实现:一个保存了行的创建时间,一个保存行的过期时间(删除时间),当然,这里的时间并不是时间戳,而是系统版本号,每开始一个新的事务,系统版本号就会递增。在RR隔离级别下,MVCC的操作如下:
- select操作。
- InnoDB只查找版本早于(包含等于)当前事务版本的数据行。可以确保事务读取的行,要么是事务开始前就已存在,或者事务自身插入或修改的记录。
- 行的删除版本要么未定义,要么大于当前事务版本号。可以确保事务读取的行,在事务开始之前未删除。
- insert操作。将新插入的行保存当前版本号为行版本号。
- delete操作。将删除的行保存当前版本号为删除标识。
- update操作。变为insert和delete操作的组合,insert的行保存当前版本号为行版本号,delete则保存当前版本号到原来的行作为删除标识。
由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。
mysql常见函数总结
sql基本优化方法
究极面试宝典
在mysql中limit的偏移量很大时,由于要扫描前面的很多行,所以会导致查询速速比较慢,可以采用下列几种方法
# 记录上次最大id select id, name, content from users where id > 10073 order by id asc limit 20 # 子查询(子查询最好是连续的,order by后面字段要建立索引) SELECT * FROM articles WHERE id >= (SELECT id FROM articles WHERE category_id = 123 ORDER BY id LIMIT 10000, 1) LIMIT 10 # join连接 SELECT * FROM user AS t1 innerjoin (SELECT id FROM user ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) AS t2 WHERE t1.id <= t2.id ORDER BY t1.id desc LIMIT $pagesize;
创建索引,但无法命中索引的几种情况
1、应尽量避免在 WHERE 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。(注意,column IS NULL 也是不可以使用索引的。可以在column上设置默认值0,确保column中没有空值) 2、应尽量避免在 WHERE 子句中使用 OR 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,只有or条件全部都是独立索引,才可以用or,如:SELECT id FROM t WHERE num = 10 OR num = 20 可以使用union代替all。 3、应尽量避免在 WHERE 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。 4、应尽量避免在 WHERE 子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。 5、不要在 WHERE 子句中的 = 左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。 6、复合索引遵循前缀原则。 7、如果 MySQL 评估使用索引比全表扫描更慢,会放弃使用索引。如果此时想要索引,可以在语句中添加强制索引。 8、列类型是字符串类型,查询时一定要给值加引号,否则索引失效。 9、LIKE 查询,% 不能在前,因为无法使用索引。如果需要模糊匹配,可以使用全文索引。
复合索引最左匹配原则(最左匹配特性)
当 B+Tree 的数据项是复合的数据结构,比如索引 (name, age, sex) 的时候,B+Tree 是按照从左到右的顺序来建立搜索树的。
比如当 (张三, 20, F) 这样的数据来检索的时候,B+Tree 会优先比较 name 来确定下一步的所搜方向,如果 name 相同再依次比较 age 和 sex ,最后得到检索的数据。 但当 (20, F) 这样的没有 name 的数据来的时候,B+Tree 就不知道下一步该查哪个节点,因为建立搜索树的时候 name 就是第一个比较因子,必须要先根据 name 来搜索才能知道下一步去哪里查询。 比如当 (张三, F) 这样的数据来检索时,B+Tree 可以用 name 来指定搜索方向,但下一个字段 age 的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是 F 的数据了。
mysql创建索引的几种方式
创建表示int(11)中11是什么意思?
- 表示显示宽度为11,该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。也就是说,int的长度并不影响数据的存储精度,长度只和显示有关。
金额(金钱)相关的数据,选择什么数据类型?
- 方式一,使用 int 或者 bigint 类型。如果需要存储到分的维度,需要 *100 进行放大。
- 方式二,使用 decimal 类型,避免精度丢失。如果使用 Java 语言时,需要使用 BigDecimal 进行对应。
一张表,里面有 ID 自增主键,当 insert 了 17 条记录之后,删除了第 15,16,17 条记录,再把 MySQL 重启,再 insert 一条记录,这条记录的 ID 是 18 还是 15?
- 一般情况下,我们创建的表的类型是 InnoDB ,如果新增一条记录(不重启 MySQL 的情况下),这条记录的 ID 是18 ;但是如果重启 MySQL 的话,这条记录的 ID 是 15 。因为 InnoDB 表只把自增主键的最大 ID 记录到内存中,所以重启数据库或者对表 OPTIMIZE(mysql对于空记录和索引不会删除,可以使用optimize优化表空间) 操作,都会使最大 ID 丢失。
- 但是,如果我们使用表的类型是 MyISAM ,那么这条记录的 ID 就是 18 。因为 MyISAM 表会把自增主键的最大 ID 记录到数据文件里面,重启 MYSQL 后,自增主键的最大 ID 也不会丢失。最后,还可以跟面试官装个 x ,生产数据,不建议进行物理删除记录。